10 KiB
10 KiB
📋 Задачи проекта: study.qpid.pro (Backlog & Execution Queue)
Список задач для последовательной реализации в рамках принципов Ponytail (максимальная надёжность, нативные средства платформы, zero-dependency, высокая скорость).
🚀 Очередь реализации (Пошаговый план)
1. 📑 Полноценный рендеринг Markdown (.md) в читалке
- Блоки кода (Fenced Code Blocks
```language):- Выделение блоков кода в контейнер
<pre><code class="language-...">. - Моноширинный шрифт (
JetBrains Mono,Consolas), сохранение отступов и табуляции (white-space: pre). - Тёмная подложка, горизонтальный скролл при переполнении, отключение красной строки (
text-indent: 0). - Кнопка «Копировать код» в шапке блока.
- Отключение создания интерактивных словарных спанов
<span class="reader-word">для кода, чтобы синтаксис не ломал форматирование.
- Выделение блоков кода в контейнер
- Инлайн-код (
`variable`):- Оборачивание в нативный тег
<code class="reader-inline-code">с бейджик-стилем.
- Оборачивание в нативный тег
- Списки и цитаты:
- Преобразование маркированных (
-,*) и нумерованных (1.) списков в<ul><li>/<ol><li>. - Преобразование цитат (
>) в<blockquote>с акцентной левой границей. - Слова внутри списков и цитат остаются кликабельными (интерактивный клик-перевод работает!).
- Преобразование маркированных (
- Заголовки Markdown (
##,###):- Конвертация в
<h3>,<h4>с удалением сырых решёток#.
- Конвертация в
- Точное позиционирование окна перевода у курсора/слова (Popup Positioning):
- Исправить баг двойного смещения координат: у элемента
.reader-word-popupв CSS заданposition: fixed, а в JS кrect.bottomошибочно прибавлялсяwindow.scrollY, из-за чего окно улетало далеко вниз при любом скролле страницы. - Позиционировать окно точно под кликнутым словом (
rect.bottom + 6) либо над ним (rect.top - popupHeight - 6), если снизу недостаточно места до края экрана. - Центрировать окно относительно слова с ограничением по границам вьюпорта (отступы минимум 12px от краёв экрана).
- Исправить баг двойного смещения координат: у элемента
- Стилизация в CSS (
app/static/css/style.css):- Добавить стили для
.reader-content-body pre,code,blockquote,ul,ol.
- Добавить стили для
2. 🗜️ Сжатие статического трафика (GZipMiddleware)
- Подключить
GZipMiddleware(minimum_size=1000)вapp/main.py. - Сократить объём передаваемых файлов
app.js(95 КБ),index.html(56 КБ) иstyle.css(25 КБ) на 70–75% (суммарно со 176 КБ до ~40 КБ). - Проверить заголовки
Content-Encoding: gzipв ответах.
3. 🔌 Пул соединений HTTP (httpx.AsyncClient с Keep-Alive)
- В
app/dictionary.pyсоздать синглтон-клиентget_http_client()с пулом соединений:limits = httpx.Limits(max_keepalive_connections=10, max_connections=20) - Заменить вызовы
async with httpx.AsyncClient()в парсерах на переиспользуемый клиент. - Устранить 5 повторных TCP/TLS хэндшейков на каждое слово, сократив пинг внешних запросов на 300–600 мс.
4. 🗄️ Тюнинг SQLite PRAGMA и составных индексов
- В
app/database.py:- Вынести
PRAGMA journal_mode=WAL;вinit_db()(убрать избыточный вызов при каждом запросе). - Включить параметры производительности памяти Linux:
conn.execute("PRAGMA synchronous = NORMAL;") conn.execute("PRAGMA mmap_size = 268435456;") # 256MB mmap conn.execute("PRAGMA cache_size = -32000;") # 32MB cache - Добавить составной индекс:
CREATE INDEX IF NOT EXISTS idx_vocab_user_term_nocase ON vocabulary_cards(user_id, term COLLATE NOCASE);
- Вынести
- Обеспечить Zero-copy чтение страниц БД ядром Linux и мгновенный поиск дубликатов по пользователю за
O(\log N).
5. ✂️ Де-блоатинг внешних парсеров (YAGNI)
- Удалить лишний сетевой опрос Datamuse (
fetch_datamuse) — он дублирует определения и перегружает ответ нерелевантными рифмами. - Упростить хрупкий regex-парсинг разметки Wikitext, опираясь на стабильные REST JSON эндпоинты.
6. 📚 Локальный оффлайн-словарь (99%+ покрытия со словоформами, SQLite 10–20 МБ)
- Создать в SQLite таблицу:
CREATE TABLE IF NOT EXISTS offline_dictionary ( term TEXT PRIMARY KEY COLLATE NOCASE, translation TEXT NOT NULL, phonetic TEXT DEFAULT '', pos TEXT DEFAULT '' ); CREATE INDEX IF NOT EXISTS idx_offline_dict_term ON offline_dictionary(term COLLATE NOCASE); - Сформировать и интегрировать базу на 120 000–180 000 статей (~10–20 МБ в SQLite, сжатый архив ~3.5–5 МБ):
- Включить все словоформы (past tense, irregular verbs, plurals, participles).
- Включить фразовые глаголы, современный сленг и IT/Tech терминологию.
- Использовать архитектуру Zero Daemon: нативный SQLite с
PRAGMA mmap_size(без отдельного контейнера Redis, чтение < 0.1 мс прямо из оперативной памяти процесса). - Реализовать логику словарного поиска:
- Сначала запрос в
offline_dictionary\rightarrowмгновенный ответ за 0.1 мс. - Только при отсутствии слова в базе
\rightarrowfallback-запрос во внешнюю сеть.
- Сначала запрос в
- Полностью исключить исчерпание лимитов внешних API (MyMemory 100 req/day).
7. 🧩 Модульность фронтенда на нативных ES-модулях (без Webpack/Vite)
- Перевести
app/static/js/app.jsна нативный браузерный синтаксис<script type="module">. - Выделить модули с нативным
import/export:modules/reader.js— читалку, блок-парсер и навигацию по главам.modules/srs.js— алгоритм SM-2, флэшкарты и квиз.modules/api.js— клиентские сетевые вызовы.modules/ui.js— тосты, модальные окна, темы оформления.
- Сохранить полное отсутствие внешних сборщиков (0 npm-пакетов, чистая платформа).
8. 🌐 Быстрый захват из браузера (Bookmarklet)
- Создать JavaScript-букмарклет для добавления слова/фразы из любого окна браузера в личный словарь
study.qpid.pro.
⏳ Coming Soon
- Нативная автономная озвучка (HTML5 Web Speech API /
speechSynthesis):- Использовать встроенный в браузер синтезатор речи
window.speechSynthesis(en-US, en-GB). - 0 сетевых запросов к серверу, 100% оффлайн-работа.
- Поддержка озвучивания отдельных слов, фраз, идиом и предложений-контекстов читалки.
- Использовать встроенный в браузер синтезатор речи
- Возврат режима «Диктант» в SRS:
- Возобновление работы аудиотренажёра на базе нативного браузерного синтезатора речи без зависимости от внешних аудиофайлов.
🛠️ Правила и соглашения проекта (Ponytail Rules)
- Stdlib & Native First: стандартная библиотека языка и возможности платформы (браузера, SQLite, Linux) всегда приоритетнее внешних библиотек и микросервисов.
- Меньше кода — меньше багов: удаление кода и упрощение структуры всегда лучше усложнения.
- Безопасность: все мутации данных изолированы по
user_id, пароли защищены PBKDF2 с уникальной солью. - Тестирование: после каждого изменения запуск
pytest tests/test_api.py -v(100% тестов должны быть зелеными).