mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
docs: add developer onboarding guide and replace boilerplate READMEs
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
# ProjectX
|
||||
|
||||
A book and library management app with Kobo device support. Multi-user, self-hostable.
|
||||
|
||||
**Tech stack:** NestJS 11 (Fastify) + Vue 3 + PostgreSQL + Drizzle ORM
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
| Tool | Version | Install |
|
||||
|---------|---------|--------------------------------------------------------------|
|
||||
| Node.js | >= 24 | [nodejs.org](https://nodejs.org) |
|
||||
| pnpm | >= 9 | `corepack enable && corepack prepare pnpm@latest --activate` |
|
||||
| Docker | latest | [docker.com](https://www.docker.com/products/docker-desktop) |
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
git clone <repo-url> projectx
|
||||
cd projectx
|
||||
docker compose up -d --wait # start Postgres
|
||||
cp server/.env.example server/.env # create env config (edit if needed)
|
||||
pnpm install # install all dependencies
|
||||
cd server && pnpm db:migrate && cd .. # apply database migrations
|
||||
```
|
||||
|
||||
Docker is only used for PostgreSQL. The server and client run directly on your machine.
|
||||
|
||||
### Start developing
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
This starts the NestJS server and Vue client concurrently:
|
||||
|
||||
- **Client:** http://localhost:5173
|
||||
- **API:** http://localhost:3000/api
|
||||
|
||||
If you prefer separate terminals (cleaner logs):
|
||||
|
||||
```bash
|
||||
# Terminal 1
|
||||
cd server && pnpm start:dev
|
||||
|
||||
# Terminal 2
|
||||
cd client && pnpm dev
|
||||
```
|
||||
|
||||
Both must be running. The client proxies all `/api` and `/socket.io` requests to the server, so API calls will fail if only the client is running.
|
||||
|
||||
### First steps after setup
|
||||
|
||||
1. **Log in** - a default admin account is created automatically:
|
||||
- Username: `admin`
|
||||
- Password: `admin`
|
||||
2. **Change password** - you'll be prompted to set a new password on first login. Use `Admin123!` for local dev.
|
||||
3. **Create a library** - open Settings (gear icon) > Libraries > Create Library. Add a folder path pointing to some books on your machine, e.g. any directory containing `.epub`, `.pdf`, or `.cbz` files.
|
||||
4. **Scan** - the library scans automatically after creation. You should see books appear on the home page once the scan completes.
|
||||
|
||||
> **Where does data go?** `BOOKS_PATH` in `server/.env` defaults to `../local/data` (resolves to `<project-root>/local/data`). This is the app's data directory where extracted cover images and thumbnails are stored (`local/data/covers/`). It is **not** where your book files live - those paths are configured per-library in the UI. The `local/` folder is gitignored.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
projectx/
|
||||
├── client/ Vue 3 frontend (Vite + Tailwind CSS v4)
|
||||
├── server/ NestJS 11 backend (Fastify + Drizzle ORM)
|
||||
├── packages/
|
||||
│ └── types/ Shared TypeScript types (@projectx/types)
|
||||
├── docker/
|
||||
│ └── postgres/ Postgres init scripts (extensions)
|
||||
├── local/ Local dev data (covers, docs) - gitignored
|
||||
├── docker-compose.yml Dev: runs Postgres only (app runs natively)
|
||||
├── Dockerfile Production multi-stage build
|
||||
└── Dockerfile.dev Runs entire stack in Docker (not used for normal dev)
|
||||
```
|
||||
|
||||
### Monorepo layout
|
||||
|
||||
This is a **pnpm workspace**. The three packages are:
|
||||
|
||||
- **`server/`** - NestJS API. Modules live in `src/modules/`, one folder per feature. Database schema is in `src/db/schema/`.
|
||||
- **`client/`** - Vue 3 SPA. Feature code lives in `src/features/`, shared components in `src/components/ui/`.
|
||||
- **`packages/types/`** - Shared types imported as `@projectx/types` by both server and client. Add any type that crosses the API boundary here.
|
||||
|
||||
---
|
||||
|
||||
## Common Commands
|
||||
|
||||
All commands run from the **repo root** unless noted otherwise.
|
||||
|
||||
### Development
|
||||
|
||||
| Command | Description |
|
||||
|-------------------------------|--------------------------------------|
|
||||
| `pnpm dev` | Start server + client (concurrently) |
|
||||
| `cd server && pnpm start:dev` | Server only (watch mode) |
|
||||
| `cd client && pnpm dev` | Client only (Vite dev server) |
|
||||
|
||||
### Testing
|
||||
|
||||
| Command | Description |
|
||||
|----------------------------------------------------|---------------------------|
|
||||
| `cd server && pnpm test` | Server unit tests |
|
||||
| `cd server && pnpm test -- --testPathPattern=scan` | Run matching server tests |
|
||||
| `cd client && pnpm test:unit` | Client unit tests |
|
||||
| `cd client && pnpm test:unit -- BookCover` | Run matching client tests |
|
||||
| `cd server && pnpm test:e2e` | Server E2E tests |
|
||||
|
||||
### Database
|
||||
|
||||
| Command | Description |
|
||||
|----------------------------------------|------------------------------------------|
|
||||
| `cd server && pnpm db:migrate` | Apply pending migrations |
|
||||
| `cd server && pnpm db:generate <name>` | Generate a migration from schema changes |
|
||||
| `cd server && pnpm db:studio` | Open Drizzle Studio (DB browser) |
|
||||
|
||||
### Linting & formatting
|
||||
|
||||
| Command | Description |
|
||||
|---------------------------------------|--------------------|
|
||||
| `cd server && npx prettier --write .` | Format server code |
|
||||
| `cd client && npx prettier --write .` | Format client code |
|
||||
| `cd server && pnpm lint` | Lint server |
|
||||
| `cd client && pnpm lint` | Lint client |
|
||||
|
||||
---
|
||||
|
||||
## Development Workflow
|
||||
|
||||
Once `pnpm dev` is running, here's how the feedback loop works for each type of change:
|
||||
|
||||
### Frontend (`client/`)
|
||||
|
||||
Save a file → Vite HMR hot-swaps the module → browser updates instantly. No restart needed.
|
||||
|
||||
### Backend (`server/`)
|
||||
|
||||
Save a file → NestJS watch mode (SWC) recompiles and restarts the server automatically. Takes about a second.
|
||||
|
||||
### Shared types (`packages/types/`)
|
||||
|
||||
The types package points directly at `.ts` source files. Edit a type → both client and server pick it up on their next rebuild cycle. No build step needed.
|
||||
|
||||
### Database schema
|
||||
|
||||
Schema changes are the one thing that isn't automatic. See [Database Workflow](#database-workflow) for the generate + migrate steps.
|
||||
|
||||
### Environment variables
|
||||
|
||||
The `start:dev` script reads `server/.env` once at startup. If you change a value in `.env`, you must restart `pnpm dev` for it to take effect.
|
||||
|
||||
### After `git pull`
|
||||
|
||||
If other people have pushed changes, you may need to sync dependencies and migrations:
|
||||
|
||||
```bash
|
||||
pnpm install # pick up lockfile changes
|
||||
cd server && pnpm db:migrate # apply any new migrations
|
||||
```
|
||||
|
||||
### Adding a dependency
|
||||
|
||||
Always install into the correct workspace, not the root:
|
||||
|
||||
```bash
|
||||
cd server && pnpm add <pkg> # backend dependency
|
||||
cd client && pnpm add <pkg> # frontend dependency
|
||||
```
|
||||
|
||||
### Adding a new feature
|
||||
|
||||
The fastest way to learn the patterns is to follow an existing module:
|
||||
|
||||
- **Backend:** Look at `server/src/modules/bookmark/` for a minimal example (controller, service, repository, DTO, module). Copy it, rename, and adapt.
|
||||
- **Frontend:** Look at `client/src/features/collection/` for a full feature (composables for state/API, components for UI).
|
||||
- **Shared types:** If the feature adds API request/response shapes, add them in `packages/types/src/` and import via `@projectx/types`.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Server environment is configured in `server/.env` (created from `.env.example` during setup).
|
||||
|
||||
| Variable | Default | Description |
|
||||
|--------------------------|--------------------------------------------------------|------------------------------------------------------------|
|
||||
| `DATABASE_URL` | `postgres://projectx:projectx@localhost:5432/projectx` | PostgreSQL connection string |
|
||||
| `PORT` | `3000` | Server port |
|
||||
| `NODE_ENV` | `development` | Environment mode |
|
||||
| `JWT_SECRET` | `change-me-in-production` | JWT signing secret |
|
||||
| `JWT_EXPIRES_IN` | `15m` | Access token lifetime |
|
||||
| `JWT_REFRESH_EXPIRES_IN` | `7d` | Refresh token lifetime |
|
||||
| `BOOKS_PATH` | `../local/data` | App data directory for cover images (not where books live) |
|
||||
| `SMTP_*` | (empty) | Optional SMTP config for password-reset emails |
|
||||
| `APP_URL` | `http://localhost:5173` | Client URL (used in emails) |
|
||||
|
||||
---
|
||||
|
||||
## Database Workflow
|
||||
|
||||
The database schema is defined in `server/src/db/schema/` using Drizzle ORM. Each domain has its own schema file (e.g. `books.ts`, `libraries.ts`, `auth.ts`).
|
||||
|
||||
**Making schema changes:**
|
||||
|
||||
1. Edit the relevant file in `server/src/db/schema/`
|
||||
2. Generate a migration: `cd server && pnpm db:generate describe_your_change`
|
||||
3. Apply it: `cd server && pnpm db:migrate`
|
||||
|
||||
Never hand-write migration SQL. Always generate from schema diffs.
|
||||
|
||||
### Resetting the database from scratch
|
||||
|
||||
```bash
|
||||
# 1. Drop and recreate the public schema
|
||||
docker exec $(docker ps --filter "name=postgres" --format "{{.Names}}" | head -1) \
|
||||
psql -U projectx -d projectx -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
|
||||
|
||||
# 2. Clear Drizzle's migration tracking (it lives in a separate schema)
|
||||
docker exec $(docker ps --filter "name=postgres" --format "{{.Names}}" | head -1) \
|
||||
psql -U projectx -d projectx -c "DELETE FROM drizzle.__drizzle_migrations;"
|
||||
|
||||
# 3. Re-apply all migrations
|
||||
cd server && pnpm db:migrate
|
||||
|
||||
# 4. (Optional) Wipe cover images
|
||||
rm -rf local/data/covers
|
||||
```
|
||||
|
||||
Step 2 is necessary because Drizzle tracks applied migrations in `drizzle.__drizzle_migrations`, which lives outside the `public` schema and survives the drop.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────────────┐ ┌────────────┐
|
||||
│ Vue 3 SPA │──────>│ NestJS API (/api) │──────>│ PostgreSQL │
|
||||
│ port 5173 │<──────│ port 3000 │<──────│ port 5432 │
|
||||
└──────────────┘ └──────────────────────┘ └────────────┘
|
||||
│ │
|
||||
│ WebSocket │ Drizzle ORM
|
||||
│ (socket.io) │ (schema in src/db/schema/)
|
||||
└────────────────────────┘
|
||||
```
|
||||
|
||||
- **Backend:** NestJS 11 on Fastify. Global prefix `/api`. Auth via JWT (access + refresh tokens in httpOnly cookies). RBAC with permissions system.
|
||||
- **Frontend:** Vue 3 Composition API (`<script setup>`). Tailwind CSS v4 for styling. Feature-local state in composables, not global stores.
|
||||
- **Database:** PostgreSQL 16 via Drizzle ORM. Migrations generated by Drizzle Kit.
|
||||
- **Shared types:** `@projectx/types` package ensures API contracts stay in sync.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Port 5432 already in use
|
||||
|
||||
Another PostgreSQL instance is running. Either stop it or change the port mapping in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "5433:5432" # use 5433 on host
|
||||
```
|
||||
|
||||
Then update `DATABASE_URL` in `server/.env` to use port `5433`.
|
||||
|
||||
### Port 3000 or 5173 already in use
|
||||
|
||||
Kill the process occupying the port:
|
||||
|
||||
```bash
|
||||
lsof -ti:3000 | xargs kill -9 # server port
|
||||
lsof -ti:5173 | xargs kill -9 # client port
|
||||
```
|
||||
|
||||
### `pnpm db:migrate` does nothing after a schema change
|
||||
|
||||
You need to generate a migration first:
|
||||
|
||||
```bash
|
||||
cd server && pnpm db:generate describe_your_change
|
||||
cd server && pnpm db:migrate
|
||||
```
|
||||
|
||||
### `pnpm db:generate` fails with a connection error
|
||||
|
||||
Drizzle Kit auto-loads `server/.env` for the `DATABASE_URL`. If the file is missing or the URL is wrong, generation fails. Verify `server/.env` exists and that PostgreSQL is running (`docker compose ps`).
|
||||
|
||||
The fallback URL in `drizzle.config.ts` uses `postgres:5432` (the Docker service hostname), which only works inside Docker, not from the host machine.
|
||||
|
||||
### Docker container won't start
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose up -d --wait
|
||||
```
|
||||
|
||||
If the volume is corrupted, wipe it (destroys all data):
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
docker compose up -d --wait
|
||||
cd server && pnpm db:migrate
|
||||
```
|
||||
|
||||
### `Cannot find module '@projectx/types'`
|
||||
|
||||
The shared types package needs to be built or the workspace link is broken:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### CORS errors in the browser
|
||||
|
||||
Make sure you're accessing the client at `http://localhost:5173` (not port 3000). The Vite dev server proxies API requests to the backend automatically.
|
||||
|
||||
---
|
||||
|
||||
## Further Reading
|
||||
|
||||
| Doc | What it covers |
|
||||
|----------------------------------------|--------------------------------------------------------------|
|
||||
| [`server/README.md`](server/README.md) | Backend module map, DB commands, NestJS conventions |
|
||||
| [`client/README.md`](client/README.md) | Frontend project layout, IDE setup, Vue/Tailwind conventions |
|
||||
| [`packages/types/`](packages/types/) | Shared type definitions between server and client |
|
||||
|
||||
+41
-39
@@ -1,54 +1,56 @@
|
||||
# client
|
||||
# ProjectX - Client
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
Vue 3 SPA built with Vite and Tailwind CSS v4.
|
||||
|
||||
## Recommended IDE Setup
|
||||
## Running
|
||||
|
||||
[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||
From the repo root: `pnpm dev` (starts both server and client).
|
||||
|
||||
## Recommended Browser Setup
|
||||
Client only: `pnpm dev` (from this directory). Runs at http://localhost:5173.
|
||||
|
||||
- Chromium-based browsers (Chrome, Edge, Brave, etc.):
|
||||
- [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
|
||||
- [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
|
||||
- Firefox:
|
||||
- [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
|
||||
- [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
|
||||
The Vite dev server proxies `/api` and `/socket.io` requests to the backend at `localhost:3000`.
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
## IDE setup
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
||||
- **VS Code:** Install the [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) extension. Disable Vetur if installed.
|
||||
- **WebStorm / IntelliJ:** Vue support is built in. Enable TypeScript service for `.vue` files.
|
||||
- **Browser:** Install [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd) and enable Custom Object Formatters in DevTools settings.
|
||||
|
||||
## Customize configuration
|
||||
## Project layout
|
||||
|
||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
src/
|
||||
├── features/ Feature modules (one folder per domain)
|
||||
│ ├── auth/ Login, registration, password reset
|
||||
│ ├── book/ Book detail, covers, metadata
|
||||
│ ├── library/ Library management
|
||||
│ ├── collection/ Book collections
|
||||
│ ├── lens/ 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
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```bash
|
||||
pnpm test:unit # run Vitest
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
## Key conventions
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
||||
|
||||
```sh
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
- 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-next` only.
|
||||
- Shared types imported from `@projectx/types`.
|
||||
|
||||
+5
-1
@@ -11,7 +11,11 @@ JWT_EXPIRES_IN=15m
|
||||
JWT_REFRESH_EXPIRES_IN=7d
|
||||
|
||||
# Storage
|
||||
BOOKS_PATH=/books
|
||||
# App data directory for cover images and generated files.
|
||||
# This path resolves relative to server/ (where the process runs).
|
||||
# ../local/data points to <project-root>/local/data.
|
||||
# In production/Docker this is typically an absolute path like /data.
|
||||
BOOKS_PATH=../local/data
|
||||
|
||||
# OIDC (optional — configure via admin settings UI; these are just for reference)
|
||||
# OIDC config is stored in the database (app_settings table, key: oidc_config)
|
||||
|
||||
+46
-81
@@ -1,98 +1,63 @@
|
||||
<p align="center">
|
||||
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
||||
</p>
|
||||
# ProjectX - Server
|
||||
|
||||
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
|
||||
[circleci-url]: https://circleci.com/gh/nestjs/nest
|
||||
NestJS 11 backend running on Fastify.
|
||||
|
||||
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
|
||||
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
|
||||
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
||||
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
|
||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
||||
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
|
||||
</p>
|
||||
<!--[](https://opencollective.com/nest#backer)
|
||||
[](https://opencollective.com/nest#sponsor)-->
|
||||
## Running
|
||||
|
||||
## Description
|
||||
From the repo root: `pnpm dev` (starts both server and client).
|
||||
|
||||
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
|
||||
Server only: `pnpm start:dev` (from this directory).
|
||||
|
||||
## Project setup
|
||||
The server loads environment variables from `.env` in this directory. See `.env.example` for all available options.
|
||||
|
||||
```bash
|
||||
$ pnpm install
|
||||
## 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
|
||||
```
|
||||
|
||||
## Compile and run the project
|
||||
## Database
|
||||
|
||||
Schema files live in `src/db/schema/`, one per domain. Migrations are generated by Drizzle Kit.
|
||||
|
||||
```bash
|
||||
# development
|
||||
$ pnpm run start
|
||||
|
||||
# watch mode
|
||||
$ pnpm run start:dev
|
||||
|
||||
# production mode
|
||||
$ pnpm run start:prod
|
||||
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)
|
||||
```
|
||||
|
||||
## Run tests
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# unit tests
|
||||
$ pnpm run test
|
||||
|
||||
# e2e tests
|
||||
$ pnpm run test:e2e
|
||||
|
||||
# test coverage
|
||||
$ pnpm run test:cov
|
||||
pnpm test # unit tests
|
||||
pnpm test:watch # unit tests in watch mode
|
||||
pnpm test:e2e # end-to-end tests
|
||||
pnpm test:cov # unit tests with coverage
|
||||
```
|
||||
|
||||
## Deployment
|
||||
## Key conventions
|
||||
|
||||
When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information.
|
||||
|
||||
If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps:
|
||||
|
||||
```bash
|
||||
$ pnpm install -g @nestjs/mau
|
||||
$ mau deploy
|
||||
```
|
||||
|
||||
With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure.
|
||||
|
||||
## Resources
|
||||
|
||||
Check out a few resources that may come in handy when working with NestJS:
|
||||
|
||||
- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
|
||||
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
|
||||
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
|
||||
- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks.
|
||||
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
|
||||
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
|
||||
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
|
||||
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
|
||||
|
||||
## Support
|
||||
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
||||
## Stay in touch
|
||||
|
||||
- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||
- Website - [https://nestjs.com](https://nestjs.com/)
|
||||
- Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
|
||||
- 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.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1770522775823,
|
||||
"when": 1770528090812,
|
||||
"tag": "0000_add_rating_and_book_card_fields",
|
||||
"breakpoints": true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user