Files
ahp 5b9b2a16e6 docs: add product overview and engineering documentation
Document architecture, security, deployment, and development for contributors.
2026-10-07 19:40:26 +03:30

2.1 KiB

Development

Prerequisites

  • Docker + Compose
  • Go (aligned with the backend Dockerfile; currently 1.27-alpine)
  • Node 22+ / bun for the frontend (image builds use npm ci)
  • Optional: k3s, Helm 3/4, kubectl, ffmpeg (only to regenerate the sample video)
cp .env.example .env
# Fill POSTGRES_PASSWORD, REDIS_PASSWORD, RUSTFS_*, JWT_SECRET, ADMIN_PASSWORD
./scripts/compose-dev.sh up -d --build

Equivalent:

docker compose -f deploy/compose/compose.yaml -f deploy/compose/compose.dev.yaml --env-file .env up -d --build

The root docker-compose.yml includes the same pair.

For UI iteration without rebuilding the image, run bun run dev inside frontend/ and keep PUBLIC_URL / FRONTEND_ORIGINS aligned; the standard path is still behind Traefik.

Code structure

  • Copy naming and patterns from sibling files; do not invent new top-level folders without agreement.
  • Backend tests use Go testing; frontend typechecks with tsc.
  • Frontend calls the API mainly via http / @/lib/api.

Tests

# With Postgres/Redis available (compose) and a correct REDIS_URL
cd backend
export GOTMPDIR="${GOTMPDIR:-$HOME/.cache/go-tmp}"
go test ./internal/config/ -count=1
go test ./internal/api/ -count=1
# or filter:
go test ./internal/api/ -count=1 -run 'TestPasswordRecovery|TestSessionCookie|TestAdminEvent'

cd ../frontend
bunx tsc --noEmit

Note: if Redis has a password, build REDIS_URL=redis://:${REDIS_PASSWORD}@localhost:6379 from .env.

Seed and sample video

  • SEED_CURRICULUM=true seeds curriculum/events at startup.
  • backend/media/sample.mp4 is tracked in git; the Docker image copies it; startup PutObjects if the key is missing.
  • Regenerate a corrupted file with ./scripts/regenerate-sample-mp4.sh (needs ffmpeg; not a runtime dependency).

UI error contract

  • Empty list ≠ network error: show error UI + retry.
  • Mutations: toUserError.
  • Player: no infinite skeleton; explicit error state.

Fonts

  • Persian body: Vazirmatn FD (Persian digits)
  • Latin fields (password, username, captcha): regular Vazirmatn / font-latin