3fb7a47469
Cross-repo git-hygiene audit remediation: surface ~/Projects/standards/INBOX.md items at session start, and switch .gitignore to the deny-by-default .claude/* block (shared wiring allow-listed) plus the canonical secrets/env lines — per standards/portability.md.
81 lines
6.9 KiB
Markdown
81 lines
6.9 KiB
Markdown
# AGENTS.md
|
|
|
|
Kid-friendly soccer training tracker PWA for one player ("Gunner"), packaged as a StartOS 0.4.x `.s9pk` service.
|
|
|
|
> **Inbox check:** At session start, if `~/Projects/standards/INBOX.md` exists, scan it for
|
|
> items tagged `(premier-gunner)` and surface them before proposing next steps; triage with `/triage`.
|
|
|
|
## 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.
|