121 lines
3.7 KiB
Markdown
121 lines
3.7 KiB
Markdown
# Architektur
|
|
|
|
Das Repository ist ein modularer Monolith mit getrennten Workspaces fuer
|
|
Frontend, Backend und API-Client. Ausgeliefert wird eine einzelne Node.js-App,
|
|
die die gebaute Angular-Anwendung statisch mitliefert.
|
|
|
|
## Workspaces
|
|
|
|
```text
|
|
apps/frontend
|
|
apps/backend
|
|
packages/api-client
|
|
```
|
|
|
|
Es wird bewusst kein Nx eingesetzt. Workspace-Grenzen bleiben durch npm-Scripts,
|
|
TypeScript-Projekte und klare Importpfade nachvollziehbar.
|
|
|
|
## Backend
|
|
|
|
Das Backend liegt in `apps/backend` und basiert auf NestJS. Es ist nach Features
|
|
geschnitten:
|
|
|
|
- `auth`: OIDC Login, Callback, Logout und Authentifizierung
|
|
- `sessions`: serverseitige Sessions, CSRF-Token und Session-Listen
|
|
- `roles`: Code-definierte Permissions und rollenbasierte Rechteverwaltung
|
|
- `users`: lokale Benutzerprofile und Einstellungen
|
|
- `items`: Beispiel-Fachmodul
|
|
- `audit`: Audit-Log fuer administrative Nachvollziehbarkeit
|
|
- `health`: Liveness- und Readiness-Endpunkte
|
|
- `database`: TypeORM-Konfiguration, Entities und Migrationen
|
|
- `common`: Fehlerformat, Request Context, Validierung und HTTP-Helfer
|
|
|
|
Controller enthalten keine Datenbanklogik. Sie validieren den HTTP-Rand,
|
|
deklarieren Permissions und delegieren an Services. Services enthalten
|
|
Fachlogik. Datenbankzugriffe laufen ueber Repository-Klassen oder klar benannte
|
|
Persistence-Services.
|
|
|
|
Globale Backend-Bausteine:
|
|
|
|
- `ApiExceptionFilter` normalisiert Fehlerantworten.
|
|
- `ThrottlerGuard` setzt Rate Limits.
|
|
- `CsrfGuard` schuetzt schreibende Requests.
|
|
- `PermissionsGuard` prueft Rollen und Permissions.
|
|
- `RequestIdMiddleware` setzt Request-Korrelation.
|
|
- `helmet` setzt Security Header.
|
|
- `pino-http` loggt mit Redaction fuer Cookies, Tokens und Secrets.
|
|
|
|
## Frontend
|
|
|
|
Das Frontend liegt in `apps/frontend` und nutzt Angular Standalone Components.
|
|
Der Shell-Aufbau steckt in `src/app/layout/app-shell.ts`. Feature-Seiten liegen
|
|
unter `src/app/features`.
|
|
|
|
Design- und Implementierungsregeln:
|
|
|
|
- mobile-first HTML und SCSS
|
|
- keine UI-Komponentenbibliothek
|
|
- Signals fuer lokalen UI-State
|
|
- RxJS fuer HTTP- und API-Flows
|
|
- Angular Permissions nur fuer Darstellung und Navigation, nicht als
|
|
Sicherheitsgrenze
|
|
|
|
Der `permissionGuard` verhindert unpassende Navigation im Frontend. Die
|
|
verbindliche Autorisierung findet immer im Backend statt.
|
|
|
|
## API-Client
|
|
|
|
`packages/api-client` enthaelt den vom Frontend genutzten Angular-Service und die
|
|
DTO-Typen. Der Code ist als generiert markiert. Er wird mit folgendem Befehl neu
|
|
geschrieben:
|
|
|
|
```bash
|
|
npm run api:generate
|
|
```
|
|
|
|
Der Produktionsbuild ruft diesen Schritt vor Backend- und Frontend-Builds auf.
|
|
Bei API-Aenderungen muss der Generator synchron zur Backend-API angepasst werden.
|
|
|
|
## Runtime-Aufbau
|
|
|
|
Im Produktionsbuild entsteht:
|
|
|
|
```text
|
|
apps/backend/dist/main.js
|
|
apps/backend/dist/public/index.html
|
|
apps/backend/dist/public/assets...
|
|
```
|
|
|
|
NestJS liefert:
|
|
|
|
- `/api/*` als JSON API
|
|
- `/api/docs` als Swagger UI, wenn aktiviert
|
|
- `/health/live` fuer Liveness
|
|
- `/health/ready` fuer Readiness inklusive Datenbank- und Migrationspruefung
|
|
- alle anderen Pfade als Angular SPA Fallback
|
|
|
|
## Datenmodell und Migrationen
|
|
|
|
TypeORM laeuft mit:
|
|
|
|
- `synchronize: false`
|
|
- `migrationsRun: false`
|
|
- expliziten Migrationen unter `apps/backend/src/database/migrations`
|
|
|
|
Der normale App-Start fuehrt keine Migrationen aus. Stattdessen prueft
|
|
`MigrationHealthService`, ob Migrationen fehlen. Dadurch wird verhindert, dass
|
|
ein App-Rollout unbemerkt ein Schema veraendert.
|
|
|
|
## Autorisierung
|
|
|
|
Permissions werden in `apps/backend/src/roles/permissions.ts` definiert. Rollen
|
|
sind Datenbankdaten, Benutzer erhalten Permissions nur ueber Rollen.
|
|
|
|
Systemrollen:
|
|
|
|
- `admin`: alle Permissions
|
|
- `user`: Basisrechte fuer Items-Lesen und eigene Sessions
|
|
|
|
Der erste erfolgreich angemeldete Benutzer wird automatisch Admin. Danach
|
|
erhalten neue Benutzer initial die Rolle `user`.
|