- Multi-stage Dockerfiles for API (NestJS) and Web (Next.js standalone)
- docker-compose.prod.yml: full production stack (postgres, redis, keycloak,
api, web) with optional Caddy/Let's Encrypt via --profile ssl
- docker-compose.local.yml: identical local test stack, all ports exposed
- docker/postgres/init.sql: auto-creates tos_app DB on first start
- Caddyfile: reverse proxy for app domain + auth subdomain
- install.sh: interactive installer (domain, SSL mode, secret generation)
- NestJS SetupModule: @Public() endpoints for /setup/status, /setup/admin,
/setup/branding, /setup/complete with setup-token guard
- Web installer: 4-step flow (system check, admin creation, branding, complete)
at /[locale]/setup/* with public middleware bypass
- i18n: installer namespace added to de.json and en.json
- CORS: x-setup-token header allowed in main.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the top-level "Integrationen" sidebar entry and add an "Uebersicht"
tab to the admin integrations page with summary stats and integration cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded .env configuration with database-backed settings
manageable through the Admin web interface. This reduces .env to
bootstrap-only variables (DB, Keycloak, encryption keys).
Backend:
- Add SystemSetting Prisma model with category, valueType, isSecret
- Add system-settings NestJS module (CRUD, 60s cache, encryption)
- Refactor all 7 connectors to lazy-load credentials from DB via
CredentialsService.findActiveByType() instead of ConfigService
- Add event-driven credential reload (@nestjs/event-emitter)
- Dynamic CORS origins and conditional Swagger from DB settings
- Fix JWT strategy: use Keycloak JWKS (RS256) instead of symmetric secret
- Add SYSTEM_SETTINGS_VIEW/MANAGE permissions
- Seed 13 default settings (sync intervals, features, branding, CORS)
- Add env-to-db migration script (prisma/migrate-env-to-db.ts)
Frontend:
- Add use-credentials hook (full CRUD for integration credentials)
- Add use-system-settings hook (read/update system settings)
- Wire admin-integrations page to real API (create/update/test/toggle)
- Add admin system-settings page with 4 tabs (Branding, CORS, Sync, Features)
- Fix sidebar double-highlighting with exactMatch flag
- Fix integration detail fallback when API unavailable
- Fix API client to unwrap backend's {success, data} envelope
- Update NEXT_PUBLIC_API_URL to include /v1 version prefix
- Fix activity-widget hydration error
- Add i18n keys for systemSettings (de + en)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Since tOS uses Keycloak as sole auth provider, the intermediate
login page with the manual "Mit Keycloak anmelden" button was
unnecessary. Now unauthenticated users are redirected directly
to Keycloak. The error UI with retry button is preserved for
failed auth attempts (expired session, unauthorized).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Skill Matrix: use correct nested key `skillMatrix.title` instead of
`skillMatrix` which resolved to the full object
- Skill Matrix: use `skillMatrix.trend.label` instead of
`skillMatrix.trend` which resolved to the trend object
- Integrations: rename duplicate `title` key to `documentTitle` in
de.json/en.json to prevent the ecoDMS column header from overriding
the page title ("Titel" instead of "Integrationen")
- Shared package: move `types` condition before `import`/`require` in
exports field to fix TypeScript type resolution
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>