docs(openapi): add descriptions to OpenAPI specification (#25185)

* faces

* add openapi descriptions

* remove dto descriptions

* gen openapi

* dtos

* fix dtos

* fix more

* fix build

* more

* complete dtos

* descriptions on rebase

* gen rebase

* revert correct integer type conversion

* gen after revert

* revert correct nullables

* regen after revert

* actually incorrect adding default here

* revert correct number type conversion

* regen after revert

* revert nullable usage

* regen fully

* readd some comments

* one more

* one more

* use enum

* add missing

* add missing controllers

* add missing dtos

* complete it

* more

* describe global key and slug

* add remaining body and param descriptions

* lint and format

* cleanup

* response and schema descriptions

* test patch according to suggestion

* revert added api response objects

* revert added api body objects

* revert added api param object

* revert added api query objects

* revert reorganized http code objects

* revert reorganize ApiOkResponse objects

* revert added api response objects (2)

* revert added api tag object

* revert added api schema objects

* migrate missing asset.dto.ts

* regenerate openapi builds

* delete generated mustache files

* remove descriptions from properties that are schemas

* lint

* revert nullable type changes

* revert int/num type changes

* remove explicit default

* readd comment

* lint

* pr fixes

* last bits and pieces

* lint and format

* chore: remove rejected patches

* fix: deleting asset from asset-viewer on search results (#25596)

* fix: escape handling in search asset viewer (#25621)

* fix: correctly show owner in album options modal (#25618)

* fix: validation issues

* fix: validation issues

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: Min Idzelis <min123@gmail.com>
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
Co-authored-by: Paul Makles <me@insrt.uk>
This commit is contained in:
Timon
2026-01-29 14:49:15 +01:00
committed by GitHub
parent eadb2f89af
commit 8db61d341f
377 changed files with 5554 additions and 735 deletions
+165 -73
View File
@@ -40,18 +40,20 @@ const isEmailNotificationEnabled = (config: SystemConfigSmtpDto) => config.enabl
const isDatabaseBackupEnabled = (config: DatabaseBackupConfig) => config.enabled;
export class DatabaseBackupConfig {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateIf(isDatabaseBackupEnabled)
@IsNotEmpty()
@IsCronExpression()
@IsString()
@ApiProperty({ description: 'Cron expression' })
cronExpression!: string;
@IsInt()
@IsPositive()
@IsNotEmpty()
@ApiProperty({ description: 'Keep last amount' })
keepLastAmount!: number;
}
@@ -67,171 +69,179 @@ export class SystemConfigFFmpegDto {
@Min(0)
@Max(51)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'CRF' })
crf!: number;
@IsInt()
@Min(0)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Threads' })
threads!: number;
@IsString()
@ApiProperty({ description: 'Preset' })
preset!: string;
@ValidateEnum({ enum: VideoCodec, name: 'VideoCodec' })
@ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', description: 'Target video codec' })
targetVideoCodec!: VideoCodec;
@ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', each: true })
@ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', each: true, description: 'Accepted video codecs' })
acceptedVideoCodecs!: VideoCodec[];
@ValidateEnum({ enum: AudioCodec, name: 'AudioCodec' })
@ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', description: 'Target audio codec' })
targetAudioCodec!: AudioCodec;
@ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', each: true })
@ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', each: true, description: 'Accepted audio codecs' })
acceptedAudioCodecs!: AudioCodec[];
@ValidateEnum({ enum: VideoContainer, name: 'VideoContainer', each: true })
@ValidateEnum({ enum: VideoContainer, name: 'VideoContainer', each: true, description: 'Accepted containers' })
acceptedContainers!: VideoContainer[];
@IsString()
@ApiProperty({ description: 'Target resolution' })
targetResolution!: string;
@IsString()
@ApiProperty({ description: 'Max bitrate' })
maxBitrate!: string;
@IsInt()
@Min(-1)
@Max(16)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'B-frames' })
bframes!: number;
@IsInt()
@Min(0)
@Max(6)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'References' })
refs!: number;
@IsInt()
@Min(0)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'GOP size' })
gopSize!: number;
@ValidateBoolean()
@ValidateBoolean({ description: 'Temporal AQ' })
temporalAQ!: boolean;
@ValidateEnum({ enum: CQMode, name: 'CQMode' })
@ValidateEnum({ enum: CQMode, name: 'CQMode', description: 'CQ mode' })
cqMode!: CQMode;
@ValidateBoolean()
@ValidateBoolean({ description: 'Two pass' })
twoPass!: boolean;
@ApiProperty({ description: 'Preferred hardware device' })
@IsString()
preferredHwDevice!: string;
@ValidateEnum({ enum: TranscodePolicy, name: 'TranscodePolicy' })
@ValidateEnum({ enum: TranscodePolicy, name: 'TranscodePolicy', description: 'Transcode policy' })
transcode!: TranscodePolicy;
@ValidateEnum({ enum: TranscodeHardwareAcceleration, name: 'TranscodeHWAccel' })
@ValidateEnum({
enum: TranscodeHardwareAcceleration,
name: 'TranscodeHWAccel',
description: 'Transcode hardware acceleration',
})
accel!: TranscodeHardwareAcceleration;
@ValidateBoolean()
@ValidateBoolean({ description: 'Accelerated decode' })
accelDecode!: boolean;
@ValidateEnum({ enum: ToneMapping, name: 'ToneMapping' })
@ValidateEnum({ enum: ToneMapping, name: 'ToneMapping', description: 'Tone mapping' })
tonemap!: ToneMapping;
}
class JobSettingsDto {
@IsInt()
@IsPositive()
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Concurrency' })
concurrency!: number;
}
class SystemConfigJobDto implements Record<ConcurrentQueueName, JobSettingsDto> {
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.ThumbnailGeneration]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.MetadataExtraction]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.VideoConversion]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.SmartSearch]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Migration]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.BackgroundTask]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Search]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.FaceDetection]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Ocr]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Sidecar]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Library]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Notification]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
[QueueName.Workflow]!: JobSettingsDto;
@ApiProperty({ type: JobSettingsDto })
@ApiProperty({ type: JobSettingsDto, description: undefined })
@ValidateNested()
@IsObject()
@Type(() => JobSettingsDto)
@@ -239,7 +249,7 @@ class SystemConfigJobDto implements Record<ConcurrentQueueName, JobSettingsDto>
}
class SystemConfigLibraryScanDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateIf(isLibraryScanEnabled)
@@ -250,7 +260,7 @@ class SystemConfigLibraryScanDto {
}
class SystemConfigLibraryWatchDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
}
@@ -267,7 +277,7 @@ class SystemConfigLibraryDto {
}
class SystemConfigLoggingDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateEnum({ enum: LogLevel, name: 'LogLevel' })
@@ -275,7 +285,7 @@ class SystemConfigLoggingDto {
}
class MachineLearningAvailabilityChecksDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@IsInt()
@@ -286,7 +296,7 @@ class MachineLearningAvailabilityChecksDto {
}
class SystemConfigMachineLearningDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@IsUrl({ require_tld: false, allow_underscores: true }, { each: true })
@@ -332,7 +342,7 @@ export class MapThemeDto {
}
class SystemConfigMapDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@IsNotEmpty()
@@ -345,7 +355,7 @@ class SystemConfigMapDto {
}
class SystemConfigNewVersionCheckDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
}
@@ -353,72 +363,82 @@ class SystemConfigNightlyTasksDto {
@IsDateStringFormat('HH:mm', { message: 'startTime must be in HH:mm format' })
startTime!: string;
@ValidateBoolean()
@ValidateBoolean({ description: 'Database cleanup' })
databaseCleanup!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Missing thumbnails' })
missingThumbnails!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Cluster new faces' })
clusterNewFaces!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Generate memories' })
generateMemories!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Sync quota usage' })
syncQuotaUsage!: boolean;
}
class SystemConfigOAuthDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Auto launch' })
autoLaunch!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Auto register' })
autoRegister!: boolean;
@IsString()
@ApiProperty({ description: 'Button text' })
buttonText!: string;
@ValidateIf(isOAuthEnabled)
@IsNotEmpty()
@IsString()
@ApiProperty({ description: 'Client ID' })
clientId!: string;
@ValidateIf(isOAuthEnabled)
@IsString()
@ApiProperty({ description: 'Client secret' })
clientSecret!: string;
@ValidateEnum({ enum: OAuthTokenEndpointAuthMethod, name: 'OAuthTokenEndpointAuthMethod' })
@ValidateEnum({
enum: OAuthTokenEndpointAuthMethod,
name: 'OAuthTokenEndpointAuthMethod',
description: 'Token endpoint auth method',
})
tokenEndpointAuthMethod!: OAuthTokenEndpointAuthMethod;
@IsInt()
@IsPositive()
@Optional()
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Timeout' })
timeout!: number;
@IsNumber()
@Min(0)
@Optional({ nullable: true })
@ApiProperty({ type: 'integer', format: 'int64' })
@ApiProperty({ type: 'integer', format: 'int64', description: 'Default storage quota' })
defaultStorageQuota!: number | null;
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateIf(isOAuthEnabled)
@IsNotEmpty()
@IsString()
@ApiProperty({ description: 'Issuer URL' })
issuerUrl!: string;
@ValidateBoolean()
@ValidateBoolean({ description: 'Mobile override enabled' })
mobileOverrideEnabled!: boolean;
@ValidateIf(isOAuthOverrideEnabled)
@IsUrl()
@ApiProperty({ description: 'Mobile redirect URI' })
mobileRedirectUri!: string;
@IsString()
@ApiProperty({ description: 'Scope' })
scope!: string;
@IsString()
@@ -427,30 +447,34 @@ class SystemConfigOAuthDto {
@IsString()
@IsNotEmpty()
@ApiProperty({ description: 'Profile signing algorithm' })
profileSigningAlgorithm!: string;
@IsString()
@ApiProperty({ description: 'Storage label claim' })
storageLabelClaim!: string;
@IsString()
@ApiProperty({ description: 'Storage quota claim' })
storageQuotaClaim!: string;
@IsString()
@ApiProperty({ description: 'Role claim' })
roleClaim!: string;
}
class SystemConfigPasswordLoginDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
}
class SystemConfigReverseGeocodingDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
}
class SystemConfigFacesDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Import' })
import!: boolean;
}
@@ -464,51 +488,61 @@ class SystemConfigMetadataDto {
class SystemConfigServerDto {
@ValidateIf((_, value: string) => value !== '')
@IsUrl({ require_tld: false, require_protocol: true, protocols: ['http', 'https'] })
@ApiProperty({ description: 'External domain' })
externalDomain!: string;
@IsString()
@ApiProperty({ description: 'Login page message' })
loginPageMessage!: string;
@ValidateBoolean()
@ValidateBoolean({ description: 'Public users' })
publicUsers!: boolean;
}
class SystemConfigSmtpTransportDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Whether to ignore SSL certificate errors' })
ignoreCert!: boolean;
@ApiProperty({ description: 'SMTP server hostname' })
@IsNotEmpty()
@IsString()
host!: string;
@ApiProperty({ description: 'SMTP server port', type: Number, minimum: 0, maximum: 65_535 })
@IsNumber()
@Min(0)
@Max(65_535)
port!: number;
@ValidateBoolean()
@ValidateBoolean({ description: 'Whether to use secure connection (TLS/SSL)' })
secure!: boolean;
@ApiProperty({ description: 'SMTP username' })
@IsString()
username!: string;
@ApiProperty({ description: 'SMTP password' })
@IsString()
password!: string;
}
export class SystemConfigSmtpDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Whether SMTP email notifications are enabled' })
enabled!: boolean;
@ApiProperty({ description: 'Email address to send from' })
@ValidateIf(isEmailNotificationEnabled)
@IsNotEmpty()
@IsString()
@IsNotEmpty()
from!: string;
@ApiProperty({ description: 'Email address for replies' })
@IsString()
replyTo!: string;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@ValidateIf(isEmailNotificationEnabled)
@Type(() => SystemConfigSmtpTransportDto)
@ValidateNested()
@@ -542,48 +576,58 @@ class SystemConfigTemplatesDto {
}
class SystemConfigStorageTemplateDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateBoolean()
@ValidateBoolean({ description: 'Hash verification enabled' })
hashVerificationEnabled!: boolean;
@IsNotEmpty()
@IsString()
@ApiProperty({ description: 'Template' })
template!: string;
}
export class SystemConfigTemplateStorageOptionDto {
@ApiProperty({ description: 'Available year format options for storage template' })
yearOptions!: string[];
@ApiProperty({ description: 'Available month format options for storage template' })
monthOptions!: string[];
@ApiProperty({ description: 'Available week format options for storage template' })
weekOptions!: string[];
@ApiProperty({ description: 'Available day format options for storage template' })
dayOptions!: string[];
@ApiProperty({ description: 'Available hour format options for storage template' })
hourOptions!: string[];
@ApiProperty({ description: 'Available minute format options for storage template' })
minuteOptions!: string[];
@ApiProperty({ description: 'Available second format options for storage template' })
secondOptions!: string[];
@ApiProperty({ description: 'Available preset template options' })
presetOptions!: string[];
}
export class SystemConfigThemeDto {
@ApiProperty({ description: 'Custom CSS for theming' })
@IsString()
customCss!: string;
}
class SystemConfigGeneratedImageDto {
@ValidateEnum({ enum: ImageFormat, name: 'ImageFormat' })
@ValidateEnum({ enum: ImageFormat, name: 'ImageFormat', description: 'Image format' })
format!: ImageFormat;
@IsInt()
@Min(1)
@Max(100)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Quality' })
quality!: number;
@IsInt()
@Min(1)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Size' })
size!: number;
@ValidateBoolean({ optional: true, default: false })
@@ -591,20 +635,20 @@ class SystemConfigGeneratedImageDto {
}
class SystemConfigGeneratedFullsizeImageDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@ValidateEnum({ enum: ImageFormat, name: 'ImageFormat' })
@ValidateEnum({ enum: ImageFormat, name: 'ImageFormat', description: 'Image format' })
format!: ImageFormat;
@IsInt()
@Min(1)
@Max(100)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Quality' })
quality!: number;
@ValidateBoolean({ optional: true, default: false })
@ValidateBoolean({ optional: true, default: false, description: 'Progressive' })
progressive?: boolean;
}
@@ -612,33 +656,39 @@ export class SystemConfigImageDto {
@Type(() => SystemConfigGeneratedImageDto)
@ValidateNested()
@IsObject()
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
thumbnail!: SystemConfigGeneratedImageDto;
@Type(() => SystemConfigGeneratedImageDto)
@ValidateNested()
@IsObject()
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
preview!: SystemConfigGeneratedImageDto;
@Type(() => SystemConfigGeneratedFullsizeImageDto)
@ValidateNested()
@IsObject()
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
fullsize!: SystemConfigGeneratedFullsizeImageDto;
@ValidateEnum({ enum: Colorspace, name: 'Colorspace' })
@ValidateEnum({ enum: Colorspace, name: 'Colorspace', description: 'Colorspace' })
colorspace!: Colorspace;
@ValidateBoolean()
@ValidateBoolean({ description: 'Extract embedded' })
extractEmbedded!: boolean;
}
class SystemConfigTrashDto {
@ValidateBoolean()
@ValidateBoolean({ description: 'Enabled' })
enabled!: boolean;
@IsInt()
@Min(0)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Days' })
days!: number;
}
@@ -646,111 +696,153 @@ class SystemConfigUserDto {
@IsInt()
@Min(1)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
@ApiProperty({ type: 'integer', description: 'Delete delay' })
deleteDelay!: number;
}
export class SystemConfigDto implements SystemConfig {
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigBackupsDto)
@ValidateNested()
@IsObject()
backup!: SystemConfigBackupsDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigFFmpegDto)
@ValidateNested()
@IsObject()
ffmpeg!: SystemConfigFFmpegDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigLoggingDto)
@ValidateNested()
@IsObject()
logging!: SystemConfigLoggingDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigMachineLearningDto)
@ValidateNested()
@IsObject()
machineLearning!: SystemConfigMachineLearningDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigMapDto)
@ValidateNested()
@IsObject()
map!: SystemConfigMapDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigNewVersionCheckDto)
@ValidateNested()
@IsObject()
newVersionCheck!: SystemConfigNewVersionCheckDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigNightlyTasksDto)
@ValidateNested()
@IsObject()
nightlyTasks!: SystemConfigNightlyTasksDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigOAuthDto)
@ValidateNested()
@IsObject()
oauth!: SystemConfigOAuthDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigPasswordLoginDto)
@ValidateNested()
@IsObject()
passwordLogin!: SystemConfigPasswordLoginDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigReverseGeocodingDto)
@ValidateNested()
@IsObject()
reverseGeocoding!: SystemConfigReverseGeocodingDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigMetadataDto)
@ValidateNested()
@IsObject()
metadata!: SystemConfigMetadataDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigStorageTemplateDto)
@ValidateNested()
@IsObject()
storageTemplate!: SystemConfigStorageTemplateDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigJobDto)
@ValidateNested()
@IsObject()
job!: SystemConfigJobDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigImageDto)
@ValidateNested()
@IsObject()
image!: SystemConfigImageDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigTrashDto)
@ValidateNested()
@IsObject()
trash!: SystemConfigTrashDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigThemeDto)
@ValidateNested()
@IsObject()
theme!: SystemConfigThemeDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigLibraryDto)
@ValidateNested()
@IsObject()
library!: SystemConfigLibraryDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigNotificationsDto)
@ValidateNested()
@IsObject()
notifications!: SystemConfigNotificationsDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigTemplatesDto)
@ValidateNested()
@IsObject()
templates!: SystemConfigTemplatesDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigServerDto)
@ValidateNested()
@IsObject()
server!: SystemConfigServerDto;
// Description lives on schema to avoid duplication
@ApiProperty({ description: undefined })
@Type(() => SystemConfigUserDto)
@ValidateNested()
@IsObject()