Imported from kernoeb/PlanningSup (
AGENTS.md). Install upstream withnpx skills add kernoeb/PlanningSup. Copyright stays with the author.
PlanningSup (AGENTS)
Uni calendar PWA + API (ICS→events) with offline + auth prefs sync.
Fast (root)
- Setup:
bun install - API env:
cp apps/api/.env.example apps/api/.env(needsDATABASE_URL) - Dev:
bun dev - Quality:
bun run lint-fix && bun run lint && bun run typecheck && bun run test:unit - Docker smoke:
bun run docker:build(Dockerfile runs lint/typecheck/build/test:unit) - Integration:
bun run test:integration[:local]/bun run test:integration:auth(20001) - E2E:
bun run test:e2e[:safari|:headed|:debug] - DB/auth changed:
cd apps/api && bun run generate-drizzle && bun run generate-better-auth - Release:
bun run release <patch|minor|major>(must be onmain, clean tree; then ask user togit push --follow-tags)
Workspaces / Bun
- Workspaces:
apps/*,packages/*,test. - Root scripts fan-out via
scripts/run.ts(excludesapps/app,apps/extension). - Per-workspace:
cd <workspace> && bun run <script>(needed forapps/extension). - No colon-namespaced commands:
bun run typecheck:web,bun run lint:web, etc. do NOT exist. Usecd apps/web && bun run typecheckinstead. - Use Bun only;
.bun-version+bun.lock;bunx --bun <cli>;bun run <script> -- <flags>. - Tests:
bun testfor*.test.ts; Playwright fortest/e2e/*.spec.ts. - End-to-end typed API: use Eden treaty client
packages/libs/src/client/index.ts(client.api.*), avoid ad-hocfetch('/api/...').
CI / Docker / ports
- Workflows:
.github/workflows/docker-publish.yml,.github/workflows/extension-build.yml; validate:bun run validate:workflows. docker-publish.yml: build→integration (auth off/on)→optional e2e on UI changes→publish only on whitelist branches orvX.Y.Z(no fork PR publish).- DB: Postgres (Docker Compose).
- Ports:
api=20000 web=4444 pg=5432 testpg=5433 auth=20001 authpg=5434.
Key paths
- Orchestrators:
scripts/run.ts,scripts/test*.ts,scripts/validate-workflows.ts - API:
apps/api/src/**,apps/api/drizzle.config.ts,apps/api/drizzle/*.sql - Auth/prefs sync:
apps/web/src/composables/useUserPrefsSync.ts↔apps/api/src/utils/auth.ts↔apps/api/src/db/schemas/auth.ts - Web:
apps/web/src/**,apps/web/vite.config.* - Extension:
apps/extension/** - Shared:
packages/libs/**,packages/config/** - Data:
resources/plannings/*.json(schema checked bytest/plannings.schema.test.ts; live URLs viabun scripts/check-plannings-urls.ts [--only <file>] [--fix],--fixrepairs a rolled-over ADEprojectId) - Generate plannings, per timetable system:
- ADE 7 portal (Rennes):
bun scripts/ade-portal-generator.ts --listthen--branch <name>, headless via the portal REST API - Celcat webpub (Nantes):
bun scripts/celcat-generator.ts --url https://edt.univ-nantes.fr/<site> --title <t> --out <file> - ADE 6 (UBS, Lyon 1, INSA, Brest, Artois):
scripts/browser.jsin the browser console, thenscripts/shu-generator.js
- ADE 7 portal (Rennes):
- Tests:
test/*.test.ts,test/integration/*.test.ts,test/e2e/*.spec.ts
API notes (bun:sql + Drizzle)
- DB:
import { SQL } from 'bun'+drizzle-orm/bun-sql;db.execute(...) => Row[]. - Prefer Drizzle query builder; use raw SQL only when needed (PG-specific/atomic patterns).
- Migrations on boot unless
NO_MIGRATE_DATABASE=true. refreshedAt: network=Date.now(); db=plannings_backup.updated_at./api/ops/plannings:x-ops-tokenmust matchOPS_TOKEN(prod: 404 if missing/invalid).- Jobs:
RUN_JOBS=false,ALLOWED_JOBS,JOBS_QUIET_HOURS*. - Routes (current):
/api/ping,/api/plannings,/api/plannings/:fullId?events=true[&onlyDb=true],/api/ops/plannings,/api/auth/*,/api/auth/auto-redirect/:provider,/config.js.