Files
teOS/apps/api/src/modules/system-settings/dto/update-setting.dto.ts
Flexomatic81 6a8265d3dc feat: move configuration from .env to DB with Admin UI management
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>
2026-02-23 20:07:39 +01:00

54 lines
1.4 KiB
TypeScript

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsOptional, IsBoolean } from 'class-validator';
export class UpdateSettingDto {
@ApiProperty({ description: 'The setting value (always stored as string)' })
@IsString()
value: string;
@ApiPropertyOptional({ description: 'Human-readable description of the setting' })
@IsString()
@IsOptional()
description?: string;
@ApiPropertyOptional({
description: 'Value type for parsing: string, number, boolean, json',
enum: ['string', 'number', 'boolean', 'json'],
})
@IsString()
@IsOptional()
valueType?: string;
@ApiPropertyOptional({ description: 'Whether the value should be encrypted at rest' })
@IsBoolean()
@IsOptional()
isSecret?: boolean;
}
export class BulkUpdateSettingsDto {
@ApiProperty({
type: 'array',
items: {
type: 'object',
properties: {
key: { type: 'string' },
value: { type: 'string' },
category: { type: 'string' },
description: { type: 'string' },
valueType: { type: 'string' },
isSecret: { type: 'boolean' },
},
required: ['key', 'value'],
},
description: 'Array of settings to upsert in one transaction',
})
settings: Array<{
key: string;
value: string;
category?: string;
description?: string;
valueType?: string;
isSecret?: boolean;
}>;
}