Files
premier-gunner/AGENTS.md
T
Keysat 5628bab5b6 Add AGENTS.md with CLAUDE.md symlink
Repo-root guide for coding agents: stack, commands, layout,
conventions, and Always/Never gotchas. CLAUDE.md symlinks to it.
2026-06-13 14:44:17 -05:00

68 lines
5.4 KiB
Markdown

# 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-sqlite3` 11, `bcryptjs` 3, `@fastify/cookie` 11, `@fastify/static` 8. No build step.
- **Frontend**: vanilla-JS PWA — no framework, no bundler. Chart.js v4 vendored at `public/vendor/chart.umd.min.js`. Service worker at `public/sw.js`.
- **Packaging** (`s9pk/`): `@start9labs/start-sdk` 1.5.3 (TypeScript), bundled with `@vercel/ncc`, packed with `start-cli` (0.4.0-beta). Targets StartOS **0.4.x**. Image built locally via `Dockerfile` (Node 22), **x86_64 only**.
## Commands
Run from repo root unless noted.
- **Run (dev)**: `npm run dev` (node --watch) or `npm start` — listens on `PG_PORT` (default 3000). Local: `PG_PORT=3344 PG_PASSWORD=gunner npm start`. Default dev password is `gunner` (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.js` then `curl`/login. No single-test runner — TODO.
- **Lint (root)**: none configured — TODO.
- **Typecheck + format (s9pk)**: `cd s9pk && npm run check` (tsc --noEmit) and `npm run prettier`.
- **Build .s9pk**: `cd s9pk && npm ci && make` (vendors the app, builds the image, packs `premier-gunner_x86_64.s9pk`).
- **Deploy to StartOS**: `cd s9pk && make install` (installs newest `.s9pk` to the host in `~/.startos/config.yaml`). Status reaches `installed` via `start-cli package list`.
## Directory layout
- `src/` — backend. `server.js` (Fastify app + `/api/*` auth gate), `config.js` (env), `db.js` (applies `schema.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 by `make prep`; **gitignored, do not edit**.
- `data/` — runtime SQLite (`premier-gunner.db`); gitignored.
## Data model notes
- Metrics live in `category_metrics`; `kind` is one of `count | duration | score | decimal`. Records are `track_record` (bool) + `record` (REAL) on the metric; bumped automatically when a logged value beats them (respecting `higher_is_better`).
- Entries: one row per logged session (`entries`, with `note`); metric readings in `entry_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.ts` `version` on 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 `CACHE` constant in `public/sw.js`** whenever frontend assets change, so installed PWAs update.
- For DB changes, edit `schema.sql` (fresh installs) **and** add an idempotent migration in `src/db.js` guarded by a `settings` flag (existing DBs) **and** update `src/seed.js`.
- Run `cd s9pk && npm run check` after editing `startos/*.ts`.
- Keep i18n in sync: every `i18n('x')` must be a key in `startos/i18n/dictionaries/default.ts`, with all indices present for `es_ES, de_DE, pl_PL, fr_FR` in `translations.ts`, or `tsc` fails.
## Never
- Never edit `s9pk/s9pk.mk` (plumbing) or `s9pk/app/` (generated). Makefile overrides go **above** the `include s9pk.mk` line.
- Never rely on `schema.sql` alone for changes to existing databases — `CREATE TABLE IF NOT EXISTS` won't ALTER; add a migration.
- Never build/ship aarch64 — target is x86_64 only (`ARCHES := x86`, manifest `arch: ['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` (and `make install`) needs a git repo with at least one commit — it stamps the build with the git hash.
- `make install` picks the newest `*.s9pk` by mtime; with x86-only there's just one.
- Migrations key off a flag row in the `settings` table (e.g. `migr_records_scores`); pick a new flag name per migration.