Files
chronicle.nixg.ru/ROADMAP.md
T

24 KiB
Raw Blame History

CHRONICLE ROADMAP

The Operating System for Technical Creators
Единая среда для создания, публикации и архивирования технического контента


🎯 Миссия

Решить проблему фрагментации цифровой идентичности технических авторов (разработчики, DevOps, IT-евангелисты) и дать им инструмент для работы с кодом в статьях без боли.

Боль: В рунете нет редактора лонгридов с нормальной подсветкой синтаксиса. Тех-блогеры мучаются между Telegram (нет подсветки), Хабром (закрытая платформа) и скриншотами кода (🤮).

Решение: Chronicle — редактор + кросс-постинг + архив на своём сайте.


🗺️ Дорожная карта

Фаза 0: Telegram Archiver (MVP) ✅ (В РАБОТЕ)

Цель: Базовый архиватор Telegram-канала в Markdown для Hugo

  • 0.1 Парсинг Telegram-канала (API / MTProto) ✅ ВЫПОЛНЕНА
  • 0.2 Конвертация постов в Markdown (с сохранением форматирования) ✅ ВЫПОЛНЕНА
  • 0.3 Экспорт медиа (изображения, видео, документы) ✅ ВЫПОЛНЕНА
  • 0.4 Генерация структуры файлов для Hugo ✅ ВЫПОЛНЕНА
  • 0.5 Front-matter для каждого поста (дата, теги, ID) ✅ ВЫПОЛНЕНА
  • 0.6 Базовая дедупликация при повторном запуске ✅ ВЫПОЛНЕНА
  • 0.7 Извлечение тегов из постов (#хэштеги) и добавление во front-matter ✅ ВЫПОЛНЕНА
  • 0.8 Обработка медиа: встраивание в Markdown для Hugo (image shortcode, video) ✅ ВЫПОЛНЕНА
  • 0.9 Сохранение прямых ссылок на посты (для репостов и оригиналов)
  • 0.10 Исправление бага: посты без index.md (только медиа в папке)
  • 0.11 Конвертация видео-кружков и .bin файлов в нормальный формат (mp4)
  • 0.12 Отчёт о неуспешно скачанных файлах (таймаут/размер) + список URL для дозагрузки
  • 0.13 Корректная временная зона (GMT+3 Москва) вместо UTC
  • 0.14 Прямые ссылки на скачивание файлов в front-matter (для дозагрузки)
  • 0.15 Исправление: размер файла = 0 во front-matter (должен браться из Telegram)
  • 0.16 Расширенный front-matter: ссылки на канал, автора, оригинальный пост
  • 0.17 Многопоточное скачивание медиа (параллельные загрузки)
  • 0.18 Валидация скачанных файлов (проверка целостности)
  • 0.19 Очередь на скачивание: сбор URL → многопоточная загрузка
  • 0.20 Аудио-файлы: длительность, waveform для Hugo (красивый плеер)
  • 0.21 Resume: возобновление прерванной архивации (по последнему ID)
  • 0.22 Формат тегов для Hugo: tags: ["tag1", "tag2"] вместо списка
  • 0.23 Обработка трансляций (streaming messages) без текста
  • 0.24 Голосовые сообщения: определение формата (ogg/mp3), метаданные

Результат: Консольная утилита, которая по ссылке на канал скачивает все посты в папку content/posts/ для Hugo

Критерий готовности: Можно запустить на своём канале dedinit и получить работающий статический сайт


Фаза 1: Брендинг и запуск сайта ⬜

Цель: Зарегистрировать бренд, запустить сайт-визитку

  • 1.1 DNS для c7e.ru настроен
  • 1.2 SSL-сертификат (Caddy / Let's Encrypt)
  • 1.3 Лендинг (1 экран):
    • Заголовок + слоган
    • Краткое описание идеи
    • Email для связи / форма подписки на ранний доступ
  • 1.4 GitHub репозиторий: github.com/evgenystor/c7e или github.com/evgenystor/chronicle
  • 1.5 README.md с:
    • ASCII-арт логотипом
    • Описанием проекта
    • Roadmap
    • Инструкциями для контрибьюторов

Результат: c7e.ru — рабочая точка входа, есть куда направить первых пользователей


Фаза 2: Редактор с подсветкой кода (Q2 2026)

Цель: Дать тех-блогерам редактор, в котором можно писать статьи с кодом

Требования пользователя (2026-09-18): отдельный модуль для встраивания в другие проекты (VESTI — первый потребитель) + основа блогоплатформы chronicle:

  • Блоки кода с кнопкой «Скопировать»

  • Включение/выключение нумерации строк (копирование БЕЗ номеров)

  • Подсветка синтаксиса по выбранному языку

  • Выделение инлайн-команд в тексте (`cmd`)

  • Живой предпросмотр + GFM

  • 2.1 Веб-редактор — как ОТДЕЛЬНЫЙ модуль (web component / npm-пакет / собственная сборка), встраивается в VESTI и другие проекты — ПЕРЕНЕСЁН в /opt/md-editor (2026-09-20), реализуется там: web-компонент <md-editor> (CodeMirror 6, без npm)

  • 2.2 Интеграция Monaco Editor (как в VS Code) — перенесено в /opt/md-editor (2026-09-20: CodeMirror 6, не Monaco — ADR 0001)

  • 2.3 Поддержка языков: Python, JavaScript, Go, Rust, Bash, SQL — перенесено в /opt/md-editor (2026-09-20: + Markdown, JSON, YAML, TOML, HTML, CSS)

  • 2.4 Темы оформления (светлая / тёмная) — перенесено в /opt/md-editor

  • 2.5 Блоки кода с кнопкой «скопировать» + нумерация строк (toggle; копирование без номеров) — перенесено в /opt/md-editor

  • 2.6 Markdown-режим + WYSIWYG превью — перенесено в /opt/md-editor (web-компонент <md-editor>, живой предпросмотр + GFM)

  • 2.7 Сохранение черновиков (локально / в GitHub) — перенесено в /opt/md-editor (черновики в localStorage)

  • 2.8 Drag-and-drop изображений — перенесено в /opt/md-editor

Результат: Можно написать статью с кодом, и она будет выглядеть как в IDE


Фаза 3: Интеграция с архивом (Q3 2026)

Цель: Объединить редактор и архив в единую систему

  • 3.1 Написанное в редакторе → автоматически в архив (Markdown-файлы)
  • 3.2 Импорт постов из Telegram (через Phase 0)
  • 3.3 Редактирование старых постов из архива
  • 3.4 Поиск по всему контенту (full-text)
  • 3.5 Теги и категории
  • 3.6 Версионность постов (как Git: история изменений, откат)

Результат: Весь контент в одном месте, можно редактировать и искать


Фаза 4: Публикация и кросс-постинг (Q4 2026)

Цель: Публикация в несколько соцсетей одной кнопкой

  • 4.1 Интеграция с Telegram Bot API (публикация в канал)
  • 4.2 Интеграция с VK API
  • 4.3 Интеграция с Habr API (или парсинг формы)
  • 4.4 Интеграция с Medium API
  • 4.5 Календарь публикаций
  • 4.6 Отложенные посты (очередь)
  • 4.7 Адаптация контента под платформы:
    • Telegram: коротко, без сложных блоков
    • Habr: полная версия с кодом
    • VK: адаптированный текст
  • 4.8 Превью: как пост будет выглядеть на каждой платформе

Результат: Написал один раз → опубликовал везде с адаптацией


Фаза 5: Аналитика и экосистема (Q1-Q2 2027)

Цель: Превратить Chronicle в полноценную платформу

  • 5.1 Сбор статистики по платформам (просмотры, реакции, комментарии)
  • 5.2 Аналитика вовлеченности
  • 5.3 Лучшее время для постов (рекомендации)
  • 5.4 Сбор комментариев с платформ обратно в Chronicle
  • 5.5 Командная работа (несколько авторов)
  • 5.6 API для разработчиков
  • 5.7 Мобильное приложение (черновики, заметки)
  • 5.8 White-label решения для брендов

Результат: Полноценная операционная система для технического креатора


💰 Монетизация

План Цена Что включает
Free $0 1 соцсеть (Telegram), базовый архив, редактор
Pro $9/мес До 3 соцсетей, календарь, базовая аналитика
Creator $19/мес До 10 соцсетей, приоритетная поддержка, API
Team $49/мес Командная работа, общий архив, white-label

Дополнительно:

  • White-label сайты: $299 разово
  • Хостинг сайта: $5/мес (опционально)
  • API доступ: $29/мес

📊 Метрики успеха

Фаза Метрика Цель
Phase 0 Каналов архивировано 10+
Phase 1 Посетителей на c7e.ru 100+ за первый месяц
Phase 2 Активных редакторов 50+
Phase 4 Публикаций в день 100+
Phase 5 Платящих пользователей 500+

📝 Детали задач Фазы 0

Задача 0.7: Извлечение тегов (#хэштеги)

Проблема: В Telegram теги — это просто текст с #. Для Hugo нужно извлечь их и добавить во front-matter.

Реализация:

  • Парсинг текста поста на наличие #хэштегов (regex: #[\wа-яА-ЯёЁ\d_]+)
  • Извлечение в список tags: [tag1, tag2, tag3]
  • Добавление во front-matter:
    ---
    message_id: 1044
    date: 2026-03-05T18:05:47+00:00
    author: Дед in АйТи
    tags: [linux, debian, usermod, sudo]
    ---
    
  • Удаление хэштегов из текста поста (опционально)

Результат: Hugo сможет генерировать страницу /tags/linux/ со списком всех постов с этим тегом.


Задача 0.8: Обработка медиа для Hugo

Проблема: Hugo имеет свои shortcodes для встраивания медиа. Нужно использовать их вместо стандартного Markdown.

Hugo shortcodes для медиа:

Изображения:

{{< figure src="photo.jpg" alt="Описание" title="Заголовок" >}}

Видео:

{{< video src="video.mp4" >}}

Аудио:

{{< audio src="audio.mp3" >}}

Документы:

{{< download-file href="document.pdf" title="Скачать PDF" >}}

Реализация:

  • При генерации index.md проверять тип медиа
  • Вместо ![caption](file.jpg) использовать Hugo shortcodes
  • Для изображений: извлекать alt, title из caption
  • Для видео/аудио: определять формат и подбирать shortcode

Пример выходного файла:

---
message_id: 1042
date: 2026-03-05T07:09:24+00:00
author: Дед in АйТи
media_files:
  - filename: photo_20260305_070924.jpg
    type: photo
    caption: "Скриншот конфига"
---

{{< figure src="photo_20260305_070924.jpg" alt="Скриншот конфига" >}}

Текст поста...

Альтернатива: Оставить стандартный Markdown ![]() — Hugo тоже его понимает. Shortcodes дают больше контроля (lightbox, подписи, размеры).


📝 Найденные проблемы при полном тестировании (992 поста)

Задача 0.9: Прямые ссылки на посты

Проблема: При скачивании репоста сохраняется название канала и ID поста, но нет прямой ссылки на оригинал.

Реализация:

  • Для репостов: original_post_url: https://t.me/channel_name/12345
  • Для канала: channel_url: https://t.me/dedinit
  • Сохранять в front-matter для каждой записи

Пример:

---
message_id: 1015
repost_from: 987
repost_channel: "Some Channel"
original_post_url: "https://t.me/somechannel/987"
channel_url: "https://t.me/dedinit/1015"
---

Задача 0.10: Посты без index.md

Проблема: Пост 987 — в папке только mp3 файл, index.md отсутствует.

Причина: Вероятно, ошибка при записи файла или пост был удалён/изменён.

Решение:

  • Проверять наличие index.md после записи
  • Создавать минимальный front-matter даже если текст пуст
  • Логировать ошибки записи

Задача 0.11: Видео-кружки и .bin файлы

Проблема: Пост 988 — видео-кружок сохранился как .bin файл.

Причина: Telethon не определяет расширение для video_note.

Решение:

  • Определять тип по MIME (video/mp4 для кружков)
  • Переименовывать .bin → .mp4 после скачивания
  • Опционально: конвертировать в нормальное видео через ffmpeg

Задача 0.12: Отчёт о неуспешно скачанных файлах

Проблема: Файлы по таймауту или размеру пропускаются, но не сохраняется информация для последующей дозагрузки.

Реализация:

  • Создавать 2big2get.md (уже есть) + to_download_later.md
  • Сохранять прямые ссылки на файлы: https://t.me/dedinit/123/file.mp4
  • Добавить команду для дозагрузки: python run_archiver.py --resume-downloads to_download_later.md

Задача 0.13: Временная зона (GMT+3 Москва)

Проблема: date: '2026-01-18T08:11:24+00:00' — UTC вместо Москвы (GMT+3).

Пост был в 11:11 по Москве, а указано 08:11 UTC.

Решение:

  • Определять часовой пояс канала/автора
  • Конвертировать время: date.astimezone(timezone('Europe/Moscow'))
  • Сохранять с правильным offset: +03:00

Задача 0.14: Прямые ссылки на файлы

Проблема: При таймауте нет ссылки для последующей загрузки.

Решение:

  • Telethon может получить прямую ссылку: await client.download_media(..., file=file_path) → сохранить URL
  • Добавлять во front-matter: download_url: "https://..."
  • Для дозагрузки использовать список URL

Задача 0.15: Размер файла = 0 во front-matter

Проблема: size: 0 вместо реального размера.

Причина: Размер не проставляется после скачивания.

Решение:

  • Брать размер из атрибутов Telegram: doc.size
  • Либо проверять размер файла после записи: Path(filepath).stat().st_size

Задача 0.16: Расширенный front-matter

Проблема: Нет ссылок на канал, автора, оригинальный пост.

Текущий front-matter:

author: Дед in АйТи

Нужно:

author: Дед in АйТи
author_username: "@dedinit"
channel_title: "Дед in АйТи"
channel_username: "@dedinit"
channel_url: "https://t.me/dedinit"
post_url: "https://t.me/dedinit/1234"
original_post_url: "https://t.me/otherchannel/987"  # для репостов

Задача 0.17: Многопоточное скачивание медиа

Идея: Скачивать медиафайлы параллельно (5-10 потоков).

Оценка:

  • Telethon поддерживает asyncio.gather() для параллельных загрузок
  • Ограничение: Telegram может блокировать при слишком частых запросах
  • Реалистично: 3-5 одновременных загрузок

План:

  • Создать очередь на скачивание
  • Запускать 3-5 корутин параллельно
  • Соблюдать rate limits (паузы между запросами)

Задача 0.18: Валидация скачанных файлов

Проблема: Файл 618 — голосовуха 384 КБ, но нет проверки целостности.

Решение:

  • Проверять размер после скачивания (сравнить с ожидаемым)
  • Проверять заголовки файлов (magic bytes)
  • Логировать битые файлы в corrupted.md

Задача 0.19: Очередь на скачивание + многопоточность

Идея: Разделить на 2 прохода:

  1. Сбор всех URL файлов (быстро)
  2. Многопоточная загрузка по списку

План:

  • Первый проход: собрать все download_url
  • Сохранить в queue.json
  • Второй проход: загружать параллельно (3-5 потоков)
  • Resume: продолжать с места обрыва

Задача 0.20: Аудио-файлы для Hugo

Проблема: Голосовые сообщения без метаданных (длительность, waveform).

Вопросы:

  • Нужна ли длительность во front-matter? (duration: 45 секунд)
  • Как отобразить waveform в Hugo?

Решение:

  • Извлекать длительность из атрибутов Telegram: doc.attributes.duration
  • Для waveform: использовать Hugo shortcode с JS-библиотекой (wavesurfer.js)
  • Пример: {{< audio-player src="file.ogg" waveform="true" >}}

Задача 0.21: Resume прерванной архивации

Проблема: 2 часа на 1000 постов — при обрыве начинать заново.

Решение:

  • Сохранять последний обработанный ID: last_message_id: 992
  • Команда: python run_archiver.py --resume
  • Пропускать уже скачанные посты (дедупликация по ID)

Задача 0.22: Формат тегов для Hugo

Проблема: Сейчас:

tags:
- 1с
- debian

Hugo предпочитает:

tags: ["1с", "debian", "postgres"]

Решение:

  • Изменить формат вывода YAML
  • Протестировать оба варианта в Hugo

Задача 0.23: Обработка трансляций

Проблема: Посты 122, 120 — трансляции без текста, только метаданные.

Вопросы:

  • Что приходит от Telegram для streaming messages?
  • Можно ли извлечь длительность, участников, тему?

Решение:

  • Изучить message.media для трансляций
  • Сохранять метаданные во front-matter
  • Создавать index.md с информацией о трансляции

Задача 0.24: Голосовые сообщения

Проблема: Голосовухи скачиваются как .bin или .ogg.

Вопросы:

  • Как определить формат (ogg/mp3)?
  • Нужны ли метаданные (длительность, размер)?

Решение:

  • Определять по MIME: audio/ogg → .ogg, audio/mp3 → .mp3
  • Извлекать длительность из атрибутов
  • Сохранять во front-matter: duration: 45, size: 127359

🚀 Ближайшие шаги (эта неделя)

  • 1.1 DNS для c7e.ru настроен
  • 1.2 SSL-сертификат (Caddy)
  • 1.4 GitHub репозиторий
  • 1.5 README.md с ASCII-логотипом
  • 1.3 Лендинг (1 экран) на c7e.ru
  • 0.1 Начать Phase 0: парсинг Telegram

📝 История изменений

Дата Изменение
19 февраля 2026 Создан документ ROADMAP.md

Документ создан на основе диалога о проекте Telegram Archiver и его эволюции в Chronicle.