# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash npm run build # Compile TypeScript → dist/ npm run start # Build and start (tsc && node ./dist/app.js) npm run debug # Start with DEBUG=* environment variable npm run test # Run Jest tests with coverage (outputs sonar-report.xml) ``` Run a single test file: ```bash npx jest test/some.test.ts ``` ## Architecture Express.js REST API in TypeScript with a service-oriented layering. The sole domain is `Calendar`, which organises **events** and **users**. **Request path:** 1. `app.ts` mounts `Calendar.router.ts` at `/calendar` 2. `Calendar.router.ts` delegates to `events.router.ts` and `users.router.ts` 3. Routers call services; services call the MariaDB pool in `Calendar.db.ts` **Key layers:** | Layer | Location | |---|---| | Router | `src/models/calendar/Calendar.router.ts`, `…/events/events.router.ts`, `…/users/users.router.ts` | | Services | `…/events/events.service.ts`, `…/users/users.service.ts`, `…/events/credentials.service.ts`, `…/events/icalgenerator.service.ts` | | DB pool | `src/models/calendar/Calendar.db.ts` (MariaDB, pool size 5) | | Shared | `src/common/` (base route class, nodemailer wrapper), `src/middleware/logger.ts` (Winston) | **Auth model:** Users must have a `@nachklang.art` email. After activation they receive a session token (30-day window); the token hash + IP are stored in the DB. Credentials for non-user calendar access (`MEMBER_CREDENTIAL`, `CHOIR_CREDENTIAL`, `MANAGEMENT_CREDENTIAL`) come from `.env`. **Event versioning:** Events have a companion `event_versions` table. `events.service.ts` manages writes to both. **Calendar types and IDs:** `public` (1), `members` (2), `management` (3), `choir` (4), `birthdays` (5). `credentials.service.ts` enforces which session/credential can read each calendar. **iCal export:** `icalgenerator.service.ts` converts DB events to RFC 5545 format; reachable via `GET /calendar/events/{calendar}/ical`. **API docs:** Swagger UI served at `/docs`, generated from JSDoc annotations in the router files. ## Environment Copy `.env.example` (or create `.env`) with: ``` PORT= DB_HOST= DB_USER= DB_PASSWORD= CALENDAR_DB= EMAIL_HOST= EMAIL_USERNAME= EMAIL_PASSWORD= MEMBER_CREDENTIAL= CHOIR_CREDENTIAL= MANAGEMENT_CREDENTIAL= ``` ## TypeScript config Strict mode enabled, target ES2016, compiled output in `./dist`, inline source maps. Tests run through `ts-jest` directly against `.ts` sources.