# tOS – Claude Code Guide ## Projekt Enterprise Web Operating System: Next.js 14 + NestJS 10 + Prisma + PostgreSQL 16 + Keycloak 24. pnpm-Monorepo mit Turbo (`apps/web`, `apps/api`, `packages/shared`). ## Dev-Befehle ```bash # Infrastruktur starten (PostgreSQL, Redis, Keycloak) cd docker && docker compose up -d # Apps starten pnpm dev # alle Apps pnpm dev:api # nur Backend pnpm dev:web # nur Frontend # Datenbank pnpm db:push # Schema anwenden (dev) pnpm db:seed # Default-Daten (Rollen, SystemSettings) # TypeScript-Check pnpm --filter @tos/api exec tsc --noEmit pnpm --filter @tos/web exec tsc --noEmit ``` ## Ports | Service | Port | |------------|------| | Frontend | 3000 | | Backend | 3001 | | Keycloak | 8080 | | PostgreSQL | 5432 | | Redis | 6379 | ## Datenbanken - `tos_db` – Keycloak (wird automatisch erstellt) - `tos_app` – Anwendung (wird via `docker/postgres/init.sql` automatisch erstellt) - Beide in derselben PostgreSQL-Instanz ## Keycloak (Dev) - Admin-UI: http://localhost:8080 → admin / admin123 - Realm: `tOS` - Frontend-Client: `tos-nextauth` (NextAuth) - Backend-Client: `tos-backend` (NestJS) ## Architektur **Auth:** - Keycloak SSO → NextAuth (Frontend-Session) + passport-jwt RS256 via JWKS (Backend) - JWT wird über Keycloak JWKS-Endpoint validiert – KEIN symmetrischer JWT_SECRET - Global Guard Chain: JWT → Roles → Permissions, `@Public()` für opt-out **API-Kommunikation:** - Backend wickelt alle Responses in `{success, data, timestamp}` (TransformInterceptor) - Frontend-`api.ts` unwrappt diesen Envelope automatisch - `NEXT_PUBLIC_API_URL` enthält bereits `/api/v1` (z.B. `http://localhost:3001/api/v1`) **Konfiguration:** - Integration-Credentials und SystemSettings liegen in der DB, nicht in `.env` - `.env` enthält nur Bootstrap-Variablen (DB-URL, Secrets, Keycloak-Koordinaten) ## Code-Konventionen - **Route-Pattern:** `page.tsx` (Server Component) importiert `*-content.tsx` (Client Component) - **Routen:** `[locale]/(auth)/...` = geschützt, `[locale]/(setup)/...` = public, `/login` = public - **State:** Zustand für UI-State, TanStack Query für Server-State - **i18n:** ASCII-Umlaute in JSON-Keys (`oe`, `ae`, `ue` statt `ö`, `ä`, `ü`) - **Installer-API-Calls:** direktes `fetch()` mit `x-setup-token` Header (kein Bearer-Token) ## Deployment ```bash # Lokaler Full-Stack-Test (identisch zu Prod, vor Commit) cd docker && docker compose -f docker-compose.local.yml up --build # → http://localhost:3000/setup?token=local-setup-token-for-testing # Produktions-Installation (interaktiv) ./install.sh # → fragt Domain + SSL-Modus, generiert Secrets, startet docker-compose.prod.yml # → SSL via Let's Encrypt (Caddy, --profile ssl) oder externer Reverse Proxy ``` ## Bekannte Issues / TODOs - HR-Hooks nutzen noch Mock-Daten (nicht an Backend angebunden) - Morning Meeting Endpoints nutzen `DASHBOARD_VIEW` Permission (Security-Gap) - `apps/api/integrations.backup/` – deaktivierte Integrations-Module (via .gitignore ignoriert)