5628bab5b6
Repo-root guide for coding agents: stack, commands, layout, conventions, and Always/Never gotchas. CLAUDE.md symlinks to it.
5.4 KiB
5.4 KiB
AGENTS.md
Kid-friendly soccer training tracker PWA for one player ("Gunner"), packaged as a StartOS 0.4.x .s9pk service.
Stack (versions that matter)
- Backend: Node.js (ESM,
"type":"module") + Fastify 5,better-sqlite311,bcryptjs3,@fastify/cookie11,@fastify/static8. No build step. - Frontend: vanilla-JS PWA — no framework, no bundler. Chart.js v4 vendored at
public/vendor/chart.umd.min.js. Service worker atpublic/sw.js. - Packaging (
s9pk/):@start9labs/start-sdk1.5.3 (TypeScript), bundled with@vercel/ncc, packed withstart-cli(0.4.0-beta). Targets StartOS 0.4.x. Image built locally viaDockerfile(Node 22), x86_64 only.
Commands
Run from repo root unless noted.
- Run (dev):
npm run dev(node --watch) ornpm start— listens onPG_PORT(default 3000). Local:PG_PORT=3344 PG_PASSWORD=gunner npm start. Default dev password isgunner(logs a warning). - Seed defaults:
npm run seed(only seeds an empty DB). - Tests: none configured — TODO. Verify manually: boot against a temp DB and hit the API, e.g.
PG_DATA_DIR=/tmp/pg PG_PORT=3399 PG_PASSWORD=gunner node src/server.jsthencurl/login. No single-test runner — TODO. - Lint (root): none configured — TODO.
- Typecheck + format (s9pk):
cd s9pk && npm run check(tsc --noEmit) andnpm run prettier. - Build .s9pk:
cd s9pk && npm ci && make(vendors the app, builds the image, packspremier-gunner_x86_64.s9pk). - Deploy to StartOS:
cd s9pk && make install(installs newest.s9pkto the host in~/.startos/config.yaml). Status reachesinstalledviastart-cli package list.
Directory layout
src/— backend.server.js(Fastify app +/api/*auth gate),config.js(env),db.js(appliesschema.sql+ runs migrations),schema.sql,seed.js,auth.js,routes/{auth,categories,entries,plans,goals,stats}.js.public/— frontend.index.html,login.html,js/{app.js,api.js,dashboard.js},css/styles.css,sw.js,manifest.webmanifest,icons/,vendor/.s9pk/— StartOS package.Dockerfile,Makefile(edit here),s9pk.mk(do not edit),startos/(manifest/,main.ts,interfaces.ts,actions/,fileModels/store.ts,versions/current.ts,i18n/),instructions.md,README.md,TODO.md.s9pk/app/— generated copy of the app made bymake prep; gitignored, do not edit.data/— runtime SQLite (premier-gunner.db); gitignored.
Data model notes
- Metrics live in
category_metrics;kindis one ofcount | duration | score | decimal. Records aretrack_record(bool) +record(REAL) on the metric; bumped automatically when a logged value beats them (respectinghigher_is_better). - Entries: one row per logged session (
entries, withnote); metric readings inentry_values.
Config (env-var names only — never hardcode secrets)
PG_HOST, PG_PORT, PG_DATA_DIR, PG_PASSWORD, PG_PASSWORD_HASH, PG_COOKIE_SECRET, PG_SESSION_DAYS. NODE_ENV=production enables the Secure session cookie (requires HTTPS). On StartOS, PG_PASSWORD is injected from store.json and is authoritative (re-hashed every boot); change it via the "Set Login Password" action.
Conventions
- Commits: imperative subject; body only when the "why" isn't obvious; author is the user, no AI attribution. No
Co-Authored-By/"Generated with" trailers. - Remote: self-hosted Gitea, not GitHub — do not add a GitHub remote. (Repo currently has no remote; branch is
master.) - Match existing file conventions; small reviewable diffs; comments explain why.
- Verify browser-observable changes before shipping (run it, check no console errors).
Always
- Bump
s9pk/startos/versions/current.tsversionon every rebuild that changes anything — StartOS won't register an update otherwise. Code change → bump semver (0.1.6→0.1.7); packaging-only → bump the revision (0.1.6:0→0.1.6:1). - Bump the
CACHEconstant inpublic/sw.jswhenever frontend assets change, so installed PWAs update. - For DB changes, edit
schema.sql(fresh installs) and add an idempotent migration insrc/db.jsguarded by asettingsflag (existing DBs) and updatesrc/seed.js. - Run
cd s9pk && npm run checkafter editingstartos/*.ts. - Keep i18n in sync: every
i18n('x')must be a key instartos/i18n/dictionaries/default.ts, with all indices present fores_ES, de_DE, pl_PL, fr_FRintranslations.ts, ortscfails.
Never
- Never edit
s9pk/s9pk.mk(plumbing) ors9pk/app/(generated). Makefile overrides go above theinclude s9pk.mkline. - Never rely on
schema.sqlalone for changes to existing databases —CREATE TABLE IF NOT EXISTSwon't ALTER; add a migration. - Never build/ship aarch64 — target is x86_64 only (
ARCHES := x86, manifestarch: ['x86_64']). - Never add AI co-authorship trailers to commits; never add a GitHub remote; never force-push or commit to a shared branch unless asked.
- Never commit secrets,
data/,node_modules/, or*.s9pk(all gitignored). Reference env-var names instead.
Gotchas
start-cli(andmake install) needs a git repo with at least one commit — it stamps the build with the git hash.make installpicks the newest*.s9pkby mtime; with x86-only there's just one.- Migrations key off a flag row in the
settingstable (e.g.migr_records_scores); pick a new flag name per migration.