# BookOrbit - Server NestJS 11 backend running on Fastify. ## Running From the repo root: `pnpm dev` (starts both server and client). Server only: `pnpm start:dev` (from this directory). The server loads environment variables from `.env` in this directory. See `.env.example` for all available options. ## API docs OpenAPI docs are disabled by default. Enable them with `SWAGGER_ENABLED=true`: ```bash SWAGGER_ENABLED=true pnpm start:dev ``` Then open: - Swagger UI: http://localhost:3000/api/docs - OpenAPI JSON: http://localhost:3000/api/docs-json Dev watch uses a Nest config without the Swagger metadata generator so the server does not restart immediately after startup. Full build output still uses the standard Nest config and generates `src/metadata.ts` for enriched docs. ## Module structure Each feature is a self-contained NestJS module under `src/modules/`: ``` src/modules/ ├── auth/ Authentication (JWT, OIDC, password reset) ├── book/ Book CRUD, cover images, file serving ├── library/ Library management ├── scanner/ File system scanning, metadata extraction ├── collection/ User book collections ├── smart-scope/ Saved search/filter views ├── user/ User management ├── role/ Roles and permissions (RBAC) ├── metadata/ Book metadata providers ├── kobo/ Kobo device sync ├── annotation/ Highlights and annotations ├── bookmark/ Reading position bookmarks ├── reader-preferences/ Per-user reader settings ├── cbz/ CBZ archive handling ├── path/ File path utilities ├── seed/ Database seeding └── app-settings/ Global application settings ``` ## Database Schema files live in `src/db/schema/`, one per domain. Migrations are generated by Drizzle Kit. ```bash pnpm db:generate add_some_column # generate migration from schema diff pnpm db:migrate # apply pending migrations pnpm db:studio # open Drizzle Studio (DB browser) ``` ## Testing ```bash pnpm test # unit tests pnpm test:watch # unit tests in watch mode pnpm e2e:run # app-smoke end-to-end test from server package pnpm test:cov # unit tests with coverage ``` For suite-based e2e runs, run from the repository root: ```bash pnpm run e2e:list pnpm run e2e:all pnpm run e2e:run -- scanner-scenarios ``` ## Quality ```bash pnpm type-check # TypeScript checks (no emit) pnpm lint:check # Non-mutating lint checks pnpm lint:fix # Auto-fix lint issues pnpm format:check # Prettier check pnpm format # Prettier write ``` ## Key conventions - Constructor injection with `@Inject(DB)` for the Drizzle instance. - Config via `@nestjs/config` named configs (`appConfig`, `dbConfig`, `authConfig`, `storageConfig`, `mailerConfig`). Never read `process.env` directly in services. - DTOs use `class-validator` decorators. Global `ValidationPipe` rejects unknown fields. - Throw NestJS `HttpException` subclasses (`NotFoundException`, `ForbiddenException`, etc.) - never raw `Error`. - All user-owned data is scoped by `userId`. Service methods check ownership.