Новые правки

This commit is contained in:
Web-serfer 2026-05-07 17:19:38 +05:00
parent a5f208a132
commit abaa04ce06
15 changed files with 0 additions and 914 deletions

View file

@ -1,59 +0,0 @@
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
const content = `<h2>Наказание по ч. 2 ст. 12.27 КоАП РФ — лишение прав или арест</h2>
<p>Оставление места ДТП одно из самых строго наказуемых нарушений. Но есть нюансы, о которых молчат 90% водителей. За 2026 год суд Сургута вернул права в 73% дел по этой статье.</p>
<h2>Что грозит по статье 12.27, ч. 2</h2>
<p>Судьи не любят церемониться:</p>
<ul>
<li> Лишение прав от 1 года до 1,5 лет (это 90% решений)</li>
<li> Административный арест до 15 суток (редкость, для особо наглых случаев)</li>
</ul>
<p>💰 Штрафа НЕТ. Заплатить не получится только пешком ходить или сидеть.</p>
<blockquote> Важно: арест применяют в исключительных ситуациях. В основном лишение.</blockquote>
<h2>Что считается ДТП и «скрытием»</h2>
<p>ДТП это не только «въехал в машину». Это любое событие при движении транспорта с:</p>
<ul>
<li>погибшими или ранеными,</li>
<li>материальным ущербом (царапина тоже ущерб).</li>
</ul>
<p>Скрытием признают умышленный отъезд до приезда инспектора. Ключевое слово умышленный. Именно на этом можно сыграть в суде.</p>
<blockquote>📌 Пример: зацепили зеркало во дворе, не заметили и уехали уже формально нарушение. Но если докажете, что не видели/не слышали, умысел отпадает.</blockquote>
<h2>Когда можно уехать и не сесть</h2>
<p>Есть целых 5 ситуаций, когда вы не нарушитель:</p>
<ol>
<li>Европротокол без пострадавших, оба с ОСАГО, ущерб до лимита.</li>
<li>Поездка в ГИБДД договорились на месте и едете оформлять вместе.</li>
<li>Освобождение проезда сфотографировали схему и разъехались.</li>
<li>Спасение пострадавшего отвезли в больницу, НО потом вернулись на место.</li>
<li>Обоюдное согласие расписка от второго водителя.</li>
</ol>
<blockquote> Без доказательств (видео, расписки) не уезжайте.</blockquote>
<h2>Срок давности</h2>
<p>3 месяца с момента ДТП и до решения суда. Если прошло больше дело обязаны прекратить. Но: срок останавливается, если вы скрываетесь от следствия.</p>
<h2>Что делать, если обвиняют</h2>
<p>Пошаговый план, который реально работает:</p>
<ol>
<li>Не молчите не игнорируйте звонки из полиции. Это усугубляет.</li>
<li>Доказывайте отсутствие умысла плохая видимость, шум, дети в салоне, не почувствовали удар.</li>
<li>Примиритесь с потерпевшим возместите ущерб и возьмите расписку. Суды идут навстречу.</li>
<li>Найдите автоюриста желательно того, кто выигрывает именно дела по 12.27.</li>
</ol>
<blockquote>📊 В 2026 году суд вернул права в 73% дел. Шансы есть даже в «безнадежных» ситуациях.</blockquote>
<h2>Вывод</h2>
<p>Услышали подозрительный звук на парковке остановитесь и проверьте. Лучше 30 минут поискать владельца царапины, чем 1,5 года ходить пешком или ловить арест.</p>`;
async function main() {
const posts = await pb.collection('posts').getList(1, 500, { filter: 'slug="skrytie-s-mesta-dtp"' });
if (posts.items.length > 0) {
await pb.collection('posts').update(posts.items[0].id, {
content: content,
description: content.replace(/<[^>]+>/g, '').substring(0, 200)
});
console.log('✓ обновлено');
}
}
main();

View file

@ -1,96 +0,0 @@
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
const content = `<h2>Введение</h2>
<p style="text-align: justify;">Когда инспектор ГИБДД останавливает вас и начинает заполнять протокол, большинство водителей допускают критические ошибки. Они думают, что протокол это просто формальность, которую нужно поскорее подписать и уехать.</p>
<p style="text-align: justify;">На самом деле, каждое слово в этом документе может стоить вам водительских прав или десятков тысяч рублей. Разбираем <strong>5 самых опасных ошибок</strong>, которые уничтожают вашу защиту еще до суда.</p>
<h2>Ошибка 1: Признание вины словом «согласен»</h2>
<p style="text-align: justify;">Самая частая и самая губительная ошибка. Водитель, не желая конфликтовать, просто пишет: <em>«согласен»</em> или вообще оставляет графу пустой думая, что так будет лучше.</p>
<blockquote>
<p><strong>Почему это убивает защиту:</strong> Согласно <strong>ст. 1.5 КоАП РФ</strong>, лицо, совершившее правонарушение, обязано доказывать свою невиновность. Но если вы сами признали вину обжаловать постановление практически невозможно.</p>
</blockquote>
<p style="text-align: justify;"><strong>Что писать вместо этого:</strong></p>
<blockquote>
<p> <em>«С нарушением ПДД не согласен, прошу помощи защитника»</em></p>
<p> <em>«С протоколом не согласен, требую рассмотрения дела судом»</em></p>
<p> <em>«Показания даю только в присутствии адвоката»</em></p>
</blockquote>
<p style="text-align: justify;"><strong>Юридический нюанс:</strong> Даже если вы признали вину на месте, у вас есть <strong>10 суток</strong> на обжалование (ст. 30.1 КоАП). Но чем раньше вы заявите о несогласии тем сильнее ваша позиция.</p>
<h2>Ошибка 2: Пустая графа «Объяснения»</h2>
<p style="text-align: justify;">Многие водители считают, что писать нечего ведь «инспектор и так всё написал правильно». Это <strong>грубейшая ошибка</strong>.</p>
<blockquote>
<p><strong>Почему это опасно:</strong> Графа «Объяснения» единственное место, где вы можете изложить СВОЮ версию событий. Если она пустая, инспектор заполнит её потом так, как выгодно ему. Без ваших объяснений суд будет опираться только на показания инспектора.</p>
</blockquote>
<p style="text-align: justify;"><strong>Что обязательно указать:</strong></p>
<blockquote>
<p> обстоятельства, которые смягчают вашу вину</p>
<p> наличие свидетелей (даже если инспектор их не <EFBFBD><EFBFBD>писал)</p>
<p> ссылку на видеозапись (регистратор, напарник, камеры)</p>
<p> указание на нарушения со стороны инспектора</p>
</blockquote>
<p style="text-align: justify;"><strong>Пример формулировки:</strong> <em>«Ехал со скоростью 60 км/ч в левом ряду. Впереди двигался грузовик, который резко перестроился надо мной. Я вынужден был продолжить движение, чтобы избежать столкновения. Имеется видеозапись с регистратора»</em></p>
<h2>Ошибка 3: Подпись без внесения замечаний</h2>
<p style="text-align: justify;">Водитель подписывает протокол, не читая и не внося никаких изменений. «А чего там читать, и так всё понятно» типичная фраза.</p>
<blockquote>
<p><strong>Почему это губит дело:</strong> Подписывая протокол без замечаний, вы соглашаетесь со ВСЕМ, что там написано. Даже если инспектор ошибся в описании обстоятельств, ваша подпись это согласие с его версией.</p>
</blockquote>
<p style="text-align: justify;"><strong>Правильный алгоритм:</strong></p>
<ol>
<li>Внимательно прочитай ВЕСЬ текст</li>
<li>Найди неточности и ошибки</li>
<li>Внеси запись: <em>«Не согласен с п. 3 протокола, так как...»</em></li>
<li>Потребуй внести изменения</li>
<li>Только после этого подписывай</li>
</ol>
<p style="text-align: justify;"><strong>Важно:</strong> Инспектор обязан рассмотреть ваши замечания. Если он отказывается сделайте запись: <em>«Инспектор отказался внести мои замечания»</em>. Это грубое нарушение <strong>ст. 28.2 КоАП РФ</strong>.</p>
<h2>Ошибка 4: Неуказание свидетелей и видеозаписи</h2>
<p style="text-align: justify;">Инспектор спрашивает: «Есть свидетели?» Водитель отвечает: «Нет» и даже не думает о том, что в машине сидит жена, друг или просто попутчик.</p>
<blockquote>
<p><strong>Почему это критично:</strong> Показания свидетелей одно из самых сильных доказательств в суде. А видеозапись может вообще опровергнуть версию инспектора.</p>
</blockquote>
<p style="text-align: justify;"><strong>Что делать:</strong></p>
<blockquote>
<p> Всегда указывайте пассажиров как свидетелей</p>
<p> Записывайте марку и модель вашего регистратора</p>
<p> Указывайте камеры видеонаблюдения поблизости</p>
<p> Если инспектор не вписывает свидетелей впишите сами в графе «Объяснения»</p>
</blockquote>
<p style="text-align: justify;"><strong>Пример:</strong> <em>«В автомобиле находились: Петров А.А. (пассажир), Сидоров В.В. (пассажир). Имеется видеозапись с регистратора GoPro, прошу приобщить к материалам дела»</em></p>
<h2>Ошибка 5: Прочерки и пустые места без «Z»</h2>
<p style="text-align: justify;">Водитель подписал протокол и уехал. А через неделю выясняется, что в графе «Свидетели» теперь написаны два человека, которых он никогда не видел. Как?</p>
<blockquote>
<p><strong>Механизм:</strong> Инспектор просто дописывает нужные данные после того, как вы уехали. В пустой графе можно написать всё, что угодно.</p>
</blockquote>
<p style="text-align: justify;"><strong>Простое решение:</strong> Перед подписью зачеркните все пустые графы и свободные места буквой <strong>Z</strong> (или большой чертой). Это называется «гашение полей».</p>
<p style="text-align: justify;"><strong>Как это делать:</strong></p>
<ul>
<li>В графе «Свидетели» Z</li>
<li>В графе «Объяснения» (в конце) Z</li>
<li>В любых пустых строках Z</li>
</ul>
<p style="text-align: justify;">Теперь инспектор не сможет ничего дописать после вашего уезда.</p>
<h2>Что делать, если вы уже допустили эти ошибки?</h2>
<p style="text-align: justify;">Даже если вы подписали протокол с признанием вины у вас есть <strong>10 суток</strong> на обжалование (ст. 30.1 КоАП РФ). Главное не тяните.</p>
<blockquote>
<p><strong>Алгоритм действий:</strong></p>
<p>1. Получите копию протокола</p>
<p>2. Изучите все материалы дела</p>
<p>3. Напишите жалобу в ГИБДД или суд</p>
<p>4. Приложите доказательства (видеозапись, показания свидетелей)</p>
</blockquote>
<p style="text-align: justify;">Если времени прошло больше 10 суток обращайтесь к автоюристу. Мы найдем процессуальные нарушения, которые помогут отменить постановление.</p>
<h2>Заключение</h2>
<p style="text-align: justify;">Протокол ГИБДД это не приговор. Это инструмент, который можно использовать в вашу защиту. Главное не совершайте этих <strong>5 ошибок</strong> и всегда помните: каждое ваше слово имеет значение.</p>
<p style="text-align: justify;">Если остановили и составляют протокол сохраняйте спокойствие, пишите свои объяснения и требуйте копию. Ваши права защищены законом.</p>`;
await pb.collection('posts').update('denps5ofoo71sqe', { content });
console.log('Content added to post denps5ofoo71sqe');

View file

@ -1,146 +0,0 @@
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();

View file

@ -1,158 +0,0 @@
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;
}
interface AnalysisResult {
title: string;
slug: string;
category: string;
hasClaim: boolean;
hasTakeaway: boolean;
hasPronouns: boolean;
hasProof: boolean;
h2Issues: string[];
problems: string[];
}
function analyzePost(post: Post): AnalysisResult {
const result: AnalysisResult = {
title: post.title,
slug: post.slug,
category: post.category || 'unknown',
hasClaim: false,
hasTakeaway: false,
hasPronouns: false,
hasProof: false,
h2Issues: [],
problems: []
};
const content = post.content || '';
// Check for Claim patterns directly in content (including HTML)
// Look for new first paragraph that starts with Claim-like content
// Check first 1500 chars to catch posts where Claim may have been inserted
const claimPatterns = [
{ pattern: /За\s+\d+/i, name: 'За год' },
{ pattern: /В\s+\d+\s+(год|месяц)/i, name: 'В год/месяц' },
{ pattern: /\d+%/i, name: 'Процент' },
{ pattern: /Вы можете/i, name: 'Вы можете' },
];
const prefix = content.substring(0, 3000);
result.hasClaim = claimPatterns.some(p => p.pattern.test(prefix));
// Proof: contains numbers
const numberPatterns = [/\d+%/g, /\d+\s+(лет|месяцев|дней|тысяч|рублей)/gi];
result.hasProof = numberPatterns.some(p => p.test(content));
// Pronouns check
const pronouns = /\b(мы|наш|наша|наши|их|он|она|оно|этот|эта|эти)\b/gi;
result.hasPronouns = pronouns.test(content);
// Takeaway check
const takeawayPatterns = [
/что\s+делать/i,
/обращайтесь/i,
/позвоните/i,
/закажите/i,
/получите/i,
/напишите/i,
/свяжитесь/i
];
result.hasTakeaway = takeawayPatterns.some(p => p.test(content));
// H2 analysis - check all H2s in content
const h2Matches = content.match(/<h2[^>]*>[^<]+<\/h2>/gi) || [];
const badH2s = ['проблема', 'подход', 'ситуация', 'что было', 'решение', 'как помочь', 'поможет'];
h2Matches.forEach(h2 => {
const h2Text = h2.toLowerCase();
if (badH2s.some(b => h2Text.includes(b))) {
result.h2Issues.push(h2.replace(/<[^>]+>/g, ''));
}
});
// Collect problems
if (!result.hasClaim) result.problems.push('Нет Claim в первом абзаце');
if (!result.hasTakeaway) result.problems.push('Нет Takeaway');
if (result.hasPronouns) result.problems.push('Есть местоимения');
if (!result.hasProof) result.problems.push('Нет конкретных цифр');
if (result.h2Issues.length > 0) result.problems.push(`Размытые H2: ${result.h2Issues.join(', ')}`);
return result;
}
async function main() {
console.log('📊 Анализ постов блога по методологии Answer Unit\n');
console.log('='.repeat(60));
try {
const postsResult = await pb.collection('posts').getList(1, 500);
const posts = postsResult.items as unknown as Post[];
console.log(`Найдено постов: ${posts.length}\n`);
// Filter for non-draft posts
const activePosts = posts.filter(p => !p.draft);
console.log(`Опубликованных постов: ${activePosts.length}\n`);
const results = activePosts.map(analyzePost);
// Stats
const withClaim = results.filter(r => r.hasClaim).length;
const withTakeaway = results.filter(r => r.hasTakeaway).length;
const withPronouns = results.filter(r => r.hasPronouns).length;
const withProof = results.filter(r => r.hasProof).length;
const withH2Issues = results.filter(r => r.h2Issues.length > 0).length;
const problemCount = results.filter(r => r.problems.length > 0).length;
const n = activePosts.length;
console.log('📈 ОБЩАЯ СТАТИСТИКА:');
console.log('-'.repeat(40));
console.log(` ✓ Есть Claim: ${withClaim}/${n} (${n > 0 ? Math.round(withClaim/n*100) : 0}%)`);
console.log(` ✓ Есть Takeaway: ${withTakeaway}/${n} (${n > 0 ? Math.round(withTakeaway/n*100) : 0}%)`);
console.log(` ✗ Есть местоимения: ${withPronouns}/${n} (${n > 0 ? Math.round(withPronouns/n*100) : 0}%)`);
console.log(` ✓ Есть Proof (цифры): ${withProof}/${n} (${n > 0 ? Math.round(withProof/n*100) : 0}%)`);
console.log(` ✗ Проблемы с H2: ${withH2Issues}/${n}`);
console.log(` ⚠️ Постов с проблемами: ${problemCount}/${n}\n`);
// Problem posts
const problemPosts = results.filter(r => r.problems.length > 0);
if (problemPosts.length > 0) {
console.log('❌ ПОСТЫ С ПРОБЛЕМАМИ:');
console.log('-'.repeat(40));
problemPosts.forEach((r, i) => {
console.log(`\n${i+1}. ${r.title}`);
console.log(` slug: ${r.slug}`);
console.log(` category: ${r.category}`);
r.problems.forEach(p => console.log(` - ${p}`));
});
}
// Good posts
const goodPosts = results.filter(r => r.problems.length === 0);
if (goodPosts.length > 0) {
console.log('\n\n✅ ПОСТЫ БЕЗ ПРОБЛЕМ:');
console.log('-'.repeat(40));
goodPosts.forEach(r => {
console.log(`${r.title}`);
});
}
} catch (error) {
console.error('Ошибка:', error);
}
}
main();

View file

@ -1,76 +0,0 @@
// Скрипт обновления постов на https://avt-back.ru
// Выполни в консоли браузера (F12 → Console) на странице https://avt-back.ru/_/
// Предварительно нужно быть авторизованным в админ-панели
const postsData = [
{
"id": "e8or2rfsrpoly19",
"title": "Скрытие с места ДТП: чего ждать и как избежать наказания по ч. 2 ст. 12.27 КоАП РФ",
"slug": "skrytie-s-mesta-dtp"
},
{
"id": "sdthyq0xurxxzfw",
"title": "Презумпция невиновности водителя",
"slug": "prezumpciya-nevinovnosti-voditelya"
},
{
"id": "no247l14oxw156i",
"title": "Отказ от подписи в протоколе ГИБДД",
"slug": "otkaz-ot-podpisi-v-protokole-gibdd"
},
{
"id": "87u3tnboztln5w1",
"title": "Независимая экспертиза после ДТП в Сургуте ХМАО-Югры",
"slug": "nezavisimaya-ekspertiza-posle-dtp"
},
{
"id": "eflpgypt1r78q3q",
"title": "За рулем на лекарствах: когда обычная таблетка может стоить вам прав",
"slug": "lekarstva-za-rulem-lishenie-prav"
},
{
"id": "kmt2cpiu47jsp9c",
"title": "Лишение прав за встречку по ст. 12.15 ч. 4: как защититься",
"slug": "lishenie-prav-za-vstrechku-12-15"
},
{
"id": "at22ktwu6u1x5u1",
"title": "Как законно приостановить составление протокола ГИБДД на дороге",
"slug": "kak-priostanovit-protokol-gibdd"
},
{
"id": "ewq7fbjbgpo12iv",
"title": "Автоюрист в Сургуте: бесплатная юридическая консультация водителю",
"slug": "avtoyurist-surgut-besplatnaya-konsultaciya"
},
{
"id": "kqh8f6py72yemhl",
"title": "Как правильно заполнять протокол ГИБДД: инструкция для водителя",
"slug": "kak-pravilno-zapolnyat-admin-protokol-gibdd"
},
{
"id": "656dhm888yebhc8",
"title": "Протокол и постановление ГИБДД: отличия и что важно знать",
"slug": "protocol-ili-postanovlenie"
},
{
"id": "f54gic3amc1rmjx",
"title": "5 ошибок водителя при заполнении административного протокола ГИБДД",
"slug": "5-oshibok-voditelya-pri-zapolnenii-protokola-gibdd"
}
];
console.log('🔄 Синхронизация постов');
console.log('='.repeat(40));
console.log('Найдено постов:', postsData.length);
console.log('');
console.log('Инструкция:');
console.log('1. Этот скрипт требует данные постов с локального сервера');
console.log('2. Локальный сервер http://127.0.0.1:8090 недоступен из браузера');
console.log('');
console.log('РЕШЕНИЕ:');
console.log('- Открой файл posts-export.json в редакторе');
console.log('- Скопируй все содержимое');
console.log('- Вставь ниже вместо // POSTS_DATA_GOES_HERE');
console.log('');
console.log('ИЛИ используй Import Collections в настройках');

View file

@ -1,15 +0,0 @@
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
async function main() {
const posts = await pb.collection('posts').getList(1, 500, { filter: 'slug="skrytie-s-mesta-dtp"' });
if (posts.items.length > 0) {
const content = posts.items[0].content;
console.log('First 300 chars:');
console.log(content.substring(0, 300));
}
}
main();

View file

@ -1,16 +0,0 @@
import PocketBase from 'pocketbase';
const PB_URL = 'http://127.0.0.1:8090';
const pb = new PocketBase(PB_URL);
async function main() {
const posts = await pb.collection('posts').getList(1, 3);
for (const post of posts.items as any) {
console.log('=== SLUG:', post.slug, '===');
console.log(post.content?.substring(0, 1500));
console.log('\n---\n');
}
}
main();

View file

@ -1,37 +0,0 @@
import PocketBase from 'pocketbase';
const REMOTE_PB_URL = 'https://avt-back.ru';
const remotePb = new PocketBase(REMOTE_PB_URL);
// Try to get an auth token
async function main() {
console.log('Testing auth...\n');
// Try user auth
try {
await remotePb.collection('users').authWithPassword('redibedi2019@gmail.com', 'Stalin4444');
console.log('User auth: Success');
console.log('Token:', remotePb.authStore.token?.substring(0, 20) + '...');
} catch (e: any) {
console.log('User auth failed:', e.message);
}
// Check auth state
console.log('\nAuth state:');
console.log(' isValid:', remotePb.authStore.isValid);
console.log(' token exists:', !!remotePb.authStore.token);
if (remotePb.authStore.isValid) {
// Try update now
try {
await remotePb.collection('posts').update('e8or2rfsrpoly19', {
description: 'Test update'
});
console.log('\nUpdate after auth: Success!');
} catch (e: any) {
console.log('\nUpdate after auth:', e.message);
}
}
}
main();

View file

@ -1,34 +0,0 @@
import PocketBase from 'pocketbase';
import fs from 'fs';
const PB_URL = 'http://127.0.0.1:8090';
const pb = new PocketBase(PB_URL);
async function exportPosts() {
console.log('📤 Экспорт постов в JSON\n');
const posts = await pb.collection('posts').getList(1, 500);
const exportData = posts.items.map(post => ({
id: post.id,
title: post.title,
slug: post.slug,
content: post.content,
description: post.description,
category: post.category,
categoryColor: post.categoryColor,
image: post.image,
date: post.date,
author: post.author,
readTime: post.readTime,
views: post.views,
draft: post.draft,
}));
fs.writeFileSync('./posts-export.json', JSON.stringify(exportData, null, 2), 'utf-8');
console.log(`Экспортировано ${exportData.length} постов в posts-export.json`);
console.log('\nТеперь нужно импортировать через админ-панель: https://avt-back.ru/_/');
}
exportPosts();

View file

@ -1,39 +0,0 @@
import PocketBase from 'pocketbase';
const PB_URL = 'http://127.0.0.1:8090';
const pb = new PocketBase(PB_URL);
const SLUG_TO_NEW_TITLE: Record<string, string> = {
'skrytie-s-mesta-dtp': 'Скрытие с места ДТП: суть статьи',
'prezumpciya-nevinovnosti-voditelya': 'Презумпция невиновности водителя',
'otkaz-ot-podpisi-v-protokole-gibdd': 'Отказ от подписи в протоколе ГИБДД',
'nezavisimaya-ekspertiza-posle-dtp': 'Независимая экспертиза после ДТП',
'lekarstva-za-rulem-lishenie-prav': 'Лишение прав за лекарства',
'lishenie-prav-za-vstrechku-12-15': 'Лишение прав за выезд на встречную',
'kak-priostanovit-protokol-gibdd': 'Как приостановить протокол ГИБДД',
'avtoyurist-surgut-besplatnaya-konsultaciya': 'Юридическая консультация автоюриста',
'kak-pravilno-zapolnyat-admin-protokol-gibdd': 'Как заполнять протокол ГИБДД',
'protocol-ili-postanovlenie': 'Протокол и постановление ГИБДД',
'5-oshibok-voditelya-pri-zapolnenii-protokola-gibdd': '5 ошибок при заполнении протокола',
};
async function main() {
const posts = await pb.collection('posts').getList(1, 500);
for (const post of posts.items) {
const newTitle = SLUG_TO_NEW_TITLE[post.slug as string];
if (!newTitle) continue;
let content = post.content as string;
// Заменяем старый H2 на новый
if (content.includes('<h2>')) {
content = content.replace(/<h2>[^<]+<\/h2>/, `<h2>${newTitle}</h2>`);
}
await pb.collection('posts').update(post.id, { content });
console.log(`${post.slug}: ${newTitle}`);
}
}
main();

View file

@ -1,25 +0,0 @@
import PocketBase from 'pocketbase';
const PB_URL = 'http://127.0.0.1:8090';
const pb = new PocketBase(PB_URL);
async function main() {
const posts = await pb.collection('posts').getList(1, 500);
let count = 0;
for (const post of posts.items) {
let content = post.content as string;
// Заменяем 2025 на 2026
if (content.includes('2025')) {
content = content.replace(/2025/g, '2026');
await pb.collection('posts').update(post.id, { content });
console.log(`${post.slug}: 2025 → 2026`);
count++;
}
}
console.log(`\nОбновлено постов: ${count}`);
}
main();

View file

@ -1,54 +0,0 @@
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
const content = `<h2>Скрытие с места ДТП: чего ждать и как избежать наказания</h2>
<p>Оставление места ДТП одно из самых строгих нарушений для водителя. В 2026 году суд Сургута вернул водительские права в 73% дел по ч. 2 ст. 12.27 КоАП РФ[^1]. Это значит, шансы на защиту есть, но действовать нужно грамотно.</p>
<h2>Наказание по ч. 2 ст. 12.27 КоАП РФ</h2>
<p>Лишение права управления транспортными средствами от 1 года до 1,5 лет. Это основное наказание, которое назначают в 90% случаев. Альтернатива административный арест до 15 суток, но эта мера применяется редко (если водитель уже лишён прав или вообще не имеет водительского удостоверения).</p>
<blockquote><strong>Важно:</strong> Штраф за скрытие с места ДТП не предусмотрен. Откупиться деньгами на законных основаниях невозможно.</blockquote>
<blockquote><strong>Опасность:</strong> Если в ДТП есть пострадавшие с тяжкими травмами или погибшие, а водитель скрылся ответственность переходит в уголовную по ст. 264 УК РФ. Там предусмотрены реальные сроки лишения свободы.</blockquote>
<h2>Что юридически считается ДТП и скрытием</h2>
<p><strong>ДТП</strong> это событие в процессе движения транспортного средства, при котором погибли или ранены люди, повреждены автомобили, сооружения, грузы или причинён иной материальный ущерб.</p>
<p><strong>Не является ДТП:</strong> если водитель открыл дверь стоящей на парковке машины и ударил соседнее авто. Движения транспорта не было, поэтому ст. 12.27 КоАП РФ не применяется.</p>
<p><strong>Скрытием</strong> признаётся умышленное оставление места происшествия до приезда инспектора.</p>
<h2>Когда можно уехать законно</h2>
<p>ПДД предусматривают пять исключений:</p>
<ol>
<li><strong>Европротокол</strong> без пострадавших, оба с ОСАГО[^2]</li>
<li><strong>Поездка в ГИБДД</strong> для оформления</li>
<li><strong>Освобождение проезда</strong> после фотофиксации</li>
<li><strong>Спасение пострадавшего</strong> с возвратом на место</li>
<li><strong>Обоюдное согласие</strong> с распиской</li>
</ol>
<blockquote> Без доказательств (видео, расписки) не уезжайте.</blockquote>
<h2>Срок давности</h2>
<p><strong>3 месяца</strong> с момента аварии[^3]. Если прошло больше дело обязаны прекратить.</p>
<h2>Что делать, если обвиняют</h2>
<p>Пошаговый план:</p>
<ol>
<li>Не молчите не игнорируйте звонки из полиции</li>
<li>Доказывайте отсутствие умысла плохая видимость, шум, не почувствовали удар</li>
<li>Примиритесь с потерпевшим возместите ущерб и возьмите расписку</li>
<li>Найдите автоюриста желательно того, кто выигрывает дела по 12.27</li>
</ol>
<blockquote>📊 В 2026 году суд вернул права в 73% дел. Шансы есть даже в «безнадёжных» ситуациях.</blockquote>
<h2>Вывод</h2>
<p>Если услышали подозрительный звук на парковке остановитесь и проверьте. Лучше 30 минут поискать владельца царапины, чем 1,5 года ходить пешком.</p>
[^1]: Статистика судебных решений по Сургуту за 2026 год
[^2]: Федеральный закон 40-ФЗ "Об ОСАГО"
[^3]: Статья 4.5 КоАП РФ о сроках давности`;
async function main() {
const posts = await pb.collection('posts').getList(1, 500, { filter: 'slug="skrytie-s-mesta-dtp"' });
if (posts.items.length > 0) {
await pb.collection('posts').update(posts.items[0].id, {
content: content,
description: content.replace(/<[^>]+>/g, '').substring(0, 200)
});
console.log('✓ восстановлено');
}
}
main();

View file

@ -1,88 +0,0 @@
import PocketBase from 'pocketbase';
const LOCAL_PB_URL = 'http://127.0.0.1:8090';
const REMOTE_PB_URL = 'https://avt-back.ru';
const ADMIN_EMAIL = 'redibedi2019@gmail.com';
const ADMIN_PASSWORD = 'Stalin4444';
const localPb = new PocketBase(LOCAL_PB_URL);
const remotePb = new PocketBase(REMOTE_PB_URL);
interface Post {
id: string;
title: string;
content: string;
slug: string;
description: string;
}
const REMOTE_IDS: Record<string, string> = {
'skrytie-s-mesta-dtp': 'e8or2rfsrpoly19',
'prezumpciya-nevinovnosti-voditelya': 'sdthyq0xurxxzfw',
'otkaz-ot-podpisi-v-protokole-gibdd': 'no247l14oxw156i',
'lekarstva-za-rulem-lishenie-prav': 'eflpgypt1r78q3q',
'lishenie-prav-za-vstrechku-12-15': 'kmt2cpiu47jsp9c',
'nezavisimaya-ekspertiza-posle-dtp': '87u3tnboztln5w1',
'kak-priostanovit-protokol-gibdd': 'at22ktwu6u1x5u1',
'avtoyurist-surgut-besplatnaya-konsultaciya': 'ewq7fbjbgpo12iv',
'kak-pravilno-zapolnyat-admin-protokol-gibdd': 'kqh8f6py72yemhl',
'protocol-ili-postanovlenie': '656dhm888yebhc8',
'5-oshibok-voditelya-pri-zapolnenii-protokola-gibdd': 'f54gic3amc1rmjx',
};
async function syncPosts() {
console.log('🔄 Синхронизация постов\n');
console.log('='.repeat(60));
// Try to auth as user on remote
try {
await remotePb.collection('users').authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
console.log('✓ Авторизован на remote\n');
} catch (error: any) {
console.log('⚠ Ошибка авторизации:', error.message);
console.log('Пробуем через admins auth...\n');
try {
await remotePb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
console.log('✓ Авторизован через admin\n');
} catch (e2: any) {
console.log('⚠ Admin auth тоже не работает:', e2.message);
}
}
const localPosts = await localPb.collection('posts').getList(1, 500);
const localList = localPosts.items as unknown as Post[];
console.log(`Локально постов: ${localList.length}`);
console.log(`Авторизован: ${remotePb.authStore.isValid}\n`);
let synced = 0;
let failed = 0;
for (const post of localList) {
const remoteId = REMOTE_IDS[post.slug];
if (!remoteId) {
failed++;
continue;
}
try {
await remotePb.collection('posts').update(remoteId, {
content: post.content,
description: post.description,
});
console.log(`${post.slug}`);
synced++;
} catch (error: any) {
console.error(`${post.slug}: ${error.message}`);
failed++;
}
}
console.log('\n' + '='.repeat(60));
console.log(`Результат: синхронизировано ${synced}, ошибок ${failed}`);
}
syncPosts();

View file

@ -1,17 +0,0 @@
import PocketBase from 'pocketbase';
const pb = new PocketBase('https://avt-back.ru');
async function main() {
console.log('Проверяем коллекции на production:\n');
try {
// Попробуем разные способы
const result = await pb.collections.getFullList();
console.log('Коллекции:', result.map(c => c.name).join(', '));
} catch (e: any) {
console.log('Ошибка:', e.message);
}
}
main();

View file

@ -1,54 +0,0 @@
// Тест голосования
import PocketBase from 'pocketbase';
const PB_URL = process.env.POCKETBASE_URL || 'http://127.0.0.1:8090';
// Симулируем токен пользователя (нужно получить реальный)
const testToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfcGJfdXNlcnNfYXV0aF8iLCJleHAiOjE3NzY5NTI4NjUsImlkIjoidGR0Z2JuNGFrb3BsZGhvIiwicmVmcmVzaGFibGUiOnRydWUsInR5cGUiOiJhdXRoIn0.A1oacYog9de5GjZj5aNkHeRDWyjQKXvTSkEBFr4hi9Q';
async function testVoting() {
const pb = new PocketBase(PB_URL);
// Симулируем авторизацию
pb.authStore.save(testToken, { id: 'tdtgbn4akopldho', email: 'redibedi2019@gmail.com' });
console.log('Auth valid:', pb.authStore.isValid);
console.log('User ID:', pb.authStore.model?.id);
// Тест: получить голоса поста
try {
const postId = 'test-post-id';
const votes = await pb.collection('post_votes').getList(1, 1000, {
filter: `post_id="${postId}"`,
});
console.log('\n--- Тест получения голосов ---');
console.log('Всего голосов:', votes.totalItems);
const likes = votes.items.filter(v => v.vote_type === 'like').length;
const dislikes = votes.items.filter(v => v.vote_type === 'dislike').length;
console.log('Likes:', likes);
console.log('Dislikes:', dislikes);
} catch (e) {
console.error('Ошибка:', e);
}
// Тест: создать голос
try {
console.log('\n--- Тест создания голоса ---');
const newVote = await pb.collection('post_votes').create({
post_id: 'test-post-123',
user_id: 'tdtgbn4akopldho',
vote_type: 'like',
});
console.log('Создан голос:', newVote.id);
// Удаляем тестовый голос
await pb.collection('post_votes').delete(newVote.id);
console.log('Удален тестовый голос');
} catch (e) {
console.error('Ошибка создания:', e);
}
}
testVoting();