- TypeScript 92.1%
- JavaScript 7.7%
- CSS 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
- Implemented GET and PUT routes for local submission settings. - Created a settings page for managing submission defaults including language and release groups. - Added series creation suggestions component to handle normalized names for series. - Introduced hooks for managing series creation workflow and repairing Windows short filenames. - Developed utilities for handling dropped files and normalizing scan edition labels. - Enhanced local submission settings management with validation and default values. |
||
| .github | ||
| app | ||
| components | ||
| data | ||
| docs | ||
| lib | ||
| public | ||
| scripts | ||
| tests/e2e | ||
| types | ||
| .env.example | ||
| .gitignore | ||
| eslint.config.mjs | ||
| export_output.json | ||
| LICENSE | ||
| next.config.ts | ||
| NOTICE | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| postcss.config.mjs | ||
| proxy.ts | ||
| README.md | ||
| tsconfig.json | ||
DigitalBookDB
DigitalBookDB is a fully local Next.js application for managing manga, manwha,
light-novel, submission, and series metadata. It stores everything in the
project-local SQLite database at data/digitalbookdb.sqlite.
No external database, server account, login, password, or network service is
required. There is no session provider, role model, or synthetic signed-in
account. Writes use the stable audit actor ID local only when a record needs
compatibility fields such as createdBy or updatedBy; that ID grants no
permissions.
Legacy account and password-hash keys are purged by migration and excluded from
exports/restores; historical audit IDs embedded in library records are kept.
Run locally
Requirements:
- Node.js 26 or newer (the database uses Node's built-in
node:sqlite) - npm
npm install
npm run dev
Open http://localhost:3000. The tracked SQLite database
is loaded automatically. Development and production servers bind to
127.0.0.1; API mutations also require a same-origin local request.
An environment file is optional. To use a different SQLite file:
SQLITE_DB_PATH=./data/digitalbookdb.sqlite
Scripts
npm run dev— start the development servernpm run build— build for productionnpm run start— run the production buildnpm run typecheck— run TypeScript checksnpm run lint— run ESLint with zero warningsnpm run check:sqlite-local-db— verify the local SQLite adapternpm run check:sqlite-projections— verify migrations, normalized projections, FTS search, filters, and paginationnpm run check:native-store— verify native-table CRUD, virtual legacy indexes, snapshot restore, and integritynpm run check:change-history— verify transactional history, rollback, canonical NDJSON export, and stale-undo protectionnpm run check:portable-backup— verify compressed streaming backups, manifests, safety limits, and native-table round tripsnpm run check:data-quality— verify issue counts and complete duplicate samples for the data-quality workbenchnpm run test:regression— run all non-browser database, API, transaction, operations, and local-request safety checksnpm run test:e2e— run destructive browser workflows against an isolated temporary SQLite database and temporary local storagenpm run test:smoke:production— build and smoke-test the production server against an isolated temporary databasenpm run maintenance:local -- --help— show the local maintenance commandnpm run import:legacy-backup -- path/to/backup.json— replace the local SQLite contents with a compatible legacy JSON snapshot
Data and backups
- The canonical database is
data/digitalbookdb.sqliteand is intentionally tracked directly by Git. - Runtime SQLite sidecars (
.sqlite-wal,.sqlite-shm, and similar files) stay ignored. - The Backups page creates streaming, gzip-compressed portable NDJSON snapshots
in
backups/. Each snapshot carries a schema version, record/type counts, byte counts, and a SHA-256 manifest. - Restore accepts current SQLite snapshots and legacy JSON snapshots so old data can be migrated without running the old server backend.
Committing the SQLite database safely
Treat the tracked database as a single-writer artifact. Git compresses it for transport, but SQLite files cannot be meaningfully line-merged.
- Stop every running DigitalBookDB process so no connection can write while the snapshot is being committed.
- Create a backup from
/admin/backup. - Run
npm run check:sqlite-local-dband confirm the integrity check succeeds. - Ensure no
digitalbookdb.sqlite-walordigitalbookdb.sqlite-shmsidecar is present. - Stage
data/digitalbookdb.sqlitetogether with the code that understands its schema, then commit them as one change. - If two branches changed the database, choose one snapshot and re-apply the other branch's changes through the application or a portable export. Do not use a binary merge tool.
Before pulling a database update, stop the app and preserve uncommitted local changes in a backup. After pulling, run the integrity check before starting the app again.
Normalized SQLite tables are authoritative for series, books, media,
categories, submissions, and book hashes. The small kv_store table remains
only for non-domain settings and historical moderation records; normal library
CRUD no longer duplicates data into it. Repeatable schema migrations maintain
constraints, indexes, derived compatibility views, and an FTS5 search index.
Multi-record writes and exports are serialized through explicit SQLite
transactions. See
docs/native-sqlite-storage.md for migration
and virtual-backup details.
Entity mutations are recorded transactionally with the supporting index and
collection writes needed for safe undo. The History page rejects stale undo
attempts instead of overwriting newer work and exports canonical, deterministic
NDJSON for review or branch reconciliation. See
docs/change-history.md for the format and safety
rules.
Portable compressed backups are streamed without materializing the full export,
written atomically, verified through their manifests, and rotated using the
configured retention count. Destructive restore/import requires a fresh
validated preview token and first creates a safety backup. The maintenance page
can create a checkpoint, verify integrity, rebuild indexes, inspect orphan
uploads, and optionally run VACUUM. The diagnostics page reports database
size, record counts, backup age, orphan files, and recent structured local
errors.
Uploads are constrained by extension, MIME declaration, file signature, size,
path containment, and a one-hour orphan grace period by default. Manga cleanup
also bounds archive size, entries, expanded bytes, compression ratio, and
concurrent extraction work; every limit is configurable in .env.example.
Main routes
/database— browse and edit the collection/submit— add media and series data/admin/dashboard— local administration/admin/backup— backup and restore/admin/maintenance— integrity and duplicate checks/admin/diagnostics— local health, storage, backup, and error diagnostics/admin/history— transactional history, safe undo, and portable NDJSON/admin/data-quality— missing metadata, duplicate candidates, orphan submissions, and suspicious hash collisions/admin/manga-cleanup— cleanup workflow
License
This project is licensed under the GNU Affero General Public License v3.0.
See LICENSE for the full text.