diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5a32ea6 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Copy to .env and fill in. .env is not committed. +PB_DIR=pocketbase/pb_data +PB_SUPERUSER_EMAIL= +PB_SUPERUSER_PASSWORD= diff --git a/.gitignore b/.gitignore index 854acd5..abc6aa7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ yarn-error.log *.launch .settings/ *.sublime-workspace +.claude/ # Visual Studio Code .vscode/* @@ -39,6 +40,10 @@ testem.log /typings __screenshots__/ +# PocketBase +/pocketbase/pb_data +.env + # System files .DS_Store Thumbs.db diff --git a/README.md b/README.md index 3615144..3875e41 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,32 @@ ng e2e Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. +## PocketBase + +The backend is [PocketBase](https://pocketbase.io/) (v0.40.x). The `pocketbase` binary must be in `PATH`. + +- `pocketbase/pb_migrations/` — collection schema as JS migrations (committed). +- `pocketbase/pb_data/` — local dev database (not committed). + +Local development: + +```bash +cp .env.example .env # then set PB_SUPERUSER_EMAIL / PB_SUPERUSER_PASSWORD +pnpm pb:superuser # create the superuser or reset its password (safe to re-run) +pnpm pb:serve # http://127.0.0.1:8090, admin UI at /_/ +``` + +Migrations are applied on `pb:serve` start (or explicitly with `pnpm pb:migrate`). Schema changes made in the dev admin UI are written to `pocketbase/pb_migrations/` automatically — commit them. + +Production uses the same binary version and the same `pb_migrations/`, with its own data dir: + +```bash +pocketbase serve --dir /path/to/pb_data --migrationsDir pocketbase/pb_migrations --automigrate=false --http 127.0.0.1:8090 +PB_DIR=/path/to/pb_data node --env-file=.env scripts/pb-superuser.mjs +``` + +Back up by copying the `pb_data` directory. + ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/package.json b/package.json index a111885..575ce7d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,10 @@ "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", - "serve:ssr:pchelpcrm": "node dist/pchelpcrm/server/server.mjs" + "serve:ssr:pchelpcrm": "node dist/pchelpcrm/server/server.mjs", + "pb:serve": "pocketbase serve --dir pocketbase/pb_data --migrationsDir pocketbase/pb_migrations --dev", + "pb:superuser": "node --env-file=.env scripts/pb-superuser.mjs", + "pb:migrate": "pocketbase migrate up --dir pocketbase/pb_data --migrationsDir pocketbase/pb_migrations" }, "private": true, "dependencies": { @@ -20,6 +23,7 @@ "@angular/router": "^22.2.0", "@angular/ssr": "^22.2.3", "express": "^5.1.0", + "pocketbase": "^0.28.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7755fcc..fff2fe9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: express: specifier: ^5.1.0 version: 5.3.0(supports-color@8.1.1) + pocketbase: + specifier: ^0.28.1 + version: 0.28.1 rxjs: specifier: ~7.8.0 version: 7.8.2 @@ -1986,6 +1989,9 @@ packages: resolution: {integrity: sha512-vv7l/mM7B9WgrhDaudIqv1x6v4LOBRYYmpWGdWushhpbCmVHp11sUB2v4hj1CAeTGXVxuZFz6xOU1RalAiPKfQ==} engines: {node: '>=20.x'} + pocketbase@0.28.1: + resolution: {integrity: sha512-/3ihkq+rvfcs0MQgrK4sEElOg6gfenHW9S/O+3BSO+V1yT+4B10+9aT22uTQUPqze9ItwNtwWyY5ZmdgVCTdVA==} + postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} @@ -4194,6 +4200,8 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.1.1 + pocketbase@0.28.1: {} + postcss-media-query-parser@0.2.3: {} postcss-safe-parser@7.1.0(postcss@8.5.31): diff --git a/pocketbase/pb_migrations/.gitkeep b/pocketbase/pb_migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/pb-superuser.mjs b/scripts/pb-superuser.mjs new file mode 100644 index 0000000..51a061e --- /dev/null +++ b/scripts/pb-superuser.mjs @@ -0,0 +1,12 @@ +// Creates the PocketBase superuser or resets its password (idempotent). +import { execFileSync } from 'node:child_process'; + +const { PB_SUPERUSER_EMAIL: email, PB_SUPERUSER_PASSWORD: password } = process.env; +const dir = process.env.PB_DIR || 'pocketbase/pb_data'; + +if (!email || !password) { + console.error('PB_SUPERUSER_EMAIL and PB_SUPERUSER_PASSWORD must be set (see .env.example)'); + process.exit(1); +} + +execFileSync('pocketbase', ['superuser', 'upsert', email, password, '--dir', dir], { stdio: 'inherit' });