Files
bookorbit/client
neon 100953ea1b feat(metadata): write metadata to every file of a multi-file book
Books often carry several files, such as an EPUB beside a PDF or an audiobook split into tracks.
Write-back reached only the primary file and the audio tracks, so the other formats kept stale
metadata.

Add an opt-in per-library mode that writes every content file of a book. Target selection,
capability reporting and the Files tab now share one role-aware selector, covers resolve per
medium, and results report per-format counts. Read-along EPUBs get their own toggle, off by
default, and their own size limit of 1000 MB, so they no longer follow the EPUB settings.

Live testing on copies of real libraries surfaced write-path bugs, fixed here as well:
- tag-only writes to chaptered M4B files failed because FFmpeg copied the chapter data track
- an undecodable cover failed every file instead of falling back to metadata only
- failure reasons stored the FFmpeg command line and absolute paths; they are now sanitized
- size limits used the stored size, so an unknown size bypassed them; writes now check the disk
- atomic replace dropped the file mode and ownership
- the EPUB temp name failed on long file names and could clash with a user file
- tracks in disc folders got duplicate titles
- a PDF worker that exited without a result hung its write forever; it now fails and times out
- null on a NOT NULL library setting returned 500 instead of 400

Generates migrations 0104 and 0105. Every new API field is optional, and released iOS builds
decode none of them.

Ref #694
2026-10-07 16:52:52 +00:00
..

BookOrbit - Client

Vue 3 SPA built with Vite and Tailwind CSS v4.

Running

From the repo root: pnpm dev (starts both server and client).

Client only: pnpm dev (from this directory). Runs at http://localhost:6263.

The Vite dev server proxies /api and /socket.io requests to the backend at localhost:6262.

IDE setup

  • VS Code: Install the Vue (Official) extension. Disable Vetur if installed.
  • WebStorm / IntelliJ: Vue support is built in. Enable TypeScript service for .vue files.
  • Browser: Install Vue.js devtools and enable Custom Object Formatters in DevTools settings.

Project layout

src/
├── features/           Feature modules (one folder per domain)
│   ├── auth/           Login, registration, password reset
│   ├── book/           Book detail, covers, metadata
│   ├── library/        Library management
│   ├── collection/     Book collections
│   ├── smart-scope/           Saved search views
│   ├── scanner/        Scan progress UI
│   ├── reader/         Book reader (epub, pdf, cbz)
│   ├── settings/       User settings
│   └── admin/          Admin panel (users, roles, settings)
├── components/         Shared components (header, sidebar, icons)
│   └── ui/             Reusable UI primitives (button, dialog, etc.)
├── composables/        Global composables
├── views/              Route-level page components
├── router/             Vue Router config and guards
├── lib/                Utilities (api client, helpers)
├── stores/             Pinia stores (theme only - prefer composables)
└── assets/             CSS, fonts, static assets

Testing

pnpm test:unit          # run unit tests
pnpm test:cov           # run unit tests with coverage

Key conventions

  • All components use <script setup lang="ts"> (Composition API only).
  • Feature state lives in composables (features/<name>/composables/use*.ts), not global stores.
  • HTTP calls use the native fetch API via src/lib/api.ts.
  • Styling with Tailwind CSS v4 utility classes. Theme tokens are CSS variables in src/assets/main.css.
  • Icons from @lucide/vue only.
  • Shared types imported from @bookorbit/types.