astro_avtourist/frontend/scripts/analyze-posts-detailed.ts
2026-05-07 17:16:25 +05:00

146 lines
No EOL
5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

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[^>]*>([^<]+)<\/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();