Files
teOS/apps/api/src/app.module.ts
Flexomatic81 0e8d5aef85 feat: add Docker deployment, web installer, and local test environment
- 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>
2026-02-23 21:17:34 +01:00

111 lines
3.3 KiB
TypeScript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { PrismaModule } from './prisma/prisma.module';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { HealthModule } from './health/health.module';
import { CommonModule } from './common/common.module';
import { JwtAuthGuard } from './auth/guards/jwt-auth.guard';
import { RolesGuard } from './auth/guards/roles.guard';
import { PermissionsGuard } from './auth/permissions/permissions.guard';
import { configValidationSchema } from './config/config.validation';
// Feature modules
import { AuditModule } from './modules/audit/audit.module';
import { AuditInterceptor } from './modules/audit/audit.interceptor';
import { DashboardModule } from './modules/dashboard/dashboard.module';
import { DepartmentsModule } from './modules/departments/departments.module';
import { UserPreferencesModule } from './modules/user-preferences/user-preferences.module';
// Phase 1 modules - System Settings
import { SystemSettingsModule } from './modules/system-settings/system-settings.module';
// Phase 4 modules - LEAN
import { LeanModule } from './modules/lean/lean.module';
// Phase 5 modules - HR
import { HrModule } from './modules/hr/hr.module';
// Phase 6 modules - Integrations
import { IntegrationsModule } from './modules/integrations/integrations.module';
// Setup module - initial system configuration wizard
import { SetupModule } from './modules/setup/setup.module';
@Module({
imports: [
// Configuration
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env.local', '.env'],
validationSchema: configValidationSchema,
validationOptions: {
allowUnknown: true,
abortEarly: false,
},
}),
// Event emitter for decoupled inter-module communication
EventEmitterModule.forRoot(),
// Database
PrismaModule,
// Common utilities
CommonModule,
// Feature modules
AuthModule,
UsersModule,
HealthModule,
// Phase 1 - System Settings (database-backed configuration)
SystemSettingsModule,
// Phase 2 modules
AuditModule,
DashboardModule,
DepartmentsModule,
UserPreferencesModule,
// Phase 4 modules - LEAN
LeanModule,
// Phase 5 modules - HR
HrModule,
// Phase 6 modules - Integrations
IntegrationsModule,
// Setup wizard - initial system configuration
SetupModule,
],
providers: [
// Global JWT Guard - routes are protected by default
// Use @Public() decorator to make routes accessible without authentication
{
provide: APP_GUARD,
useClass: JwtAuthGuard,
},
// Global Roles Guard - checks @Roles() decorator on routes
// Must be registered after JwtAuthGuard to ensure user is authenticated first
{
provide: APP_GUARD,
useClass: RolesGuard,
},
// Global Permissions Guard - checks @RequirePermissions() decorator
{
provide: APP_GUARD,
useClass: PermissionsGuard,
},
// Global Audit Interceptor - logs actions marked with @AuditLog()
{
provide: APP_INTERCEPTOR,
useClass: AuditInterceptor,
},
],
})
export class AppModule {}