From 7f1651df713871c8d616d1cf18d7e6ffeaa37607 Mon Sep 17 00:00:00 2001
From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
Date: Tue, 23 Apr 2024 00:13:44 +0200
Subject: [PATCH] chore(server): enable swagger to take class validator rules
 into account (#9022)

* enable swagger to take class validator rules into account

* chore: open api
---
 mobile/openapi/lib/model/create_user_dto.dart |  1 +
 .../openapi/lib/model/download_info_dto.dart  |  1 +
 .../openapi/lib/model/job_settings_dto.dart   |  1 +
 .../lib/model/metadata_search_dto.dart        |  3 ++
 mobile/openapi/lib/model/on_this_day_dto.dart |  1 +
 .../openapi/lib/model/recognition_config.dart |  5 +++
 .../openapi/lib/model/smart_search_dto.dart   |  3 ++
 .../lib/model/system_config_f_fmpeg_dto.dart  |  9 ++++
 .../lib/model/system_config_image_dto.dart    |  4 ++
 .../lib/model/system_config_o_auth_dto.dart   |  1 +
 .../lib/model/system_config_trash_dto.dart    |  1 +
 .../lib/model/system_config_user_dto.dart     |  1 +
 mobile/openapi/lib/model/update_user_dto.dart |  1 +
 open-api/immich-openapi-specs.json            | 45 +++++++++++++++++++
 server/nest-cli.json                          |  2 +-
 15 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/mobile/openapi/lib/model/create_user_dto.dart b/mobile/openapi/lib/model/create_user_dto.dart
index 2dada4f672..c29a8538e4 100644
--- a/mobile/openapi/lib/model/create_user_dto.dart
+++ b/mobile/openapi/lib/model/create_user_dto.dart
@@ -36,6 +36,7 @@ class CreateUserDto {
 
   String password;
 
+  /// Minimum value: 1
   int? quotaSizeInBytes;
 
   ///
diff --git a/mobile/openapi/lib/model/download_info_dto.dart b/mobile/openapi/lib/model/download_info_dto.dart
index 0bfdbe9f32..7de463b7cb 100644
--- a/mobile/openapi/lib/model/download_info_dto.dart
+++ b/mobile/openapi/lib/model/download_info_dto.dart
@@ -27,6 +27,7 @@ class DownloadInfoDto {
   ///
   String? albumId;
 
+  /// Minimum value: 1
   ///
   /// Please note: This property should have been non-nullable! Since the specification file
   /// does not include a default value (using the "default:" property), however, the generated
diff --git a/mobile/openapi/lib/model/job_settings_dto.dart b/mobile/openapi/lib/model/job_settings_dto.dart
index 777611cc8c..c7c10c267b 100644
--- a/mobile/openapi/lib/model/job_settings_dto.dart
+++ b/mobile/openapi/lib/model/job_settings_dto.dart
@@ -16,6 +16,7 @@ class JobSettingsDto {
     required this.concurrency,
   });
 
+  /// Minimum value: 1
   int concurrency;
 
   @override
diff --git a/mobile/openapi/lib/model/metadata_search_dto.dart b/mobile/openapi/lib/model/metadata_search_dto.dart
index 3f770ed092..ee5e7aa4f6 100644
--- a/mobile/openapi/lib/model/metadata_search_dto.dart
+++ b/mobile/openapi/lib/model/metadata_search_dto.dart
@@ -260,6 +260,7 @@ class MetadataSearchDto {
   ///
   String? originalPath;
 
+  /// Minimum value: 1
   ///
   /// Please note: This property should have been non-nullable! Since the specification file
   /// does not include a default value (using the "default:" property), however, the generated
@@ -286,6 +287,8 @@ class MetadataSearchDto {
   ///
   String? resizePath;
 
+  /// Minimum value: 1
+  /// Maximum value: 1000
   ///
   /// Please note: This property should have been non-nullable! Since the specification file
   /// does not include a default value (using the "default:" property), however, the generated
diff --git a/mobile/openapi/lib/model/on_this_day_dto.dart b/mobile/openapi/lib/model/on_this_day_dto.dart
index ef1471dfb7..81b13e391b 100644
--- a/mobile/openapi/lib/model/on_this_day_dto.dart
+++ b/mobile/openapi/lib/model/on_this_day_dto.dart
@@ -16,6 +16,7 @@ class OnThisDayDto {
     required this.year,
   });
 
+  /// Minimum value: 1
   num year;
 
   @override
diff --git a/mobile/openapi/lib/model/recognition_config.dart b/mobile/openapi/lib/model/recognition_config.dart
index e66c376e12..3d4171bf68 100644
--- a/mobile/openapi/lib/model/recognition_config.dart
+++ b/mobile/openapi/lib/model/recognition_config.dart
@@ -23,10 +23,15 @@ class RecognitionConfig {
 
   bool enabled;
 
+  /// Minimum value: 0
+  /// Maximum value: 2
   double maxDistance;
 
+  /// Minimum value: 1
   int minFaces;
 
+  /// Minimum value: 0
+  /// Maximum value: 1
   double minScore;
 
   String modelName;
diff --git a/mobile/openapi/lib/model/smart_search_dto.dart b/mobile/openapi/lib/model/smart_search_dto.dart
index 0b99acdd66..f24595fa1b 100644
--- a/mobile/openapi/lib/model/smart_search_dto.dart
+++ b/mobile/openapi/lib/model/smart_search_dto.dart
@@ -192,6 +192,7 @@ class SmartSearchDto {
   ///
   String? model;
 
+  /// Minimum value: 1
   ///
   /// Please note: This property should have been non-nullable! Since the specification file
   /// does not include a default value (using the "default:" property), however, the generated
@@ -204,6 +205,8 @@ class SmartSearchDto {
 
   String query;
 
+  /// Minimum value: 1
+  /// Maximum value: 1000
   ///
   /// Please note: This property should have been non-nullable! Since the specification file
   /// does not include a default value (using the "default:" property), however, the generated
diff --git a/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart b/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart
index b1c0f278a9..758bc37fa4 100644
--- a/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart
+++ b/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart
@@ -41,22 +41,30 @@ class SystemConfigFFmpegDto {
 
   List<VideoCodec> acceptedVideoCodecs;
 
+  /// Minimum value: -1
+  /// Maximum value: 16
   int bframes;
 
   CQMode cqMode;
 
+  /// Minimum value: 0
+  /// Maximum value: 51
   int crf;
 
+  /// Minimum value: 0
   int gopSize;
 
   String maxBitrate;
 
+  /// Minimum value: 0
   int npl;
 
   String preferredHwDevice;
 
   String preset;
 
+  /// Minimum value: 0
+  /// Maximum value: 6
   int refs;
 
   AudioCodec targetAudioCodec;
@@ -67,6 +75,7 @@ class SystemConfigFFmpegDto {
 
   bool temporalAQ;
 
+  /// Minimum value: 0
   int threads;
 
   ToneMapping tonemap;
diff --git a/mobile/openapi/lib/model/system_config_image_dto.dart b/mobile/openapi/lib/model/system_config_image_dto.dart
index 7072e11270..46e598d6be 100644
--- a/mobile/openapi/lib/model/system_config_image_dto.dart
+++ b/mobile/openapi/lib/model/system_config_image_dto.dart
@@ -28,12 +28,16 @@ class SystemConfigImageDto {
 
   ImageFormat previewFormat;
 
+  /// Minimum value: 1
   int previewSize;
 
+  /// Minimum value: 1
+  /// Maximum value: 100
   int quality;
 
   ImageFormat thumbnailFormat;
 
+  /// Minimum value: 1
   int thumbnailSize;
 
   @override
diff --git a/mobile/openapi/lib/model/system_config_o_auth_dto.dart b/mobile/openapi/lib/model/system_config_o_auth_dto.dart
index 1e7fe7f000..1b43f3eb72 100644
--- a/mobile/openapi/lib/model/system_config_o_auth_dto.dart
+++ b/mobile/openapi/lib/model/system_config_o_auth_dto.dart
@@ -39,6 +39,7 @@ class SystemConfigOAuthDto {
 
   String clientSecret;
 
+  /// Minimum value: 0
   num defaultStorageQuota;
 
   bool enabled;
diff --git a/mobile/openapi/lib/model/system_config_trash_dto.dart b/mobile/openapi/lib/model/system_config_trash_dto.dart
index 3c51e9945f..255be5cbda 100644
--- a/mobile/openapi/lib/model/system_config_trash_dto.dart
+++ b/mobile/openapi/lib/model/system_config_trash_dto.dart
@@ -17,6 +17,7 @@ class SystemConfigTrashDto {
     required this.enabled,
   });
 
+  /// Minimum value: 0
   int days;
 
   bool enabled;
diff --git a/mobile/openapi/lib/model/system_config_user_dto.dart b/mobile/openapi/lib/model/system_config_user_dto.dart
index 08d939c483..95b9c289e8 100644
--- a/mobile/openapi/lib/model/system_config_user_dto.dart
+++ b/mobile/openapi/lib/model/system_config_user_dto.dart
@@ -16,6 +16,7 @@ class SystemConfigUserDto {
     required this.deleteDelay,
   });
 
+  /// Minimum value: 1
   int deleteDelay;
 
   @override
diff --git a/mobile/openapi/lib/model/update_user_dto.dart b/mobile/openapi/lib/model/update_user_dto.dart
index 8fc85b4868..7a8f097975 100644
--- a/mobile/openapi/lib/model/update_user_dto.dart
+++ b/mobile/openapi/lib/model/update_user_dto.dart
@@ -75,6 +75,7 @@ class UpdateUserDto {
   ///
   String? password;
 
+  /// Minimum value: 1
   int? quotaSizeInBytes;
 
   ///
diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json
index b5bf2c9f4d..c2483d690c 100644
--- a/open-api/immich-openapi-specs.json
+++ b/open-api/immich-openapi-specs.json
@@ -1447,6 +1447,8 @@
             "required": true,
             "in": "query",
             "schema": {
+              "minimum": 1,
+              "maximum": 31,
               "type": "integer"
             }
           },
@@ -1455,6 +1457,8 @@
             "required": true,
             "in": "query",
             "schema": {
+              "minimum": 1,
+              "maximum": 12,
               "type": "integer"
             }
           }
@@ -1499,6 +1503,7 @@
             "required": false,
             "in": "query",
             "schema": {
+              "minimum": 1,
               "type": "number"
             }
           }
@@ -2086,6 +2091,7 @@
             "required": false,
             "in": "query",
             "schema": {
+              "minimum": 1,
               "type": "number"
             }
           },
@@ -2123,6 +2129,8 @@
             "required": false,
             "in": "query",
             "schema": {
+              "minimum": 1,
+              "maximum": 1000,
               "type": "number"
             }
           },
@@ -4456,6 +4464,7 @@
             "required": false,
             "in": "query",
             "schema": {
+              "minimum": 1,
               "type": "number"
             }
           },
@@ -4488,6 +4497,8 @@
             "required": false,
             "in": "query",
             "schema": {
+              "minimum": 1,
+              "maximum": 1000,
               "type": "number"
             }
           },
@@ -5622,6 +5633,7 @@
             "required": true,
             "in": "query",
             "schema": {
+              "minimum": 1,
               "type": "integer"
             }
           },
@@ -8054,6 +8066,7 @@
         "properties": {
           "newPassword": {
             "example": "password",
+            "minLength": 8,
             "type": "string"
           },
           "password": {
@@ -8286,6 +8299,7 @@
           },
           "quotaSizeInBytes": {
             "format": "int64",
+            "minimum": 1,
             "nullable": true,
             "type": "integer"
           },
@@ -8391,6 +8405,7 @@
             "type": "string"
           },
           "archiveSize": {
+            "minimum": 1,
             "type": "integer"
           },
           "assetIds": {
@@ -8731,6 +8746,7 @@
       "JobSettingsDto": {
         "properties": {
           "concurrency": {
+            "minimum": 1,
             "type": "integer"
           }
         },
@@ -9203,6 +9219,7 @@
             "type": "string"
           },
           "page": {
+            "minimum": 1,
             "type": "number"
           },
           "personIds": {
@@ -9220,6 +9237,8 @@
             "type": "string"
           },
           "size": {
+            "maximum": 1000,
+            "minimum": 1,
             "type": "number"
           },
           "state": {
@@ -9321,6 +9340,7 @@
       "OnThisDayDto": {
         "properties": {
           "year": {
+            "minimum": 1,
             "type": "number"
           }
         },
@@ -9676,13 +9696,18 @@
           },
           "maxDistance": {
             "format": "float",
+            "maximum": 2,
+            "minimum": 0,
             "type": "number"
           },
           "minFaces": {
+            "minimum": 1,
             "type": "integer"
           },
           "minScore": {
             "format": "float",
+            "maximum": 1,
+            "minimum": 0,
             "type": "number"
           },
           "modelName": {
@@ -10401,6 +10426,7 @@
             "type": "string"
           },
           "page": {
+            "minimum": 1,
             "type": "number"
           },
           "personIds": {
@@ -10414,6 +10440,8 @@
             "type": "string"
           },
           "size": {
+            "maximum": 1000,
+            "minimum": 1,
             "type": "number"
           },
           "state": {
@@ -10551,21 +10579,27 @@
             "type": "array"
           },
           "bframes": {
+            "maximum": 16,
+            "minimum": -1,
             "type": "integer"
           },
           "cqMode": {
             "$ref": "#/components/schemas/CQMode"
           },
           "crf": {
+            "maximum": 51,
+            "minimum": 0,
             "type": "integer"
           },
           "gopSize": {
+            "minimum": 0,
             "type": "integer"
           },
           "maxBitrate": {
             "type": "string"
           },
           "npl": {
+            "minimum": 0,
             "type": "integer"
           },
           "preferredHwDevice": {
@@ -10575,6 +10609,8 @@
             "type": "string"
           },
           "refs": {
+            "maximum": 6,
+            "minimum": 0,
             "type": "integer"
           },
           "targetAudioCodec": {
@@ -10590,6 +10626,7 @@
             "type": "boolean"
           },
           "threads": {
+            "minimum": 0,
             "type": "integer"
           },
           "tonemap": {
@@ -10638,15 +10675,19 @@
             "$ref": "#/components/schemas/ImageFormat"
           },
           "previewSize": {
+            "minimum": 1,
             "type": "integer"
           },
           "quality": {
+            "maximum": 100,
+            "minimum": 1,
             "type": "integer"
           },
           "thumbnailFormat": {
             "$ref": "#/components/schemas/ImageFormat"
           },
           "thumbnailSize": {
+            "minimum": 1,
             "type": "integer"
           }
         },
@@ -10835,6 +10876,7 @@
             "type": "string"
           },
           "defaultStorageQuota": {
+            "minimum": 0,
             "type": "number"
           },
           "enabled": {
@@ -11013,6 +11055,7 @@
       "SystemConfigTrashDto": {
         "properties": {
           "days": {
+            "minimum": 0,
             "type": "integer"
           },
           "enabled": {
@@ -11028,6 +11071,7 @@
       "SystemConfigUserDto": {
         "properties": {
           "deleteDelay": {
+            "minimum": 1,
             "type": "integer"
           }
         },
@@ -11254,6 +11298,7 @@
           },
           "quotaSizeInBytes": {
             "format": "int64",
+            "minimum": 1,
             "nullable": true,
             "type": "integer"
           },
diff --git a/server/nest-cli.json b/server/nest-cli.json
index b295cd0f83..1eaf1888d5 100644
--- a/server/nest-cli.json
+++ b/server/nest-cli.json
@@ -9,7 +9,7 @@
       {
         "name": "@nestjs/swagger",
         "options": {
-          "classValidatorShim": false,
+          "classValidatorShim": true,
           "introspectComments": true
         }
       }