Skip to content

Project layout

app/
├── main.py         FastAPI routes, session middleware, CSRF check
├── auth.py         accounts, identities, passwords, sessions, invites
├── oauth.py        OAuth2/OIDC client and the provider registry
├── mailer.py       optional SMTP, used only for reset links
├── backup.py       verified database snapshots and rotation
├── integrity.py    full-file hashing and drift detection
├── media.py        every image URL, and the page cache behind the reader
├── convert.py      ComicInfo write-back and container conversion
├── cli.py          command-line account recovery
├── config.py       environment configuration
├── db.py           SQLite schema and migrations
├── archives.py     CBZ/CBR/CB7/CBT/PDF/EPUB reading
├── metadata.py     ComicInfo.xml and filename parsing
├── covers.py       cover extraction and thumbnails
├── scanner.py      filesystem walking and per-user browse permissions
├── importer.py     import pipeline and background job runner
├── comicvine.py    Comic Vine client, cache and matching
├── matching.py     source-independent series and issue matching rules
├── providers/      metadata sources behind one interface (Comic Vine, Metron)
├── skins.py        colour palettes: validation, contrast checking, storage
├── diskusage.py    free space per device, for import/upload locations
├── library.py      search, filters, facets, edits — all user-scoped
├── templates/      Jinja2 pages
└── static/         one stylesheet, one script

CLAUDE.md           decisions and their reasoning, and what is next
docs/
├── architecture.md what it would take to scale this, and what to decide now
└── skins.md        the skin authoring contract

tests/
├── run.py          runs every suite
├── _support.py     shared bootstrap and assertions
├── make_samples.py generates the sample collection
└── schema_v1.sql   the pre-multi-user schema, for the migration test

vendor/             comiccore/ebookcore, vendored -- see vendor/README.md