Files
bookorbit/server
neon ce6a439062 feat(server): add unified entity manager with duplicate detection
- Remove author insights and duplicate suggestions panels, composables, DTOs, and all backend support
- Add genre and tag duplicate detection, merge, and dismiss with server-side paginated scan results
- Consolidate per-entity-type tools into a single entity-manager module backed by the Strategy pattern
- Support browse, merge, rename, delete, split, and dismiss across all entity types (author, genre, tag, narrator, publisher, language, series)
- Replace old tools module with unified entity-manager controller, service, and repository; add 85+ unit tests
2026-04-20 19:10:47 -06:00
..

ProjectX - 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.

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
├── lens/           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.

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

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:

pnpm run e2e:list
pnpm run e2e:all
pnpm run e2e:run -- scanner-scenarios

Quality

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.