geocrop-platform./apps/nextgen/AGENTS.md

7.3 KiB

AGENTS.md — Africa Alert PWA

Compact orientation for AI coding agents. Update this file when commands, structure, or load-bearing conventions change.

What this repo is

Offline-first PWA school-management system. React 18 + Vite + TypeScript client, Node 20 + Express + SQLite server, bidirectional sync to Supabase, Paynow (Zimbabwe) for fee payments. Deployed as a single Docker container.

Quickstart (local dev, two terminals)

# Terminal 1 — API on :3001
cd server
npm install
npm run db:init        # one-off; creates server/data/school.db
npm run dev

# Terminal 2 — client on :3000 (proxies /api → :3001)
cd client
npm install
npm run dev

Login with admin@school.com / admin123 (other demo accounts in server/src/database/init.js).

For production: docker-compose up --build (ports 3000 + 3001). The Dockerfile in the root is a separate, currently unused multi-stage Nginx build — docker-compose.yml builds and serves from node:20-alpine directly. Reconcile or pick one.

Repository layout (don't deviate)

client/src/
  App.tsx          router, ProtectedRoute, role-based getRoutes()
  main.tsx
  components/      shared UI (Nav, PaynowPayment)
  pages/<role>/    role-specific pages
  pages/dashboard/ role landing pages
  store/           Zustand slices — use client/src/store/api.ts as the axios instance
server/src/
  index.js         Express bootstrap, registers controllers under /api/<x>
  controllers/     one file per resource, inline auth middleware
  services/        SyncEngine.js, AuditService.js
  database/init.js schema source of truth (idempotent CREATE TABLE IF NOT EXISTS)
data/              SQLite file (gitignored, WAL mode → .db-shm + .db-wal alongside)
uploads/           multer uploads (gitignored)
.harness/          team memory (AGENTS.md, docs/conventions.md, reins/, changelogs/)

There is no root package.json. Run npm install and scripts inside client/ and server/.

Hard rules

  • All code changes go in a worktree at .worktrees/<name>/, branch feature/<kebab> or fix/<kebab>, branched from dev. Never edit the main checkout.
  • Branch model is Git Flow. Work and merge on dev. Promote to main only when dev is green and deployable. No direct commits to main.
  • Single axios instance lives at client/src/store/api.ts. Don't create a second one in a store or component.
  • All tables must have uid TEXT UNIQUE, last_synced_at, sync_status CHECK in ('synced','pending','conflict') DEFAULT 'pending', is_deleted INTEGER DEFAULT 0. Add to init.js and append the table name to tablesToSync in SyncEngine.js (in FK dependency order — parents first).
  • Route gating is done in App.tsx via <ProtectedRoute allowedRoles={…}> — do not gate inside page components.
  • Demo accounts are seeded in server/src/database/init.js. Don't add new ones in a migration; update init.js.
  • .env is gitignored. Never commit secrets, never paste .env contents into chat. The repo's actual remote is Gitea (git.techarvest.co.zw), not GitHub.

Commands cheat sheet

What Command Where
Install deps npm install client/ and server/ separately
Dev server (client) npm run dev client/ — Vite, port 3000, proxies /api → :3001
Dev server (server) npm run dev server/ — nodemon, port 3001
Init / migrate DB npm run db:init server/ — runs src/database/init.js
Production build npm run build client/ — outputs client/dist/, generates the PWA service worker
Preview build npm run preview client/
Full stack (prod-like) docker-compose up --build repo root
Stop stack docker-compose down repo root
Lint / typecheck not configured n/a — see Open follow-ups
E2E tests (Playwright) npm run test:e2e client/ — Playwright config + e2e/*.spec.ts; needs both client (3000) and server (3001) running; first run also: npx playwright install chromium

npm run build (not npm run dev) is required to exercise the PWA service worker — vite-plugin-pwa only ships the SW in production builds.

Canonical reference for new features

The exams module is the vertical slice to mimic: server/src/controllers/exams.controller.js, client/src/store/exams.ts, client/src/pages/exams/, route + nav entry in App.tsx. See IMPLEMENTATION_SUMMARY.md for the design notes.

Things that will trip you up

  • Hardcoded JWT secret 'africa-alert-secret-key-2024' is the fallback in server/src/index.js and duplicated across controllers. Set JWT_SECRET env var in any non-dev environment.
  • CORS is wide open (app.use(cors()) in server/src/index.js). Don't add more routes without a CORS review.
  • outputs/ and logo/ at the repo root are unused build artifacts — don't import from them. Real brand assets live in client/public/.
  • Sync engine uses raw http/https, not fetch or axios. 10s timeout, 100 rows/table push, 50/table delete, server-wins conflict, 30s default interval. SUPABASE_KEY empty → sync no-ops, app keeps working.
  • Paynow integration in server/src/controllers/payments.controller.js. Webhook is idempotent. Payment + student_fees.status update wrapped in db.transaction().
  • Auth is JWT only (7-day expiry). No session cookies, no refresh tokens. Logout is client-side only (clears Zustand store).
  • Roles in active UI: school_admin, systems_admin, principal, hr, bursar, teacher, student, parent, librarian, clubs_head. Schema also defines accountant and nurse but those have no UI.
  • index.js exposes module.exports = app AND starts the server with app.listen. Importing it in tests will bind a port — use a separate bootstrap or guard the listen call.

Where to read more

  • .harness/AGENTS.md — project-level memory (demo accounts, branch model, "exams" as canonical reference).
  • .harness/docs/conventions.md — SQL contract, controller/store templates, auth+RBAC, sync contract, Paynow flow, env vars.
  • .harness/docs/testing.md — test stack and manual recipes (when set up).
  • .harness/reins/ — agent role definitions (backend-expert, frontend-expert, sync-expert, tester, etc.).
  • IMPLEMENTATION_SUMMARY.md — modules and their tables; rationale for sync engine.
  • DATABASE_SCHEMA.md — full schema reference.
  • SCREENS.md — UI map and role/permission matrix (canonical for screen-level access).
  • GEMINI.md — high-level overview (older, points here for details).

Open follow-ups (do not silently take these on — ask first)

  • No test framework is installed or configured anywhere. The tester rein owns adding Vitest/Jest/Playwright.
  • No CI — no GitHub Actions, no Gitea Actions workflow. Add when the user asks.
  • Schema is CREATE TABLE IF NOT EXISTS only in init.js — no migration framework. Schema changes that require ALTER are blocked until a migration tool lands.
  • No lint or typecheck script in either package.json. tsconfig.json has "strict": false — the client typechecks leniently.
  • Dockerfile and docker-compose.yml are divergent. Pick one deploy story.
  • JWT secret, CORS, request-size limit (express.json({ limit: '50mb' })) are all loose. Don't relax further; tighten when touching the area.