5.7 KiB
5.7 KiB
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):init_pool()run_migrations()start_backup_scheduler()- routers mounten
- Shutdown lifecycle:
stop_backup_scheduler()close_pool()
- Source-of-truth regel: bestand op schijf leidend, database als index/cache.
Router Status
routers/library.py
GET /libraryGET /api/libraryPOST /library/rescanPOST /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(bulkneeds_review=false)GET /homeGET /api/homeGET /statsGET /api/statsGET /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_readingshorts_unreadnovels_unreadshorts_readnovels_read
/api/stats levert naast totals ook chart- en history-data voor stats.html:
reads_by_month,reads_by_dow,reads_by_hourgenre_counts,publisher_counts,fav_genre,fav_publishertop_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) ASCnovels_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 /backupGET/POST/DELETE /api/backup/credentialsGET /api/backup/healthGET /api/backup/statusGET /api/backup/historyPOST /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 incredentials(site='dropbox_backup_retention'). - Backup schedule (
enabled+interval_hours) encrypted opgeslagen incredentials(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
- bestandsobjecten in Dropbox:
- 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_dumpnaar Dropboxpostgres/. POST /api/backup/runstart 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
runninglogs automatisch gemarkeerd als interrupted/error.
Environment
stack/novela.env bevat nu minimaal:
POSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDNOVELA_MASTER_KEYCONFIG_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).
Newview ondersteuntGridenListmode.- Bulk selectie +
Remove from Newwerkt alleen inListmode. Listmode heeft kolomfilter (aan/uit) met kolommen:- Publisher
- Author
- Series
- Volume
- Title
- Has cover
- Updated
- Genres
- Sub-genres
- Tags
- Status
Listmode ondersteunt multi-select metShift+klikrange-select op checkboxes.Gridmode 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 voorreading_sessions.has_cached_coverkomt direct uit SQL join i.p.v. losse volledige cache-fetch.
- Nieuwe migrations-indexen:
idx_library_sort_coalesceidx_library_needs_reviewidx_library_archivedidx_reading_sessions_filename_readatidx_book_tags_filename_tag