4.5 KiB
4.5 KiB
FamChore v2 — Rules
Auth
- Every collection query includes
famId = @request.auth.famIdfilter - Super admin bypasses famId filter (access via PB admin API)
deviceTokenstored as SHA-256 hash; never log raw tokens
Config
- SvelteKit must never import
config.ts.config.tsat 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.tsviadefineEnvVars, read with$app/env/public/$app/env/private. Loopback URLs are code constants; the only real env vars are the PB creds andSERVER_IP. - Runtime env values live in
.envat root (symlinked tofrontend/.env; loaded by the proxy dev viatsx --env-file=../.env)..env.exampleis the committed template. Never commit.env. .envcurrently holds only:PB_EMAIL,PB_PASSWORD,SERVER_IP. Ports come fromconfig.ts, not.env.
Ports
- Frontend:
2080 - Proxy:
3456 - Container external:
3001(port3000is reserved) — chosen at deploy via composePORT - Must not use port
3000for 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 as127.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 whatpnpm devtalks to (viaSERVER_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. Sopb-devand 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/recreatepb-devwith 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 samepb-dev:8090. Update.envwhen your IP changes.
Monorepo
- SvelteKit in
frontend/, Hono inproxy/ pnpm dev/pnpm buildat root runs both in parallelshared/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. Bothproxy/src/migrate.ts(idempotent bootstrap) andproxy/scripts/seed.tsconsumeSCHEMA_PLAN; edit schema there, not in the consumers.
@shared/*alias: wired per package — proxy viatsconfig.jsonpaths+ esbuild--alias:@shared=../shared(tsx reads tsconfig paths); frontend viakit.aliasinvite.config.ts(don't setpathsinfrontend/tsconfig.json— SvelteKit warns). In the frontend, import shared files without the.tsextension (@shared/timezone), becauserewriteRelativeImportExtensionsonly rewrites relative paths; the proxy keeps.tsextensions.- Shared-file convention: keep shared code in
shared/(root), never insidefrontend/orproxy/. SvelteKit never importsconfig.ts. - Decisions tracked in
MEMORY.md
Environment Variables
SERVER_IP— dev machine IP where PB + proxy run (browserpocketbase.ts,pb-admin, proxy all read it). Dev only; prod ignores it.PB_EMAIL/PB_PASSWORD— PB superuser (fallbackdebug@famchamp.dev/debug123)PROXY_URL— public env inenv.ts(defaulthttp://127.0.0.1:3456); SSR → proxy- Compose/deploy:
PORT(public port, default3001),PB_DATA(host data dir) - Not currently wired (future):
STRIPE_SECRET_KEY,DONATION_MODAL_INTERVAL