Files
premier-gunner/AGENTS.md
T
Keysat 9f9358d64b Document current state and roadmap
- AGENTS.md: add Current state section; record Gitea origin; scrub the
  dev password example to a placeholder and the deploy host to a config
  reference.
- Add ROADMAP.md for longer-term backlog and deferred decisions.
2026-06-13 15:00:20 -05:00

78 lines
6.7 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=<dev-password> npm start`. If `PG_PASSWORD` is unset, the app uses a built-in dev fallback and logs a warning — set it explicitly.
- **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=<dev-password> 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 — `origin` is configured in `.git/config` (an SSH URL; keep it out of tracked files). Do not add a GitHub remote. Branch is `master`; push after committing.
- 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.
## Current state
Live on StartOS (deploy host set in `~/.startos/config.yaml` `host:`, not in this repo) at **v0.1.6:0**; `make install` deploys and the PWA self-updates via the in-app banner. Pushed to self-hosted Gitea (`origin`).
- **Working**: daily logging, weekly planning, goals + thermometer, dashboard (streak calendar, radar, line/series charts, records), personal-best records (auto + manual set), per-session notes, EPA Max/Weighted Speed, tap-to-type number fields, full category/metric management in Settings, "Set Login Password" action.
- **In progress**: none — all requested features are built, committed, and deployed.
- **Decided, not yet done**: reconcile in-app password change with the StartOS action (env wins on restart); optional "log another" for a second same-category session in a day. See `ROADMAP.md`.
- **Known issues**: changing the password from the app's own Settings reverts on restart under StartOS — use the action.
- **Next steps**: (1) set a real login password via the "Set Login Password" action; (2) confirm speed unit (`mph` vs `km/h`); (3) decide whether to add a "log another" same-category session.