# π ΠΠ°Π΄Π°ΡΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°: study.qpid.pro (Backlog & Execution Queue) Π‘ΠΏΠΈΡΠΎΠΊ Π·Π°Π΄Π°Ρ Π΄Π»Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΎΠ² **Ponytail** (ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½Π°Ρ Π½Π°Π΄ΡΠΆΠ½ΠΎΡΡΡ, Π½Π°ΡΠΈΠ²Π½ΡΠ΅ ΡΡΠ΅Π΄ΡΡΠ²Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ, zero-dependency, Π²ΡΡΠΎΠΊΠ°Ρ ΡΠΊΠΎΡΠΎΡΡΡ). --- ## π ΠΡΠ΅ΡΠ΅Π΄Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ (ΠΠΎΡΠ°Π³ΠΎΠ²ΡΠΉ ΠΏΠ»Π°Π½) ### 1. π ΠΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΡΠΉ ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³ Markdown (.md) Π² ΡΠΈΡΠ°Π»ΠΊΠ΅ - [x] **ΠΠ»ΠΎΠΊΠΈ ΠΊΠΎΠ΄Π° (Fenced Code Blocks ```` ```language ````)**: - ΠΡΠ΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΎΠ² ΠΊΠΎΠ΄Π° Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ `
`.
- ΠΠΎΠ½ΠΎΡΠΈΡΠΈΠ½Π½ΡΠΉ ΡΡΠΈΡΡ (`JetBrains Mono`, `Consolas`), ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΎΡΡΡΡΠΏΠΎΠ² ΠΈ ΡΠ°Π±ΡΠ»ΡΡΠΈΠΈ (`white-space: pre`).
- Π’ΡΠΌΠ½Π°Ρ ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠ°, Π³ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»ΡΠ½ΡΠΉ ΡΠΊΡΠΎΠ»Π» ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ, ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΡΠ°ΡΠ½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ (`text-indent: 0`).
- ΠΠ½ΠΎΠΏΠΊΠ° Β«ΠΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠΎΠ΄Β» Π² ΡΠ°ΠΏΠΊΠ΅ Π±Π»ΠΎΠΊΠ°.
- ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΡ
ΡΠ»ΠΎΠ²Π°ΡΠ½ΡΡ
ΡΠΏΠ°Π½ΠΎΠ² `` Π΄Π»Ρ ΠΊΠΎΠ΄Π°, ΡΡΠΎΠ±Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ Π½Π΅ Π»ΠΎΠΌΠ°Π» ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅.
- [x] **ΠΠ½Π»Π°ΠΉΠ½-ΠΊΠΎΠ΄ (`` `variable` ``)**:
- ΠΠ±ΠΎΡΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ Π² Π½Π°ΡΠΈΠ²Π½ΡΠΉ ΡΠ΅Π³ `` Ρ Π±Π΅ΠΉΠ΄ΠΆΠΈΠΊ-ΡΡΠΈΠ»Π΅ΠΌ.
- [x] **Π‘ΠΏΠΈΡΠΊΠΈ ΠΈ ΡΠΈΡΠ°ΡΡ**:
- ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ°ΡΠΊΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
(`- `, `* `) ΠΈ Π½ΡΠΌΠ΅ΡΠΎΠ²Π°Π½Π½ΡΡ
(`1. `) ΡΠΏΠΈΡΠΊΠΎΠ² Π² `- ` / `
- `.
- ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΈΡΠ°Ρ (`> `) Π² `
` Ρ Π°ΠΊΡΠ΅Π½ΡΠ½ΠΎΠΉ Π»Π΅Π²ΠΎΠΉ Π³ΡΠ°Π½ΠΈΡΠ΅ΠΉ.
- **Π‘Π»ΠΎΠ²Π° Π²Π½ΡΡΡΠΈ ΡΠΏΠΈΡΠΊΠΎΠ² ΠΈ ΡΠΈΡΠ°Ρ ΠΎΡΡΠ°ΡΡΡΡ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ** (ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠΉ ΠΊΠ»ΠΈΠΊ-ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ!).
- [x] **ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Markdown (`##`, `###`)**:
- ΠΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ Π² ``, `` Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ ΡΡΡΡΡ
ΡΠ΅ΡΡΡΠΎΠΊ `#`.
- [x] **Π’Π°Π±Π»ΠΈΡΡ Markdown (`| col | col |`)**:
- ΠΠ΄Π°ΠΏΡΠΈΠ²Π½ΡΠ΅ ΡΠ°Π±Π»ΠΈΡΡ Ρ ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ, ΡΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ``, Π·Π΅Π±ΡΠ°-ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΡΡΡΠΎΠΊ ΠΈ Π³ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»ΡΠ½ΡΠΌ ΡΠΊΡΠΎΠ»Π»ΠΎΠΌ Π½Π° ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΡΡ
.
- ΠΠ°ΠΆΠ΄Π°Ρ ΡΡΠ΅ΠΉΠΊΠ° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠ΅ ΡΠ»ΠΎΠ²Π° Π΄Π»Ρ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ ΠΈ ΠΈΠ½Π»Π°ΠΉΠ½-ΠΊΠΎΠ΄.
- [x] **HTML-Π±Π»ΠΎΠΊΠΈ ΠΈ ΡΠ΅Π³ΠΈ Π² Markdown (``, `
`, ``, ``, ``, `
`)**:
- ΠΠ°ΡΠΈΠ²Π½ΡΠΉ ΠΏΠ°ΡΡΠΈΠ½Π³ ΡΠ΅ΡΠ΅Π· Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ `DOMParser` Π±Π΅Π· Π²Π½Π΅ΡΠ½ΠΈΡ
Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ.
- Π£ΡΡΡΠ°Π½Π΅Π½Π° ΡΡΠ΅ΡΠΊΠ° ΡΡΡΡΡ
ΡΠ΅Π³ΠΎΠ² (``, ``, ``) Π² ΡΠ»ΠΎΠ²Π°ΡΠ½ΡΠ΅ ΡΠ»ΠΎΠ²Π°.
- [x] **Π‘ΡΡΠ»ΠΊΠΈ ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (`[text](url)`, ``, `
`)**:
- ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° Π±Π΅ΠΉΠ΄ΠΆΠ΅ΠΉ shields.io, ΡΡΠ΅Π½Π΄-Π³ΡΠ°ΡΠΈΠΊΠΎΠ² ΠΈ Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ.
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠΊΡΡΡΠΈΠ΅ Π±ΠΈΡΡΡ
/ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΡ
Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ
ΠΏΡΡΠ΅ΠΉ (`assets/...`) ΡΠ΅ΡΠ΅Π· ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ `onerror`.
- [x] **Π’ΠΎΡΠ½ΠΎΠ΅ ΠΏΠΎΠ·ΠΈΡΠΈΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠΊΠ½Π° ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄Π° Ρ ΠΊΡΡΡΠΎΡΠ°/ΡΠ»ΠΎΠ²Π° (Popup Positioning)**:
- ΠΡΠΏΡΠ°Π²Π»Π΅Π½ Π±Π°Π³ Π΄Π²ΠΎΠΉΠ½ΠΎΠ³ΠΎ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ: ΡΠ±ΡΠ°Π½ `window.scrollY` ΠΏΡΠΈ `position: fixed`.
- ΠΠΊΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΠ΅Π½ΠΎ Π² ΠΊΠΎΡΠ΅Π½Ρ `
` Π΄Π»Ρ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΏΠΎΠ·ΠΈΡΠΈΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
- ΠΠ»Π°Π²Π½ΠΎΠ΅ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΡΠΊΡΠΎΠ»Π»Π° ΡΠ΅ΡΠ΅Π· `requestAnimationFrame` Ρ Π°Π²ΡΠΎΠ·Π°ΠΊΡΡΡΠΈΠ΅ΠΌ ΠΏΡΠΈ ΡΡ
ΠΎΠ΄Π΅ ΡΠ»ΠΎΠ²Π° Π·Π° Π³ΡΠ°Π½ΠΈΡΡ ΡΠΊΡΠ°Π½Π° ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ Π»ΠΈΠΏΠΊΡΡ ΡΠ°ΠΏΠΊΡ.
- [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-table`, `.reader-heading`, `.reader-link`, `.reader-img`.
---
### 2. ποΈ Π‘ΠΆΠ°ΡΠΈΠ΅ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΡΠ°ΡΠΈΠΊΠ° (`GZipMiddleware`)
- [x] ΠΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡ `GZipMiddleware(minimum_size=1000)` Π² [`app/main.py`](file:///home/ai-projects/services/study.qpid.pro/app/main.py).
- [x] Π‘ΠΎΠΊΡΠ°ΡΠΈΡΡ ΠΎΠ±ΡΡΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ
ΡΠ°ΠΉΠ»ΠΎΠ² `app.js` (111.8 ΠΠ -> 21.5 ΠΠ), `index.html` (55.2 ΠΠ -> 10.3 ΠΠ) ΠΈ `style.css` (58.2 ΠΠ -> 9.4 ΠΠ) Π½Π° 81.7% (ΡΡΠΌΠΌΠ°ΡΠ½ΠΎ Ρ 225.2 ΠΠ Π΄ΠΎ 41.2 ΠΠ).
- [x] ΠΡΠΎΠ²Π΅ΡΠΈΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ `Content-Encoding: gzip` Π² ΠΎΡΠ²Π΅ΡΠ°Ρ
ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠ΅Π³ΡΠ΅ΡΡΠΈΠΎΠ½Π½ΡΠΉ ΡΠ΅ΡΡ Π² `tests/test_api.py`.
---
### 3. π‘οΈ ΠΠ΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡ ΡΠ»ΠΎΠ² ΠΈ Π·Π°ΡΠΈΡΠ° ΠΎΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ (Reader + API)
- [x] **ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΠΎΠ² Π½Π° Π±ΡΠΊΠ΅Π½Π΄Π΅ (`POST /api/cards`)**:
- ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠ»ΠΎΠ²Π° Π±Π΅Π· ΡΡΡΡΠ° ΡΠ΅Π³ΠΈΡΡΡΠ° `lower(trim(term))`.
- ΠΡΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΌ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½Π΅ ΡΠΎΠ·Π΄Π°ΡΡΡΡ Π΄ΡΠ±Π»ΠΈΠΊΠ°Ρ, Π° Π΄ΠΎΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ½ΠΎΠ΅ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΡΡΡΡ ΡΠ΅Π³ΠΈ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ `already_exists: True`.
- [x] **ΠΠ½Π΄ΠΈΠΊΠ°ΡΠΈΡ Π² ΡΠΈΡΠ°Π»ΠΊΠ΅ ΠΈ ΠΊΠ°ΡΡΠΎΡΠΊΠ΅ ΠΏΠΎΠΈΡΠΊΠ°**:
- Π ΡΠΈΡΠ°Π»ΠΊΠ΅ ΠΏΡΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π½Π° ΡΠ»ΠΎΠ²ΠΎ ΠΈ Π² ΠΊΠ°ΡΡΠΎΡΠΊΠ΅ ΠΏΠΎΠΈΡΠΊΠ° Π²ΡΠ²ΠΎΠ΄ΠΈΡΡΡ Π±Π΅ΠΉΠ΄ΠΆ `β Π Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅`.
- ΠΠ½ΠΎΠΏΠΊΠ° Β«+ Π ΡΠ»ΠΎΠ²Π°ΡΡΒ» Π·Π°ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π½Π° Π±Π΅ΠΉΠ΄ΠΆ `β Π‘Π»ΠΎΠ²ΠΎ ΡΠΆΠ΅ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅` Ρ ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΎΠΉ `+ ΠΠΎΠ±Π°Π²ΠΈΡΡ ΡΡΡ ΡΠΈΡΠ°ΡΡ ΠΊ ΠΊΠ°ΡΡΠΎΡΠΊΠ΅`.
- [x] **ΠΠ½Π΄Π΅ΠΊΡ ΡΠ΅Π»ΠΎΡΡΠ½ΠΎΡΡΠΈ Π² SQLite**:
- Π‘ΠΎΠ·Π΄Π°Π½ `UNIQUE INDEX idx_vocab_user_term_nocase ON vocabulary_cards(user_id, term COLLATE NOCASE);` Π³Π°ΡΠ°Π½ΡΠΈΡΡΡΡΠΈΠΉ ΠΎΡΡΡΡΡΡΠ²ΠΈΠ΅ Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΠΎΠ² Π½Π° ΡΡΠΎΠ²Π½Π΅ Π΄Π²ΠΈΠΆΠΊΠ° ΠΠ Π·Π° $O(\log N)$.
- [x] **Π‘Π»ΠΈΡΠ½ΠΈΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΡ
Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΠΎΠ² Π² Π±Π°Π·Π΅**:
- ΠΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½Ρ Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΡ `admired` (ID 5 ΠΈ ID 7) ΠΈ `suddenly`/`Suddenly` (ID 2 ΠΈ ID 9) Ρ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ½ΡΡ
ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΡΠ»ΠΈΡΠ½ΠΈΠ΅ΠΌ ΡΠ΅Π³ΠΎΠ² ΠΈ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ΅ΡΡΠ° SRS.
---
### 4. π ΠΡΠ» ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ 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 ΠΌΡ.
---
### 5. ποΈ Π’ΡΠ½ΠΈΠ½Π³ 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
```
- [ ] ΠΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ Zero-copy ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΡΠ°Π½ΠΈΡ ΠΠ ΡΠ΄ΡΠΎΠΌ Linux.
---
### 6. βοΈ ΠΠ΅-Π±Π»ΠΎΠ°ΡΠΈΠ½Π³ Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΏΠ°ΡΡΠ΅ΡΠΎΠ² (YAGNI)
- [ ] Π£Π΄Π°Π»ΠΈΡΡ Π»ΠΈΡΠ½ΠΈΠΉ ΡΠ΅ΡΠ΅Π²ΠΎΠΉ ΠΎΠΏΡΠΎΡ Datamuse (`fetch_datamuse`) β ΠΎΠ½ Π΄ΡΠ±Π»ΠΈΡΡΠ΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΈ ΠΏΠ΅ΡΠ΅Π³ΡΡΠΆΠ°Π΅Ρ ΠΎΡΠ²Π΅Ρ Π½Π΅ΡΠ΅Π»Π΅Π²Π°Π½ΡΠ½ΡΠΌΠΈ ΡΠΈΡΠΌΠ°ΠΌΠΈ.
- [ ] Π£ΠΏΡΠΎΡΡΠΈΡΡ Ρ
ΡΡΠΏΠΊΠΈΠΉ regex-ΠΏΠ°ΡΡΠΈΠ½Π³ ΡΠ°Π·ΠΌΠ΅ΡΠΊΠΈ Wikitext, ΠΎΠΏΠΈΡΠ°ΡΡΡ Π½Π° ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΡΠ΅ REST JSON ΡΠ½Π΄ΠΏΠΎΠΈΠ½ΡΡ.
---
### 7. π ΠΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΎΡΡΠ»Π°ΠΉΠ½-ΡΠ»ΠΎΠ²Π°ΡΡ (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).
---
### 8. π§© ΠΠΎΠ΄ΡΠ»ΡΠ½ΠΎΡΡΡ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π° Π½Π° Π½Π°ΡΠΈΠ²Π½ΡΡ
ES-ΠΌΠΎΠ΄ΡΠ»ΡΡ
(Π±Π΅Π· Webpack/Vite)
- [ ] ΠΠ΅ΡΠ΅Π²Π΅ΡΡΠΈ [`app/static/js/app.js`](file:///home/ai-projects/services/study.qpid.pro/app/static/js/app.js) Π½Π° Π½Π°ΡΠΈΠ²Π½ΡΠΉ Π±ΡΠ°ΡΠ·Π΅ΡΠ½ΡΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ `