docs: add CLAUDE.md with project conventions and dev workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
86
CLAUDE.md
Normal file
86
CLAUDE.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# 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)
|
||||||
Reference in New Issue
Block a user