Files
hotels/n8n_code_check_regex.js
Фёдор 684fada337 🚀 Full project sync: Hotels RAG & Audit System
 Major Features:
- Complete RAG system for hotel website analysis
- Hybrid audit with BGE-M3 embeddings + Natasha NER
- Universal horizontal Excel reports with dashboards
- Multi-region processing (SPb, Orel, Chukotka, Kamchatka)

📊 Completed Regions:
- Орловская область: 100% (36/36)
- Чукотский АО: 100% (4/4)
- г. Санкт-Петербург: 93% (893/960)
- Камчатский край: 87% (89/102)

🔧 Infrastructure:
- PostgreSQL with pgvector extension
- BGE-M3 embeddings API
- Browserless for web scraping
- N8N workflows for automation
- S3/Nextcloud file storage

📝 Documentation:
- Complete DB schemas
- API documentation
- Setup guides
- Status reports
2025-10-27 22:49:42 +03:00

161 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 🎯 CODE NODE: Проверка регулярными выражениями
// Размести эту ноду ПОСЛЕ AI Agent
// Она улучшит оценку, если найдёт точные форматы (ИНН, телефоны, email)
// Получаем данные от AI Agent
const aiResult = $input.item.json;
// Получаем текст из chunks (должен быть в контексте)
// Если у тебя есть отдельная нода для получения chunks - используй её
// Иначе - нужно сделать дополнительный запрос к PostgreSQL
const hotelText = $('Postgres1').all().map(item => item.json.text).join(' ');
// Регулярные выражения для каждого критерия
const regexPatterns = {
1: { // ИНН, ОГРН
patterns: [
/\b\d{10}\b/g, // ИНН юр.лица (10 цифр)
/\b\d{12}\b/g, // ИНН ИП (12 цифр)
/\b\d{13}\b/g, // ОГРН (13 цифр)
/\b\d{15}\b/g, // ОГРНИП (15 цифр)
/инн\s*:?\s*\d{10,12}/gi,
/огрн\s*:?\s*\d{13}/gi
],
weight: 1.0
},
2: { // Адрес
patterns: [
/\d{6}.*?ул\./gi,
/ул\.\s*[А-Яа-яёЁA-Za-z\s]+,?\s*\d+/gi,
/\d{6},?\s*г\.\s*[А-Яа-яёЁ-]+/gi
],
weight: 1.0
},
3: { // Контакты
patterns: [
/(?:\+7|8)\s*\(?\d{3,5}\)?\s*\d{1,3}[-\s]?\d{2}[-\s]?\d{2}/g, // Телефон
/[\w\.-]+@[\w\.-]+\.\w{2,}/g // Email
],
weight: 1.0
},
4: { // Режим работы
patterns: [
/(?:с|с\s+)\d{1,2}(?::|\.)\d{2}\s*(?:до|по)\s*\d{1,2}(?::|\.)\d{2}/gi,
/круглосуточно/gi,
/24\s*[/\-]\s*7/g
],
weight: 1.0
},
5: { // 152-ФЗ
patterns: [
/152[-\s]?фз/gi,
/политика\s+в\s+отношении\s+обработки\s+персональных\s+данных/gi
],
weight: 1.0
},
7: { // Договор-оферта
patterns: [
/публичная\s+оферта/gi,
/договор.*?оказани.*?услуг/gi,
/пользовательское\s+соглашение/gi
],
weight: 1.0
},
9: { // Цены
patterns: [
/\d+\s*(?:руб|₽)/g,
/(?:от|цена|стоимость)\s*\d+/gi
],
weight: 0.8
},
12: { // Онлайн-бронирование
patterns: [
/забронировать/gi,
/форма\s+(?:заявки|бронирования)/gi
],
weight: 0.8
}
};
// Функция проверки паттернов
function checkPatterns(text, patterns) {
const matches = [];
for (const pattern of patterns) {
const found = text.match(pattern);
if (found) {
matches.push(...found.slice(0, 3)); // Макс 3 совпадения на паттерн
}
}
return matches;
}
// Проверяем текущий критерий
const criterionId = aiResult.criterion_id || aiResult.id;
const regexConfig = regexPatterns[criterionId];
let regexScore = 0.0;
let regexMatches = [];
if (regexConfig && hotelText) {
regexMatches = checkPatterns(hotelText, regexConfig.patterns);
if (regexMatches.length > 0) {
regexScore = regexConfig.weight;
}
}
// ГИБРИДНАЯ ОЦЕНКА: берём максимум из AI и регулярок
const aiScore = parseFloat(aiResult.score) || 0.0;
const finalScore = Math.max(aiScore, regexScore);
// Определяем метод, который дал результат
let method = 'Не найдено';
if (finalScore > 0) {
if (aiScore > regexScore) {
method = 'AI Agent';
} else if (regexScore > aiScore) {
method = 'Регулярные выражения';
} else {
method = 'AI Agent + Регулярки';
}
}
// Возвращаем улучшенный результат
return {
json: {
criterion_id: criterionId,
criterion_name: aiResult.criterion_name || aiResult.name,
question: aiResult.question,
// Результаты AI Agent
ai_score: aiScore,
ai_found: aiResult.found,
ai_quote: aiResult.quote || '',
ai_url: aiResult.url || '',
// Результаты регулярок
regex_score: regexScore,
regex_matches: regexMatches.slice(0, 5), // Макс 5 совпадений
regex_found: regexMatches.length > 0,
// Итоговая оценка
final_score: finalScore,
method: method,
confidence: finalScore >= 0.8 ? 'Высокая' :
finalScore >= 0.5 ? 'Средняя' :
finalScore >= 0.3 ? 'Низкая' : 'Не найдено',
// Для отчёта
quote: aiResult.quote || (regexMatches.length > 0 ? `Найдено: ${regexMatches[0]}` : ''),
url: aiResult.url || '',
details: aiResult.details || ''
}
};