Files
famdone/RULES.md
T
2026-08-07 11:37:46 +01:00

58 lines
4.5 KiB
Markdown

# FamChore v2 — Rules
## Auth
- Every collection query includes `famId = @request.auth.famId` filter
- Super admin bypasses famId filter (access via PB admin API)
- `deviceToken` stored as SHA-256 hash; never log raw tokens
## Config
- **SvelteKit must never import `config.ts`.** `config.ts` at root owns the three service **ports** for the Hono proxy (`FRONTEND_PORT`/`PROXY_PORT`/`PB_PORT` = `2080`/`3456`/`8090`).
- SvelteKit env vars are declared in `frontend/src/env.ts` via `defineEnvVars`, read with `$app/env/public` / `$app/env/private`. Loopback URLs are code constants; the only real env vars are the PB creds and `SERVER_IP`.
- Runtime env values live in `.env` at root (symlinked to `frontend/.env`; loaded by the proxy dev via `tsx --env-file=../.env`). `.env.example` is the committed template. Never commit `.env`.
- `.env` currently holds only: `PB_EMAIL`, `PB_PASSWORD`, `SERVER_IP`. Ports come from `config.ts`, not `.env`.
## Ports
- Frontend: `2080`
- Proxy: `3456`
- Container external: `3001` (port `3000` is reserved) — chosen at deploy via compose `PORT`
- Must not use port `3000` for anything.
## Docker
- Prod: `docker/Dockerfile` (multi-stage + nginx, bundles internal PB)
- Dev PB: `docker/Dockerfile.dev` (standalone PocketBase)
- Nginx routes: `/api/*` → Hono (`:3456`), `/pb/api/*` → PB (`:8090`), `/pb/` → 404 (admin UI kept internal), `/*` → SvelteKit (`:2080`)
- `docker-compose.yaml`: public port is `${PORT:-3001}:3001`; internal PB published loopback-only as `127.0.0.1:8091:8090`.
## ⚠️ Dev vs Prod PocketBase data (READ BEFORE TOUCHING CONTAINERS)
- **Permanent dev PB** = container **`pb-dev`**, publishes **`:8090`**, data in host **`./pb_data`** (root-owned). This is what `pnpm dev` talks to (via `SERVER_IP:8090`).
- **Docker app** (`famchamp-app-1`) has its **own internal PB**, published **`:8091`** (loopback), and it **also bind-mounts `./pb_data` → `/app/pb_data`**. So `pb-dev` and the docker app currently **share the same host data dir** — two PB processes on one store. Keep this in mind; the docker version is not the dev target.
- **NEVER `docker rm`/recreate `pb-dev` with a fresh volume** — that wipes the permanent dev PB. To restore it, recreate with its data intact:
```
docker rm -f pb-dev
docker run -d --name pb-dev \
-v "$PWD/pb_data:/pb_data" \
-p 8090:8090 \
pb-dev \
pocketbase serve --http=0.0.0.0:8090 --dir=/pb_data
```
- Superuser creds: `debug@famchamp.dev` / `debug123` (fallback baked in code). If superuser auth returns HTTP 500, the container is almost certainly serving an **empty store** (broken/missing mount) — restore the mount, don't reseed a new store.
- `SERVER_IP`: same LAN = `192.168.1.225`, away = your Tailscale IP (e.g. `100.103.22.104`). Both hit the same `pb-dev:8090`. Update `.env` when your IP changes.
## Monorepo
- SvelteKit in `frontend/`, Hono in `proxy/`
- `pnpm dev` / `pnpm build` at root runs both in parallel
- `shared/` at root for code shared across packages, imported as `@shared/*` (path alias):
- `shared/config.ts` — service ports (`FRONTEND_PORT`/`PROXY_PORT`/`PB_PORT`)
- `shared/timezone.ts` — timezone helpers (imported by frontend routes + proxy/src/index.ts)
- `shared/pb/schema.ts` — single source of truth for the PocketBase schema + field builders. Both `proxy/src/migrate.ts` (idempotent bootstrap) and `proxy/scripts/seed.ts` consume `SCHEMA_PLAN`; edit schema there, not in the consumers.
- **`@shared/*` alias:** wired per package — proxy via `tsconfig.json` `paths` + esbuild `--alias:@shared=../shared` (tsx reads tsconfig paths); frontend via `kit.alias` in `vite.config.ts` (don't set `paths` in `frontend/tsconfig.json` — SvelteKit warns). In the frontend, import shared files **without** the `.ts` extension (`@shared/timezone`), because `rewriteRelativeImportExtensions` only rewrites relative paths; the proxy keeps `.ts` extensions.
- **Shared-file convention:** keep shared code in `shared/` (root), never inside `frontend/` or `proxy/`. SvelteKit never imports `config.ts`.
- Decisions tracked in `MEMORY.md`
## Environment Variables
- `SERVER_IP` — dev machine IP where PB + proxy run (browser `pocketbase.ts`, `pb-admin`, proxy all read it). Dev only; prod ignores it.
- `PB_EMAIL` / `PB_PASSWORD` — PB superuser (fallback `debug@famchamp.dev`/`debug123`)
- `PROXY_URL` — public env in `env.ts` (default `http://127.0.0.1:3456`); SSR → proxy
- Compose/deploy: `PORT` (public port, default `3001`), `PB_DATA` (host data dir)
- Not currently wired (future): `STRIPE_SECRET_KEY`, `DONATION_MODAL_INTERVAL`