# Develop Changelog
This file tracks changes on the `develop` line.
`changelog.md` can later be used for release summaries.
## 2026-03-22
- Added blueprint/technical documentation structure in `docs/`.
- Completed router split and bootstrap structure (`main.py`, routers, migrations, DB pool).
- Expanded media support to EPUB/PDF/CBR/CBZ in import and scan flows.
- Expanded Home UI with:
- import dropzone for EPUB/PDF/CBR/CBZ
- search functionality
- alignment matching Library (search top-right, dropzone below)
- Updated Library import texts and drag/drop filtering for multi-format support.
- Expanded Library `New` view with:
- `Grid`/`List` toggle
- column visibility filter in `List`
- multi-select + bulk `Remove from New`
- selection only in `List` mode
- `Shift+click` range selection on checkboxes
- Added route: `POST /library/new/mark-reviewed` (bulk set `needs_review=false`).
- Improved library performance:
- `/api/library` fast-path (no full rescan on every page load)
- optional `rescan=true` / `include_file_info=true`
- SQL optimizations in `list_library_json()`
- additional DB indexes for scale
- Restored `/api/home` full dataset output:
- `continue_reading`
- `shorts_unread`
- `novels_unread`
- `shorts_read`
- `novels_read`
- Explicitly filtered series books out of Home sections.
- Corrected Home read ordering: `shorts_read` and `novels_read` now show oldest first (`ORDER BY MAX(read_at) ASC`).
- Restored Statistics page by returning the full `/api/stats` payload required for charts, favorites, top books, and reading history.
- Improved backup implementation:
- Dropbox token stored encrypted in DB
- Dropbox backup root configurable via web UI and stored encrypted in DB
- versioned snapshots + object-store deduplication in Dropbox (`library_snapshots` / `library_objects`)
- configurable snapshot retention (`snapshots to keep`) via backup settings
- object pruning based on retained snapshots
- scheduled backup (enable + interval in hours)
- backup runs as a background process, so page navigation does not block execution
- stale running state recovery after restart/crash (old running logs marked interrupted/error)
- dry-run support in the new flow
- Updated Docker image with `postgresql-client` for `pg_dump`.
- Multiple test builds pushed to `gitea.oskamp.info/ivooskamp/novela:dev`.
## 2026-03-25 (3)
- Fixed CBZ extension in import: `common.make_rel_path` always generated `.cbr` for CBZ files; now accepts `ext` parameter; `library.py` passes actual suffix so CBZ files land at `comics/{author}/{title}.cbz`
- Added missing `GET /download/{filename}` endpoint (referenced in book.html but was 404)
- TECHNICAL.md fully rewritten: added File Storage Paths section, complete endpoint lists for all routers including settings.py, corrected path documentation
## 2026-03-25 (2)
- Fixed PDF metadata editing (PATCH /library/book):
- `_sync_epub_metadata` is now only called for `.epub` files; PDFs update DB only
- `_make_rel_path` now includes the format prefix matching import: EPUB → `epub/{publisher}/{author}/…`, PDF → `pdf/{author}/{title}.pdf`, CBR/CBZ → `comics/{author}/{title}{ext}`; previously files were moved outside their format directory on metadata save
- Fixed PDF reader (infinite loading screen):
- `reader_page` now passes `format` (epub/pdf/cbr/cbz) to `reader.html`
- Added `GET /api/pdf/info/{filename}` endpoint returning `{"page_count": N}`
- `reader.html` branches on `FORMAT`: PDFs render page images from `/library/pdf/{filename}?page=N`, EPUB flow unchanged
- PDF progress tracked per page; keyboard and button navigation work identically to EPUB
- `Edit EPUB` button in Book Detail hidden for non-EPUB files
## 2026-03-23
- Added `All books` Grid/List toggle in Library:
- same columns as `New` view (Publisher, Author, Series, Volume, Title, Has cover, Updated, Genres, Sub-genres, Tags, Status)
- column visibility filter in `List` mode
- no selection checkboxes or bulk actions
- view mode and column visibility persisted separately in `localStorage` (`novela.all.viewMode`, `novela.all.visibleColumns`)
- Added 1–5 star rating for books:
- stored in the database (`rating SMALLINT DEFAULT 0`)
- written to EPUB OPF as `` on rating change
- written to CBZ `ComicInfo.xml` as `N` on rating change
- CBR and PDF are DB-only (file format constraints)
- rating is recovered from file metadata during rescan/DB rebuild (`upsert_book` preserves file rating over default 0)
- stars displayed under the cover (outside `.book-info`) in all grid views (Library, Home)
- stars in grid cards are display-only (no click) to prevent accidental taps while scrolling
- stars in Book Detail are interactive (larger, 1.1rem), clicking same star removes rating
- star color: amber (`#c8a03a`) for filled, `rgba(200, 160, 58, 0.25)` for unfilled — consistent across Library, Home, and Book Detail
- Added text colour setting to reader hamburger menu:
- 5 warm-tone presets from bright (`#e8e2d9`) to dim (`#938d86`)
- active preset shown with accent-coloured ring
- choice persisted in `localStorage` (`reader-text-colour`) and restored on next open
- Increased spacing between hamburger button and back link in reader header (`margin-left: 1rem`) to prevent accidental taps
- Removed `Cover Missing` auto-tag:
- tag is no longer added on import, rescan, or grabber download
- `ensure_cover_missing_tag()` removed from `common.py`, `library.py`, and `grabber.py`
- startup migration removes all existing `Cover Missing` tags from the database
- Fixed Tags/Genres/Sub-Genres not saving in book edit panel on desktop:
- `,` (comma) now acts as a confirmation key alongside Enter in `PillInput`
- `flush()` added to `PillInput`: any text still in the input field is auto-confirmed when Save is clicked
- Fixed tag/genre search and tag-pill navigation being broken:
- `renderGenreView` was filtering on `b.genres` (non-existent field); now uses `bookGenres()`, `bookSubgenres()`, `bookPlainTags()`
- `renderSearchResults` had the same bug; search now covers title, author, genres, sub-genres, and tags