mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
3b9bae7525
Two independent guards were failing the workflow on healthy input. Retention read "exported value equals the English source" as a lost translation, but exports are built with skipUntranslatedStrings, so Crowdin omits a key entirely once it stops carrying a translation. Anything present in the export is by definition translated, and the equality check only ever fired on correct work: Spanish "Error", "Feb" and "Cookie", French "Description", Portuguese "Readwise". Retention now compares presence alone, which is what absence already meant. The same inference lived in a legacyComplete branch that would have silently stopped protecting the 2,318 keys whose translation legitimately equals the source once any locale reached full translation. Scheduled runs had no way out of that. The only escape hatch is allowed_translation_losses, a workflow_dispatch input that is never persisted, so every schedule rediscovered the same losses and failed until someone dispatched the run by hand. The slot count rule then only runs for the keys it is given, and the sync passed none, so its rejection filter was weaker than the locale validation running on its output one step later. An invalid ja message survived the filter, reached the catalog, and failed the next step instead of being dropped and reported. Move the source scan into locale-source-keys.mjs so the sync and validate-locales.mjs derive the same keys.
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:5173.
The Vite dev server proxies /api and /socket.io requests to the backend at localhost:3000.
IDE setup
- VS Code: Install the Vue (Official) extension. Disable Vetur if installed.
- WebStorm / IntelliJ: Vue support is built in. Enable TypeScript service for
.vuefiles. - 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
fetchAPI viasrc/lib/api.ts. - Styling with Tailwind CSS v4 utility classes. Theme tokens are CSS variables in
src/assets/main.css. - Icons from
@lucide/vueonly. - Shared types imported from
@bookorbit/types.