import PocketBase from 'pocketbase'; const PB_URL = 'http://127.0.0.1:8090'; const pb = new PocketBase(PB_URL); interface Post { id: string; title: string; content: string; slug: string; category: string; draft: boolean; description: string; } async function getFirstParagraph(content: string): string { // Strip HTML tags and get first paragraph const text = content.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(); const paragraphs = text.split(/\n\n/).filter(p => p.trim().length > 20); return paragraphs[0] || ''; } async function getH2Headings(content: string): string[] { const h2Matches = content.match(/]*>([^<]+)<\/h2>/gi) || []; return h2Matches.map(h2 => h2.replace(/<[^>]+>/g, '').trim()); } async function analyzePostDetailed(post: Post) { const firstParagraph = await getFirstParagraph(post.content); const h2Headings = await getH2Headings(post.content); // Check for Claim patterns at start const claimPatterns = [ { pattern: /^\d+%/i, name: 'Процент' }, { pattern: /^В\s+\d+\s+/i, name: 'Конкретное число' }, { pattern: /^\d+\s+(лет|месяцев|дней)/i, name: 'Срок' }, { pattern: /^Вы можете/i, name: 'Обращение к читателю' }, { pattern: /^За\s+\d+/i, name: 'За X' }, ]; const foundClaim = claimPatterns.find(c => c.pattern.test(firstParagraph.trim())); // Check for Takeaway const takeawayPatterns = [ /что\s+делать/i, /обращайтесь/i, /позвоните/i, /закажите/i, /получите/i, /напишите/i, /свяжитесь/i, /звоните/i ]; const hasTakeaway = takeawayPatterns.some(p => p.test(post.content)); // Check for Pronouns const pronouns = /\b(мы|наш|наша|наши)\b/gi; const hasPronouns = pronouns.test(post.content); // Check for Proof (numbers) const numbers = post.content.match(/\d+/g) || []; const hasProof = numbers.length > 3; // Check H2 issues const badH2s = ['проблема', 'подход', 'ситуация', 'что было', 'решение', 'как помочь']; const badH2sFound = h2Headings.filter(h2 => badH2s.some(b => h2.toLowerCase().includes(b)) ); return { id: post.id, title: post.title, slug: post.slug, category: post.category, firstParagraph: firstParagraph.substring(0, 150) + '...', h2Headings, hasClaim: !!foundClaim, claimType: foundClaim?.name || null, hasTakeaway, hasPronouns, hasProof, proofCount: numbers.length, badH2sFound, recommendations: [] }; } async function main() { console.log('\n📋 ДЕТАЛЬНЫЙ АНАЛИЗ ПОСТОВ\n'); console.log('='.repeat(70)); try { const postsResult = await pb.collection('posts').getList(1, 500); const posts = postsResult.items as unknown as Post[]; const activePosts = posts.filter(p => !p.draft); console.log(`Найдено постов: ${activePosts.length}\n`); for (const post of activePosts) { const analysis = await analyzePostDetailed(post); console.log(`\n${'='.repeat(70)}`); console.log(`📝 ${post.title}`); console.log(` slug: ${post.slug}`); console.log(` category: ${post.category}`); console.log('-'.repeat(70)); console.log(`\n📄 ПЕРВЫЙ АБЗАЦ:`); console.log(` "${analysis.firstParagraph}"`); console.log(`\n🔍 CHECKLIST:`); console.log(` Claim: ${analysis.hasClaim ? '✓' : '✗'} ${analysis.claimType ? `(${analysis.claimType})` : '(нужно добавить факт/число)'}`); console.log(` Takeaway: ${analysis.hasTakeaway ? '✓' : '✗'}`); console.log(` Pronouns: ${analysis.hasPronouns ? '✗' : '✓'}`); console.log(` Proof: ${analysis.hasProof ? '✓' : '✗'} (${analysis.proofCount} чисел)`); if (analysis.badH2sFound.length > 0) { console.log(` H2 issues: ${analysis.badH2sFound.join(', ')}`); } // Recommendations console.log(`\n⚠️ РЕКОМЕНДАЦИИ:`); if (!analysis.hasClaim) { console.log(` 1. Добавить Claim в первый абзац — начать с цифры или факта`); console.log(` Пример: "За 2025 год в Сургуте суд вернул права в 73% дел..."`); } if (!analysis.hasTakeaway) { console.log(` 2. Добавить Takeaway — призыв к действию в конце статьи`); } if (analysis.hasPronouns) { console.log(` 3. Убрать местоимения "мы", "наш"`); } if (!analysis.hasProof) { Console.log(` 4. Добавить конкретные цифры и факты`); } if (analysis.badH2sFound.length > 0) { console.log(` 5. Переименовать H2: ${analysis.badH2sFound.join(', ')}`); } } } catch (error) { console.error('Ошибка:', error); } } main();