169 lines
5.7 KiB
Markdown
169 lines
5.7 KiB
Markdown
# Novela 2.0 - Technical Status (Develop)
|
|
|
|
## Scope
|
|
Dit document beschrijft de actuele technische status van de `develop` codebase.
|
|
Dit document is de primaire technische documentatie voor de huidige codebase.
|
|
|
|
## Architecture
|
|
- Stack: FastAPI, Jinja2 templates, plain JS, PostgreSQL 16, Docker.
|
|
- Startup lifecycle (`main.py`):
|
|
1. `init_pool()`
|
|
2. `run_migrations()`
|
|
3. `start_backup_scheduler()`
|
|
4. routers mounten
|
|
- Shutdown lifecycle:
|
|
1. `stop_backup_scheduler()`
|
|
2. `close_pool()`
|
|
- Source-of-truth regel: bestand op schijf leidend, database als index/cache.
|
|
|
|
## Router Status
|
|
|
|
### `routers/library.py`
|
|
- `GET /library`
|
|
- `GET /api/library`
|
|
- `POST /library/rescan`
|
|
- `POST /library/import` (EPUB/PDF/CBR/CBZ)
|
|
- `DELETE /library/file/{filename}`
|
|
- `GET /library/cover/{filename}`
|
|
- `GET /library/cover-cached/{filename}`
|
|
- `POST /library/cover/{filename}` (EPUB)
|
|
- `POST /library/want-to-read/{filename}`
|
|
- `POST /library/archive/{filename}`
|
|
- `POST /library/new/mark-reviewed` (bulk `needs_review=false`)
|
|
- `GET /home`
|
|
- `GET /api/home`
|
|
- `GET /stats`
|
|
- `GET /api/stats`
|
|
- `GET /library/list` (compat)
|
|
|
|
`GET /api/library` draait standaard in fast-path (DB-only, geen full disk rescan).
|
|
Voor geforceerde sync: `GET /api/library?rescan=true` of `POST /library/rescan`.
|
|
`include_file_info=true` is optioneel voor bestandsgrootte/mtime verrijking.
|
|
|
|
`/api/home` levert:
|
|
- `continue_reading`
|
|
- `shorts_unread`
|
|
- `novels_unread`
|
|
- `shorts_read`
|
|
- `novels_read`
|
|
|
|
`/api/stats` levert naast totals ook chart- en history-data voor `stats.html`:
|
|
- `reads_by_month`, `reads_by_dow`, `reads_by_hour`
|
|
- `genre_counts`, `publisher_counts`, `fav_genre`, `fav_publisher`
|
|
- `top_books`, `history`
|
|
|
|
Home-secties filteren series uit met:
|
|
- `COALESCE(series, '') = ''`
|
|
- `filename NOT LIKE '%/Series/%'`
|
|
|
|
Read-secties op Home zijn gesorteerd op oudste eerst:
|
|
- `shorts_read`: `ORDER BY MAX(read_at) ASC`
|
|
- `novels_read`: `ORDER BY MAX(read_at) ASC`
|
|
|
|
### `routers/reader.py`
|
|
- Epub serving/chapters/images
|
|
- Reader pagina + book detail
|
|
- Metadata patch (`PATCH /library/book/{filename}`)
|
|
- Progress read/write/delete
|
|
- Mark-as-read
|
|
- PDF render endpoint
|
|
- CBR/CBZ page endpoint
|
|
- Genres endpoint
|
|
|
|
### `routers/editor.py`
|
|
- Editor pagina
|
|
- Chapter get/save
|
|
- Chapter add
|
|
- Chapter delete
|
|
|
|
### `routers/grabber.py`
|
|
- Grabber pagina + convert/debug flows
|
|
- SSE events
|
|
- Credentials beheer voor scraper-sites
|
|
- Credentials manager UI (`/credentials-manager`)
|
|
|
|
### `routers/backup.py`
|
|
- `GET /backup`
|
|
- `GET/POST/DELETE /api/backup/credentials`
|
|
- `GET /api/backup/health`
|
|
- `GET /api/backup/status`
|
|
- `GET /api/backup/history`
|
|
- `POST /api/backup/run`
|
|
|
|
## Backup & Security
|
|
- Dropbox token encrypted-at-rest in `credentials` (`site='dropbox'`).
|
|
- Dropbox backup root encrypted opgeslagen in `credentials` (`site='dropbox_backup_root'`).
|
|
- Retentie (`snapshots to keep`) encrypted opgeslagen in `credentials` (`site='dropbox_backup_retention'`).
|
|
- Backup schedule (`enabled` + `interval_hours`) encrypted opgeslagen in `credentials` (`site='dropbox_backup_schedule'`).
|
|
- Encryptie via `NOVELA_MASTER_KEY` (Fernet).
|
|
|
|
Implementatie:
|
|
- Versie-gebaseerde backups met deduplicatie:
|
|
- bestandsobjecten in Dropbox: `library_objects/{sha256_prefix}/{sha256}`
|
|
- snapshots in Dropbox: `library_snapshots/snapshot-YYYYMMDD-HHMMSS.json`
|
|
- Elke run maakt een nieuwe snapshot (versie) en uploadt alleen ontbrekende objecten.
|
|
- Retentie verwijdert oude snapshots boven de ingestelde limiet.
|
|
- Orphan object-prune verwijdert objecten die niet meer door retained snapshots worden gerefereerd.
|
|
- Lokale manifestcache (`config/backup_manifest.json`) versnelt changeddetectie.
|
|
- Database backup via `pg_dump` naar Dropbox `postgres/`.
|
|
- `POST /api/backup/run` start altijd als background task en geeft direct status terug.
|
|
- Scheduler draait in achtergrond (`start_backup_scheduler`) en triggert op interval als backup aanstaat.
|
|
- Concurrentierestrictie: slechts 1 backup tegelijk.
|
|
- Bij container restart/crash worden stale `running` logs automatisch gemarkeerd als interrupted/error.
|
|
|
|
## Environment
|
|
`stack/novela.env` bevat nu minimaal:
|
|
- `POSTGRES_DB`
|
|
- `POSTGRES_USER`
|
|
- `POSTGRES_PASSWORD`
|
|
- `NOVELA_MASTER_KEY`
|
|
- `CONFIG_DIR`
|
|
|
|
Dropbox settings verlopen via webinterface op `/backup`.
|
|
|
|
## UI Notes
|
|
- Library import accepteert: EPUB/PDF/CBR/CBZ.
|
|
- Home heeft dezelfde importmogelijkheden.
|
|
- Home heeft zoekfunctionaliteit.
|
|
- Home header/dropzone uitlijning gelijkgetrokken met Library (zoek rechtsboven, dropzone eronder).
|
|
- `New` view ondersteunt `Grid` en `List` mode.
|
|
- Bulk selectie + `Remove from New` werkt alleen in `List` mode.
|
|
- `List` mode heeft kolomfilter (aan/uit) met kolommen:
|
|
- Publisher
|
|
- Author
|
|
- Series
|
|
- Volume
|
|
- Title
|
|
- Has cover
|
|
- Updated
|
|
- Genres
|
|
- Sub-genres
|
|
- Tags
|
|
- Status
|
|
- `List` mode ondersteunt multi-select met `Shift+klik` range-select op checkboxes.
|
|
- `Grid` mode toont geen selectie-checkboxes of bulkacties.
|
|
- Backup pagina ondersteunt:
|
|
- handmatige run en dry-run
|
|
- instellingen voor Dropbox root
|
|
- retentie-aantal snapshots
|
|
- geplande backup (aan/uit + interval in uren)
|
|
- status + history overzicht
|
|
|
|
## Known Conventions
|
|
- Verwijderen boek: bestand verwijderen, lege mappen prunen, daarna `DELETE FROM library` (cascade op child-tabellen).
|
|
- Cover strategie:
|
|
- EPUB: cover uit bestand + cache
|
|
- PDF/CBR: thumbnail via cover cache
|
|
|
|
|
|
## Performance Notes
|
|
- Library-load geoptimaliseerd voor grote datasets:
|
|
- `list_library_json()` gebruikt pre-aggregatie voor `reading_sessions`.
|
|
- `has_cached_cover` komt direct uit SQL join i.p.v. losse volledige cache-fetch.
|
|
- Nieuwe migrations-indexen:
|
|
- `idx_library_sort_coalesce`
|
|
- `idx_library_needs_review`
|
|
- `idx_library_archived`
|
|
- `idx_reading_sessions_filename_readat`
|
|
- `idx_book_tags_filename_tag`
|