Files
notes-qpid-pro/TODO.md
T

128 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# 📋 Задачи проекта: study.qpid.pro (Backlog & Execution Queue)
Список задач для последовательной реализации в рамках принципов **Ponytail** (максимальная надёжность, нативные средства платформы, zero-dependency, высокая скорость).
---
## 🚀 Очередь реализации (Пошаговый план)
### 1. 📑 Полноценный рендеринг Markdown (.md) в читалке
- [x] **Блоки кода (Fenced Code Blocks ```` ```language ````)**:
- Выделение блоков кода в контейнер `<pre><code class="language-...">`.
- Моноширинный шрифт (`JetBrains Mono`, `Consolas`), сохранение отступов и табуляции (`white-space: pre`).
- Тёмная подложка, горизонтальный скролл при переполнении, отключение красной строки (`text-indent: 0`).
- Кнопка «Копировать код» в шапке блока.
- Отключение создания интерактивных словарных спанов `<span class="reader-word">` для кода, чтобы синтаксис не ломал форматирование.
- [x] **Инлайн-код (`` `variable` ``)**:
- Оборачивание в нативный тег `<code class="reader-inline-code">` с бейджик-стилем.
- [x] **Списки и цитаты**:
- Преобразование маркированных (`- `, `* `) и нумерованных (`1. `) списков в `<ul><li>` / `<ol><li>`.
- Преобразование цитат (`> `) в `<blockquote>` с акцентной левой границей.
- **Слова внутри списков и цитат остаются кликабельными** (интерактивный клик-перевод работает!).
- [x] **Заголовки Markdown (`##`, `###`)**:
- Конвертация в `<h3>`, `<h4>` с удалением сырых решёток `#`.
- [x] **Точное позиционирование окна перевода у курсора/слова (Popup Positioning)**:
- Исправлен баг двойного смещения координат: убран `window.scrollY` при `position: fixed`.
- Окно позиционируется точно под кликнутым словом (`rect.bottom + 8`) либо над ним (`rect.top - popupHeight - 8`), если снизу недостаточно места.
- Окно центрируется относительно кликнутого слова с проверкой границ вьюпорта (отступы минимум 12px от краёв).
- [x] **Стилизация в CSS ([`app/static/css/style.css`](file:///home/ai-projects/services/study.qpid.pro/app/static/css/style.css))**:
- Добавлены стили для `.reader-content-body pre`, `code`, `blockquote`, `ul`, `ol`, `.reader-code-block`, `.reader-inline-code`.
---
### 2. 🗜️ Сжатие статического трафика (`GZipMiddleware`)
- [ ] Подключить `GZipMiddleware(minimum_size=1000)` в [`app/main.py`](file:///home/ai-projects/services/study.qpid.pro/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`](file:///home/ai-projects/services/study.qpid.pro/app/dictionary.py) создать синглтон-клиент `get_http_client()` с пулом соединений:
```python
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`](file:///home/ai-projects/services/study.qpid.pro/app/database.py):
- Вынести `PRAGMA journal_mode=WAL;` в `init_db()` (убрать избыточный вызов при каждом запросе).
- Включить параметры производительности памяти Linux:
```python
conn.execute("PRAGMA synchronous = NORMAL;")
conn.execute("PRAGMA mmap_size = 268435456;") # 256MB mmap
conn.execute("PRAGMA cache_size = -32000;") # 32MB cache
```
- Добавить составной индекс:
```sql
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 таблицу:
```sql
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 мс прямо из оперативной памяти процесса).
- [ ] Реализовать логику словарного поиска:
1. Сначала запрос в `offline_dictionary` $\rightarrow$ мгновенный ответ за 0.1 мс.
2. Только при отсутствии слова в базе $\rightarrow$ fallback-запрос во внешнюю сеть.
- [ ] Полностью исключить исчерпание лимитов внешних API (MyMemory 100 req/day).
---
### 7. 🧩 Модульность фронтенда на нативных ES-модулях (без Webpack/Vite)
- [ ] Перевести [`app/static/js/app.js`](file:///home/ai-projects/services/study.qpid.pro/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`](https://study.qpid.pro).
---
## ⏳ Coming Soon
- [ ] **Нативная автономная озвучка (HTML5 Web Speech API / `speechSynthesis`)**:
- Использовать встроенный в браузер синтезатор речи `window.speechSynthesis` (en-US, en-GB).
- 0 сетевых запросов к серверу, 100% оффлайн-работа.
- Поддержка озвучивания отдельных слов, фраз, идиом и предложений-контекстов читалки.
- [ ] **Возврат режима «Диктант» в SRS**:
- Возобновление работы аудиотренажёра на базе нативного браузерного синтезатора речи без зависимости от внешних аудиофайлов.
---
## 🛠️ Правила и соглашения проекта (Ponytail Rules)
1. **Stdlib & Native First**: стандартная библиотека языка и возможности платформы (браузера, SQLite, Linux) всегда приоритетнее внешних библиотек и микросервисов.
2. **Меньше кода — меньше багов**: удаление кода и упрощение структуры всегда лучше усложнения.
3. **Безопасность**: все мутации данных изолированы по `user_id`, пароли защищены PBKDF2 с уникальной солью.
4. **Тестирование**: после каждого изменения запуск `pytest tests/test_api.py -v` (100% тестов должны быть зелеными).