diff --git a/frontend/scripts/add-h2.ts b/frontend/scripts/add-h2.ts deleted file mode 100644 index a971f7a..0000000 --- a/frontend/scripts/add-h2.ts +++ /dev/null @@ -1,59 +0,0 @@ -import PocketBase from 'pocketbase'; - -const pb = new PocketBase('http://127.0.0.1:8090'); - -const content = `

Наказание по ч. 2 ст. 12.27 КоАП РФ — лишение прав или арест

-

Оставление места ДТП — одно из самых строго наказуемых нарушений. Но есть нюансы, о которых молчат 90% водителей. За 2026 год суд Сургута вернул права в 73% дел по этой статье.

-

Что грозит по статье 12.27, ч. 2

-

Судьи не любят церемониться:

- -

💰 Штрафа НЕТ. Заплатить не получится — только пешком ходить или сидеть.

-
❗ Важно: арест применяют в исключительных ситуациях. В основном — лишение.
-

Что считается ДТП и «скрытием»

-

ДТП — это не только «въехал в машину». Это любое событие при движении транспорта с:

- -

Скрытием признают умышленный отъезд до приезда инспектора. Ключевое слово — умышленный. Именно на этом можно сыграть в суде.

-
📌 Пример: зацепили зеркало во дворе, не заметили и уехали — уже формально нарушение. Но если докажете, что не видели/не слышали, умысел отпадает.
-

Когда можно уехать и не сесть

-

Есть целых 5 ситуаций, когда вы не нарушитель:

-
    -
  1. Европротокол — без пострадавших, оба с ОСАГО, ущерб до лимита.
  2. -
  3. Поездка в ГИБДД — договорились на месте и едете оформлять вместе.
  4. -
  5. Освобождение проезда — сфотографировали схему и разъехались.
  6. -
  7. Спасение пострадавшего — отвезли в больницу, НО потом вернулись на место.
  8. -
  9. Обоюдное согласие — расписка от второго водителя.
  10. -
-
⚠️ Без доказательств (видео, расписки) — не уезжайте.
-

Срок давности

-

3 месяца с момента ДТП и до решения суда. Если прошло больше — дело обязаны прекратить. Но: срок останавливается, если вы скрываетесь от следствия.

-

Что делать, если обвиняют

-

Пошаговый план, который реально работает:

-
    -
  1. Не молчите — не игнорируйте звонки из полиции. Это усугубляет.
  2. -
  3. Доказывайте отсутствие умысла — плохая видимость, шум, дети в салоне, не почувствовали удар.
  4. -
  5. Примиритесь с потерпевшим — возместите ущерб и возьмите расписку. Суды идут навстречу.
  6. -
  7. Найдите автоюриста — желательно того, кто выигрывает именно дела по 12.27.
  8. -
-
📊 В 2026 году суд вернул права в 73% дел. Шансы есть даже в «безнадежных» ситуациях.
-

Вывод

-

Услышали подозрительный звук на парковке — остановитесь и проверьте. Лучше 30 минут поискать владельца царапины, чем 1,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(); \ No newline at end of file diff --git a/frontend/scripts/add-post-content.js b/frontend/scripts/add-post-content.js deleted file mode 100644 index bd340ab..0000000 --- a/frontend/scripts/add-post-content.js +++ /dev/null @@ -1,96 +0,0 @@ -import PocketBase from 'pocketbase'; - -const pb = new PocketBase('http://127.0.0.1:8090'); - -const content = `

Введение

-

Когда инспектор ГИБДД останавливает вас и начинает заполнять протокол, большинство водителей допускают критические ошибки. Они думают, что протокол — это просто формальность, которую нужно поскорее подписать и уехать.

-

На самом деле, каждое слово в этом документе может стоить вам водительских прав или десятков тысяч рублей. Разбираем 5 самых опасных ошибок, которые уничтожают вашу защиту еще до суда.

- -

Ошибка 1: Признание вины словом «согласен»

-

Самая частая и самая губительная ошибка. Водитель, не желая конфликтовать, просто пишет: «согласен» или вообще оставляет графу пустой — думая, что так будет лучше.

-
-

Почему это убивает защиту: Согласно ст. 1.5 КоАП РФ, лицо, совершившее правонарушение, обязано доказывать свою невиновность. Но если вы сами признали вину — обжаловать постановление практически невозможно.

-
-

Что писать вместо этого:

-
-

«С нарушением ПДД не согласен, прошу помощи защитника»

-

«С протоколом не согласен, требую рассмотрения дела судом»

-

«Показания даю только в присутствии адвоката»

-
-

Юридический нюанс: Даже если вы признали вину на месте, у вас есть 10 суток на обжалование (ст. 30.1 КоАП). Но чем раньше вы заявите о несогласии — тем сильнее ваша позиция.

- -

Ошибка 2: Пустая графа «Объяснения»

-

Многие водители считают, что писать нечего — ведь «инспектор и так всё написал правильно». Это — грубейшая ошибка.

-
-

Почему это опасно: Графа «Объяснения» — единственное место, где вы можете изложить СВОЮ версию событий. Если она пустая, инспектор заполнит её потом так, как выгодно ему. Без ваших объяснений суд будет опираться только на показания инспектора.

-
-

Что обязательно указать:

-
-

✅ обстоятельства, которые смягчают вашу вину

-

✅ наличие свидетелей (даже если инспектор их не ��писал)

-

✅ ссылку на видеозапись (регистратор, напарник, камеры)

-

✅ указание на нарушения со стороны инспектора

-
-

Пример формулировки: «Ехал со скоростью 60 км/ч в левом ряду. Впереди двигался грузовик, который резко перестроился надо мной. Я вынужден был продолжить движение, чтобы избежать столкновения. Имеется видеозапись с регистратора»

- -

Ошибка 3: Подпись без внесения замечаний

-

Водитель подписывает протокол, не читая и не внося никаких изменений. «А чего там читать, и так всё понятно» — типичная фраза.

-
-

Почему это губит дело: Подписывая протокол без замечаний, вы соглашаетесь со ВСЕМ, что там написано. Даже если инспектор ошибся в описании обстоятельств, ваша подпись — это согласие с его версией.

-
-

Правильный алгоритм:

-
    -
  1. Внимательно прочитай ВЕСЬ текст
  2. -
  3. Найди неточности и ошибки
  4. -
  5. Внеси запись: «Не согласен с п. 3 протокола, так как...»
  6. -
  7. Потребуй внести изменения
  8. -
  9. Только после этого подписывай
  10. -
-

Важно: Инспектор обязан рассмотреть ваши замечания. Если он отказывается — сделайте запись: «Инспектор отказался внести мои замечания». Это грубое нарушение ст. 28.2 КоАП РФ.

- -

Ошибка 4: Неуказание свидетелей и видеозаписи

-

Инспектор спрашивает: «Есть свидетели?» Водитель отвечает: «Нет» — и даже не думает о том, что в машине сидит жена, друг или просто попутчик.

-
-

Почему это критично: Показания свидетелей — одно из самых сильных доказательств в суде. А видеозапись может вообще опровергнуть версию инспектора.

-
-

Что делать:

-
-

✅ Всегда указывайте пассажиров как свидетелей

-

✅ Записывайте марку и модель вашего регистратора

-

✅ Указывайте камеры видеонаблюдения поблизости

-

✅ Если инспектор не вписывает свидетелей — впишите сами в графе «Объяснения»

-
-

Пример: «В автомобиле находились: Петров А.А. (пассажир), Сидоров В.В. (пассажир). Имеется видеозапись с регистратора GoPro, прошу приобщить к материалам дела»

- -

Ошибка 5: Прочерки и пустые места без «Z»

-

Водитель подписал протокол и уехал. А через неделю выясняется, что в графе «Свидетели» теперь написаны два человека, которых он никогда не видел. Как?

-
-

Механизм: Инспектор просто дописывает нужные данные после того, как вы уехали. В пустой графе можно написать всё, что угодно.

-
-

Простое решение: Перед подписью зачеркните все пустые графы и свободные места буквой Z (или большой чертой). Это называется «гашение полей».

-

Как это делать:

- -

Теперь инспектор не сможет ничего дописать после вашего уезда.

- -

Что делать, если вы уже допустили эти ошибки?

-

Даже если вы подписали протокол с признанием вины — у вас есть 10 суток на обжалование (ст. 30.1 КоАП РФ). Главное — не тяните.

-
-

Алгоритм действий:

-

1. Получите копию протокола

-

2. Изучите все материалы дела

-

3. Напишите жалобу в ГИБДД или суд

-

4. Приложите доказательства (видеозапись, показания свидетелей)

-
-

Если времени прошло больше 10 суток — обращайтесь к автоюристу. Мы найдем процессуальные нарушения, которые помогут отменить постановление.

- -

Заключение

-

Протокол ГИБДД — это не приговор. Это инструмент, который можно использовать в вашу защиту. Главное — не совершайте этих 5 ошибок и всегда помните: каждое ваше слово имеет значение.

-

Если остановили и составляют протокол — сохраняйте спокойствие, пишите свои объяснения и требуйте копию. Ваши права защищены законом.

`; - -await pb.collection('posts').update('denps5ofoo71sqe', { content }); - -console.log('Content added to post denps5ofoo71sqe'); \ No newline at end of file diff --git a/frontend/scripts/analyze-posts-detailed.ts b/frontend/scripts/analyze-posts-detailed.ts deleted file mode 100644 index 623011b..0000000 --- a/frontend/scripts/analyze-posts-detailed.ts +++ /dev/null @@ -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>/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(); \ No newline at end of file diff --git a/frontend/scripts/analyze-posts.ts b/frontend/scripts/analyze-posts.ts deleted file mode 100644 index d0e9817..0000000 --- a/frontend/scripts/analyze-posts.ts +++ /dev/null @@ -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>/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(); \ No newline at end of file diff --git a/frontend/scripts/browser-sync.js b/frontend/scripts/browser-sync.js deleted file mode 100644 index 66ad6ff..0000000 --- a/frontend/scripts/browser-sync.js +++ /dev/null @@ -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 в настройках'); \ No newline at end of file diff --git a/frontend/scripts/check-h2.ts b/frontend/scripts/check-h2.ts deleted file mode 100644 index 58bdf9e..0000000 --- a/frontend/scripts/check-h2.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/check-posts.ts b/frontend/scripts/check-posts.ts deleted file mode 100644 index aad013f..0000000 --- a/frontend/scripts/check-posts.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/debug-post.ts b/frontend/scripts/debug-post.ts deleted file mode 100644 index 5582d01..0000000 --- a/frontend/scripts/debug-post.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/export-posts.ts b/frontend/scripts/export-posts.ts deleted file mode 100644 index e40ea5b..0000000 --- a/frontend/scripts/export-posts.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/fix-h2.ts b/frontend/scripts/fix-h2.ts deleted file mode 100644 index ba23f0c..0000000 --- a/frontend/scripts/fix-h2.ts +++ /dev/null @@ -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 = { - '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('

')) { - content = content.replace(/

[^<]+<\/h2>/, `

${newTitle}

`); - } - - await pb.collection('posts').update(post.id, { content }); - console.log(`✓ ${post.slug}: ${newTitle}`); - } -} - -main(); \ No newline at end of file diff --git a/frontend/scripts/fix-year.ts b/frontend/scripts/fix-year.ts deleted file mode 100644 index 1505152..0000000 --- a/frontend/scripts/fix-year.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/restore.ts b/frontend/scripts/restore.ts deleted file mode 100644 index 1d7b889..0000000 --- a/frontend/scripts/restore.ts +++ /dev/null @@ -1,54 +0,0 @@ -import PocketBase from 'pocketbase'; - -const pb = new PocketBase('http://127.0.0.1:8090'); - -const content = `

Скрытие с места ДТП: чего ждать и как избежать наказания

-

Оставление места ДТП — одно из самых строгих нарушений для водителя. В 2026 году суд Сургута вернул водительские права в 73% дел по ч. 2 ст. 12.27 КоАП РФ[^1]. Это значит, шансы на защиту есть, но действовать нужно грамотно.

-

Наказание по ч. 2 ст. 12.27 КоАП РФ

-

Лишение права управления транспортными средствами — от 1 года до 1,5 лет. Это основное наказание, которое назначают в 90% случаев. Альтернатива — административный арест до 15 суток, но эта мера применяется редко (если водитель уже лишён прав или вообще не имеет водительского удостоверения).

-
Важно: Штраф за скрытие с места ДТП не предусмотрен. Откупиться деньгами на законных основаниях невозможно.
-
Опасность: Если в ДТП есть пострадавшие с тяжкими травмами или погибшие, а водитель скрылся — ответственность переходит в уголовную по ст. 264 УК РФ. Там предусмотрены реальные сроки лишения свободы.
-

Что юридически считается ДТП и скрытием

-

ДТП — это событие в процессе движения транспортного средства, при котором погибли или ранены люди, повреждены автомобили, сооружения, грузы или причинён иной материальный ущерб.

-

Не является ДТП: если водитель открыл дверь стоящей на парковке машины и ударил соседнее авто. Движения транспорта не было, поэтому ст. 12.27 КоАП РФ не применяется.

-

Скрытием признаётся умышленное оставление места происшествия до приезда инспектора.

-

Когда можно уехать законно

-

ПДД предусматривают пять исключений:

-
    -
  1. Европротокол — без пострадавших, оба с ОСАГО[^2]
  2. -
  3. Поездка в ГИБДД — для оформления
  4. -
  5. Освобождение проезда — после фотофиксации
  6. -
  7. Спасение пострадавшего — с возвратом на место
  8. -
  9. Обоюдное согласие — с распиской
  10. -
-
⚠️ Без доказательств (видео, расписки) — не уезжайте.
-

Срок давности

-

3 месяца с момента аварии[^3]. Если прошло больше — дело обязаны прекратить.

-

Что делать, если обвиняют

-

Пошаговый план:

-
    -
  1. Не молчите — не игнорируйте звонки из полиции
  2. -
  3. Доказывайте отсутствие умысла — плохая видимость, шум, не почувствовали удар
  4. -
  5. Примиритесь с потерпевшим — возместите ущерб и возьмите расписку
  6. -
  7. Найдите автоюриста — желательно того, кто выигрывает дела по 12.27
  8. -
-
📊 В 2026 году суд вернул права в 73% дел. Шансы есть даже в «безнадёжных» ситуациях.
-

Вывод

-

Если услышали подозрительный звук на парковке — остановитесь и проверьте. Лучше 30 минут поискать владельца царапины, чем 1,5 года ходить пешком.

-[^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(); \ No newline at end of file diff --git a/frontend/scripts/sync-posts.ts b/frontend/scripts/sync-posts.ts deleted file mode 100644 index b7112bf..0000000 --- a/frontend/scripts/sync-posts.ts +++ /dev/null @@ -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 = { - '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(); \ No newline at end of file diff --git a/frontend/scripts/test-login.ts b/frontend/scripts/test-login.ts deleted file mode 100644 index 51e7392..0000000 --- a/frontend/scripts/test-login.ts +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/frontend/scripts/test-votes.ts b/frontend/scripts/test-votes.ts deleted file mode 100644 index e6e2cd0..0000000 --- a/frontend/scripts/test-votes.ts +++ /dev/null @@ -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(); \ No newline at end of file