diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..54807b1 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,27 @@ +# AGENTS.md + +Bun workspaces monorepo: `apps/backend` (Elysia API on port 3000) + `apps/frontend` (Solid.js/Vite/PWA app on port 5173). `packages/` is empty; the frontend is the primary app. + +## Commands + +- `bun install` (root) — install all workspaces +- `bun run dev` — start backend + frontend together + - `bun --filter backend dev` / `bun --filter frontend dev` for one side +- Typecheck/build frontend: `bun --filter frontend build` (`tsc -b && vite build`) +- No test suite exists: backend `test` script is a stub that exits 1; frontend has no tests + +## Gotchas + +- Readme at repo root is stale `bun init` boilerplate (`bun run index.ts` does not exist); the real entrypoints are `apps/backend/src/index.ts` and `apps/frontend/src/index.tsx` +- Frontend calls `/api/v1/...`; Vite dev proxy adds the strip of `/api` before forwarding to `localhost:3000`. Backend routes live under `/v1/...` with NO `/api` prefix. Don't add `/api` to backend routes or drop it from frontend fetches +- Backend `apps/backend/src/index.ts:3` hardcodes `isDev = true`, which switches ID encoding between `utf8` and `base64url` for opaque `sportsmanager::` IDs — decode/encode must both use the same format; change it deliberately, not accidentally +- Frontend is Solid.js (`jsxImportSource: solid-js`), not React — no hooks, no `useState`; use `createSignal` / `createStore` (see `src/stores/matchStore.ts`) +- `matchStore.loadMatch` merges the stats payload into the same match record via `patchMatch`; the shape of `Match` is intentionally loose (`[key: string]: unknown`) +- PWA (`@serwist/*`) is in `apps/frontend/package.json` but NOT wired into `vite.config.ts` — Serwist service worker is currently inactive +- `apps/backend/package.json` has a stale `"module": "src/index.js"` field; the actual file is `src/index.ts` + +## Conventions + +- No lint/CI/prettier config is set up (prettier is only a root devDependency with no config file) — don't assume a formatter style +- Backend data comes from external German table-tennis/sportsmanager APIs (domains listed at the bottom of `apps/backend/src/index.ts`); responses are in German and field names are the raw API's (e.g. `heim_punkte`, `gast_name`) +- Team/match/event IDs are derived (encoded), not raw — compute IDs via the `Sportsmanager.id()` helper rather than hardcoding