chore(tooling): switch to fnm + pnpm, add DEPLOYMENT.md
Pin Node 24 via .node-version/.nvmrc and pnpm 9.15.0 via package.json#packageManager. Regenerate lockfile as pnpm-lock.yaml. Rewrite README setup + scripts table around pnpm, and add a production deployment guide covering systemd, nginx, upgrades, rollback, and backups. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,17 +16,33 @@ Siblings: [`buildfor_life_budget`](https://git.b4l.co.th/B4L/buildfor_life_budge
|
||||
|
||||
### 1. Prerequisites
|
||||
|
||||
- Node 20+ (24.x tested)
|
||||
- **Node 24** pinned via `.node-version` (installed with [`fnm`](https://github.com/Schniz/fnm))
|
||||
- **pnpm 9** as the package manager (declared in `package.json#packageManager`)
|
||||
- PostgreSQL 16+ running locally or reachable by URL
|
||||
- `git` with SSH access to `gitssh.b4l.co.th`
|
||||
|
||||
### 2. Install
|
||||
### 2. Install fnm + pnpm
|
||||
|
||||
```bash
|
||||
npm install
|
||||
# fnm (one-time, per machine)
|
||||
curl -fsSL https://fnm.vercel.app/install | bash # macOS / Linux
|
||||
winget install Schniz.fnm # Windows (or: scoop install fnm)
|
||||
|
||||
# pnpm (one-time, via Corepack which ships with Node)
|
||||
corepack enable
|
||||
corepack prepare pnpm@9.15.0 --activate
|
||||
```
|
||||
|
||||
### 3. Configure environment
|
||||
### 3. Activate the pinned Node version and install deps
|
||||
|
||||
```bash
|
||||
fnm use --install-if-missing
|
||||
pnpm install
|
||||
```
|
||||
|
||||
`fnm use` reads `.node-version` and drops you onto the correct Node. Add `eval "$(fnm env --use-on-cd)"` to your shell rc (bash/zsh) or the PowerShell equivalent so this happens automatically on `cd` into the repo.
|
||||
|
||||
### 4. Configure environment
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
@@ -42,22 +58,22 @@ Edit `.env`:
|
||||
- `STORAGE_LOCAL_ROOT` — where uploaded blobs live on disk (default `./storage`)
|
||||
- OIDC block — leave `OIDC_ENABLED=false` unless you're wiring SSO
|
||||
|
||||
### 4. Create the database
|
||||
### 5. Create the database
|
||||
|
||||
```bash
|
||||
createdb buildfor_life_ops # or use your tool of choice
|
||||
```
|
||||
|
||||
### 5. Apply migrations
|
||||
### 6. Apply migrations
|
||||
|
||||
```bash
|
||||
npm run db:migrate
|
||||
pnpm run db:migrate
|
||||
```
|
||||
|
||||
### 6. Bootstrap the first admin user
|
||||
### 7. Bootstrap the first admin user
|
||||
|
||||
```bash
|
||||
npm run create-user -- \
|
||||
pnpm run create-user -- \
|
||||
--email you@b4l.co.th \
|
||||
--password 'a-long-password' \
|
||||
--name 'Your Name' \
|
||||
@@ -65,29 +81,29 @@ npm run create-user -- \
|
||||
--role admin
|
||||
```
|
||||
|
||||
### 7. Run the dev server
|
||||
### 8. Run the dev server
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open http://localhost:5173 and log in.
|
||||
|
||||
## npm scripts
|
||||
## pnpm scripts
|
||||
|
||||
| Command | What it does |
|
||||
| --- | --- |
|
||||
| `npm run dev` | Start the Vite dev server with HMR |
|
||||
| `npm run build` | Production build (outputs to `build/`) |
|
||||
| `npm run preview` | Preview the production build locally |
|
||||
| `npm run check` | Typecheck: `svelte-kit sync` then `svelte-check --threshold warning` |
|
||||
| `npm run validate` | `check` + `build` — use this as a pre-commit smoke test |
|
||||
| `npm run db:generate` | Diff the Drizzle schema against the last snapshot and emit a new migration under `drizzle/` |
|
||||
| `npm run db:migrate` | Apply pending migrations against `$DATABASE_URL` |
|
||||
| `npm run db:push` | Skip migration files and sync the schema directly — **dev only** |
|
||||
| `npm run db:studio` | Open Drizzle Studio (web UI at localhost for inspecting data) |
|
||||
| `npm run db:seed` | Seed the system catalog of asset types (wired when the assets schema lands in Phase 1) |
|
||||
| `npm run create-user -- --email ... --password ... --name ... [--company ...] [--role ...]` | Create or update a user; optionally attach them to a company with a role |
|
||||
| `pnpm dev` | Start the Vite dev server with HMR |
|
||||
| `pnpm build` | Production build (outputs to `build/`) |
|
||||
| `pnpm preview` | Preview the production build locally |
|
||||
| `pnpm check` | Typecheck: `svelte-kit sync` then `svelte-check --threshold warning` |
|
||||
| `pnpm validate` | `check` + `build` — use this as a pre-commit smoke test |
|
||||
| `pnpm db:generate` | Diff the Drizzle schema against the last snapshot and emit a new migration under `drizzle/` |
|
||||
| `pnpm db:migrate` | Apply pending migrations against `$DATABASE_URL` |
|
||||
| `pnpm db:push` | Skip migration files and sync the schema directly — **dev only** |
|
||||
| `pnpm db:studio` | Open Drizzle Studio (web UI at localhost for inspecting data) |
|
||||
| `pnpm db:seed` | Seed the system catalog of asset types |
|
||||
| `pnpm run create-user -- --email ... --password ... --name ... [--company ...] [--role ...]` | Create or update a user; optionally attach them to a company with a role |
|
||||
|
||||
## Project layout
|
||||
|
||||
@@ -181,6 +197,6 @@ When in doubt, check the siblings before inventing:
|
||||
## Troubleshooting
|
||||
|
||||
- **`Environment validation failed`** on boot — `.env` is missing or incomplete; compare against `.env.example`
|
||||
- **`relation "sessions" does not exist`** — you skipped `npm run db:migrate` after `db:generate`
|
||||
- **`relation "sessions" does not exist`** — you skipped `pnpm run db:migrate` after `db:generate`
|
||||
- **Session cookie never sets** — in dev, make sure `PUBLIC_BASE_URL` includes `localhost` so the hook sets `secure: false`; in production use HTTPS
|
||||
- **`sha256 mismatch on upload`** — the client-computed sha256 disagrees with the server's stream hash; retry the upload
|
||||
|
||||
Reference in New Issue
Block a user