From b1629b24ad2fbde59a3867ae061e307f28ef2504 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 21 Feb 2025 11:44:04 +0000 Subject: [PATCH 01/14] chore: added file transformation stats to usage endpoint for bucket --- app/controllers/api/storage.php | 3 +++ src/Appwrite/Utopia/Response/Model/UsageBuckets.php | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index f180c22acf..efd82ba40e 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1894,6 +1894,7 @@ App::get('/v1/storage/:bucketId/usage') $metrics = [ str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES), str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE), + str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_FILES_TRANSFORMATIONS), ]; @@ -1948,5 +1949,7 @@ App::get('/v1/storage/:bucketId/usage') 'filesStorageTotal' => $usage[$metrics[1]]['total'], 'files' => $usage[$metrics[0]]['data'], 'storage' => $usage[$metrics[1]]['data'], + 'fileTransformations' => $usage[$metrics[2]]['data'], + 'fileTransformationsTotal' => $usage[$metrics[2]]['total'], ]), Response::MODEL_USAGE_BUCKETS); }); diff --git a/src/Appwrite/Utopia/Response/Model/UsageBuckets.php b/src/Appwrite/Utopia/Response/Model/UsageBuckets.php index 2f528ac9d1..ab8d129857 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageBuckets.php +++ b/src/Appwrite/Utopia/Response/Model/UsageBuckets.php @@ -42,6 +42,19 @@ class UsageBuckets extends Model 'example' => [], 'array' => true ]) + ->addRule('fileTransformations', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of files transformations per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('fileTransformationsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of files transformations.', + 'default' => 0, + 'example' => 0, + ]) ; } From 4ed4c660d5aff0ee10cbdaad8ff2e15293b3ed88 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 21 Feb 2025 12:53:17 +0000 Subject: [PATCH 02/14] chore: added tests for file transformations --- tests/e2e/Services/Storage/StorageConsoleClientTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/Services/Storage/StorageConsoleClientTest.php b/tests/e2e/Services/Storage/StorageConsoleClientTest.php index 5b6731b35e..b3a6ad9274 100644 --- a/tests/e2e/Services/Storage/StorageConsoleClientTest.php +++ b/tests/e2e/Services/Storage/StorageConsoleClientTest.php @@ -104,5 +104,7 @@ class StorageConsoleClientTest extends Scope $this->assertIsNumeric($response['body']['filesStorageTotal']); $this->assertIsArray($response['body']['files']); $this->assertIsArray($response['body']['storage']); + $this->assertIsArray($response['body']['fileTransformations']); + $this->assertIsNumeric($response['body']['fileTransformationsTotal']); } } From 0e0bab4c40a54a310b9d07599372ec8be8d06ac1 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 21 Feb 2025 13:28:49 +0000 Subject: [PATCH 03/14] chore: updated test --- tests/e2e/Services/Storage/StorageConsoleClientTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageConsoleClientTest.php b/tests/e2e/Services/Storage/StorageConsoleClientTest.php index b3a6ad9274..b2624746ca 100644 --- a/tests/e2e/Services/Storage/StorageConsoleClientTest.php +++ b/tests/e2e/Services/Storage/StorageConsoleClientTest.php @@ -98,7 +98,7 @@ class StorageConsoleClientTest extends Scope ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(5, count($response['body'])); + $this->assertEquals(7, count($response['body'])); $this->assertEquals('24h', $response['body']['range']); $this->assertIsNumeric($response['body']['filesTotal']); $this->assertIsNumeric($response['body']['filesStorageTotal']); From 7ac4a5bf271b7079210996c01b39bc186aa4f207 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 25 Feb 2025 04:43:44 +0000 Subject: [PATCH 04/14] chore: update naming --- app/controllers/api/storage.php | 6 +++--- src/Appwrite/Utopia/Response/Model/UsageBuckets.php | 4 ++-- tests/e2e/Services/Storage/StorageConsoleClientTest.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index efd82ba40e..072a2d4ae4 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1894,7 +1894,7 @@ App::get('/v1/storage/:bucketId/usage') $metrics = [ str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES), str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE), - str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_FILES_TRANSFORMATIONS), + str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_FILES_IMAGES_TRANSFORMED), ]; @@ -1949,7 +1949,7 @@ App::get('/v1/storage/:bucketId/usage') 'filesStorageTotal' => $usage[$metrics[1]]['total'], 'files' => $usage[$metrics[0]]['data'], 'storage' => $usage[$metrics[1]]['data'], - 'fileTransformations' => $usage[$metrics[2]]['data'], - 'fileTransformationsTotal' => $usage[$metrics[2]]['total'], + 'imageTransformations' => $usage[$metrics[2]]['data'], + 'imageTransformationsTotal' => $usage[$metrics[2]]['total'], ]), Response::MODEL_USAGE_BUCKETS); }); diff --git a/src/Appwrite/Utopia/Response/Model/UsageBuckets.php b/src/Appwrite/Utopia/Response/Model/UsageBuckets.php index ab8d129857..ee624a29ad 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageBuckets.php +++ b/src/Appwrite/Utopia/Response/Model/UsageBuckets.php @@ -42,14 +42,14 @@ class UsageBuckets extends Model 'example' => [], 'array' => true ]) - ->addRule('fileTransformations', [ + ->addRule('imageTransformations', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of files transformations per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('fileTransformationsTotal', [ + ->addRule('imageTransformationsTotal', [ 'type' => self::TYPE_INTEGER, 'description' => 'Total aggregated number of files transformations.', 'default' => 0, diff --git a/tests/e2e/Services/Storage/StorageConsoleClientTest.php b/tests/e2e/Services/Storage/StorageConsoleClientTest.php index b2624746ca..bbb14fb136 100644 --- a/tests/e2e/Services/Storage/StorageConsoleClientTest.php +++ b/tests/e2e/Services/Storage/StorageConsoleClientTest.php @@ -104,7 +104,7 @@ class StorageConsoleClientTest extends Scope $this->assertIsNumeric($response['body']['filesStorageTotal']); $this->assertIsArray($response['body']['files']); $this->assertIsArray($response['body']['storage']); - $this->assertIsArray($response['body']['fileTransformations']); - $this->assertIsNumeric($response['body']['fileTransformationsTotal']); + $this->assertIsArray($response['body']['imageTransformations']); + $this->assertIsNumeric($response['body']['imageTransformationsTotal']); } } From 676431c355d93597d34853b95c286d9bd73525e3 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 25 Feb 2025 07:16:42 +0000 Subject: [PATCH 05/14] chore: shifted to logsDb --- app/controllers/api/storage.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 072a2d4ae4..972232167b 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1879,9 +1879,12 @@ App::get('/v1/storage/:bucketId/usage') ->param('bucketId', '', new UID(), 'Bucket ID.') ->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true) ->inject('response') + ->inject('project') ->inject('dbForProject') - ->action(function (string $bucketId, string $range, Response $response, Database $dbForProject) { + ->inject('getLogsDB') + ->action(function (string $bucketId, string $range, Response $response, Document $project, Database $dbForProject, callable $getLogsDB) { + $dbForLogs = call_user_func($getLogsDB, $project); $bucket = $dbForProject->getDocument('buckets', $bucketId); if ($bucket->isEmpty()) { @@ -1894,13 +1897,16 @@ App::get('/v1/storage/:bucketId/usage') $metrics = [ str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES), str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE), - str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_FILES_IMAGES_TRANSFORMED), + str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED), ]; - - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { + Authorization::skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $db = ($metric === str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED)) + ? $dbForLogs + : $dbForProject; + + $result = $db->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1908,7 +1914,7 @@ App::get('/v1/storage/:bucketId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $db->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), From ae78e793dd3d026e376def042d2b88fbec9ecd80 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 26 Feb 2025 08:52:06 +0000 Subject: [PATCH 06/14] chore: added blocking to file preview endpoint --- app/config/errors.php | 5 +++++ app/controllers/api/storage.php | 18 ++++++++++-------- src/Appwrite/Extend/Exception.php | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index 7c7f6dc9ec..d8a5c798d3 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -480,6 +480,11 @@ return [ 'description' => 'The requested file is not publicly readable.', 'code' => 403, ], + Exception::STORAGE_FILE_PREVIEW_BLOCKED => [ + 'name' => Exception::STORAGE_FILE_PREVIEW_BLOCKED, + 'description' => 'File preview is not available on your pricing current tier.', + 'code' => 403, + ], /** VCS */ Exception::INSTALLATION_NOT_FOUND => [ diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 972232167b..38e74ad2ee 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -935,15 +935,13 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') ->param('rotation', 0, new Range(-360, 360), 'Preview image rotation in degrees. Pass an integer between -360 and 360.', true) ->param('background', '', new HexColor(), 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true) ->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true) - ->inject('request') ->inject('response') - ->inject('project') + ->inject('plan') ->inject('dbForProject') - ->inject('mode') ->inject('deviceForFiles') ->inject('deviceForLocal') ->inject('queueForStatsUsage') - ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Request $request, Response $response, Document $project, Database $dbForProject, string $mode, Device $deviceForFiles, Device $deviceForLocal, StatsUsage $queueForStatsUsage) { + ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Response $response, array $plan, Database $dbForProject, Device $deviceForFiles, Device $deviceForLocal, StatsUsage $queueForStatsUsage) { if (!\extension_loaded('imagick')) { throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing'); @@ -965,6 +963,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::USER_UNAUTHORIZED); } + if (isset($plan['imageTransformations'])) { + if ($plan['imageTransformations'] === -1) { + throw new Exception(Exception::STORAGE_FILE_PREVIEW_BLOCKED); + } + } + if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { @@ -1073,8 +1077,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $queueForStatsUsage ->addMetric(METRIC_FILES_TRANSFORMATIONS, 1) - ->addMetric(str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_TRANSFORMATIONS), 1) - ; + ->addMetric(str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_TRANSFORMATIONS), 1); $transformedAt = $file->getAttribute('transformedAt', ''); if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $transformedAt) { @@ -1085,8 +1088,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $response ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType($contentType) - ->file($data) - ; + ->file($data); unset($image); }); diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index d4f47ca177..7f601018fe 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -143,6 +143,7 @@ class Exception extends \Exception public const STORAGE_INVALID_RANGE = 'storage_invalid_range'; public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id'; public const STORAGE_FILE_NOT_PUBLIC = 'storage_file_not_public'; + public const STORAGE_FILE_PREVIEW_BLOCKED = 'storage_file_preview_blocked'; /** VCS */ public const INSTALLATION_NOT_FOUND = 'installation_not_found'; From f31acd214ec73385d1f7668ed80787dfd4be85ba Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 27 Feb 2025 09:52:27 +0000 Subject: [PATCH 07/14] chore: remove plan blocking --- app/config/errors.php | 5 ----- app/controllers/api/storage.php | 9 +-------- src/Appwrite/Extend/Exception.php | 1 - 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index d8a5c798d3..7c7f6dc9ec 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -480,11 +480,6 @@ return [ 'description' => 'The requested file is not publicly readable.', 'code' => 403, ], - Exception::STORAGE_FILE_PREVIEW_BLOCKED => [ - 'name' => Exception::STORAGE_FILE_PREVIEW_BLOCKED, - 'description' => 'File preview is not available on your pricing current tier.', - 'code' => 403, - ], /** VCS */ Exception::INSTALLATION_NOT_FOUND => [ diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 38e74ad2ee..bee245b64f 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -936,12 +936,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') ->param('background', '', new HexColor(), 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true) ->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true) ->inject('response') - ->inject('plan') ->inject('dbForProject') ->inject('deviceForFiles') ->inject('deviceForLocal') ->inject('queueForStatsUsage') - ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Response $response, array $plan, Database $dbForProject, Device $deviceForFiles, Device $deviceForLocal, StatsUsage $queueForStatsUsage) { + ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Response $response, Database $dbForProject, Device $deviceForFiles, Device $deviceForLocal, StatsUsage $queueForStatsUsage) { if (!\extension_loaded('imagick')) { throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing'); @@ -963,12 +962,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::USER_UNAUTHORIZED); } - if (isset($plan['imageTransformations'])) { - if ($plan['imageTransformations'] === -1) { - throw new Exception(Exception::STORAGE_FILE_PREVIEW_BLOCKED); - } - } - if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 7f601018fe..d4f47ca177 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -143,7 +143,6 @@ class Exception extends \Exception public const STORAGE_INVALID_RANGE = 'storage_invalid_range'; public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id'; public const STORAGE_FILE_NOT_PUBLIC = 'storage_file_not_public'; - public const STORAGE_FILE_PREVIEW_BLOCKED = 'storage_file_preview_blocked'; /** VCS */ public const INSTALLATION_NOT_FOUND = 'installation_not_found'; From e9d8d13fbdf79dfe03fd6bd61474348d1f877e01 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 28 Feb 2025 08:28:21 +0000 Subject: [PATCH 08/14] chore: added imageTransformations to project usage --- app/controllers/api/project.php | 2 ++ src/Appwrite/Utopia/Response/Model/UsageProject.php | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index ea2cd4436d..cf2a128939 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -63,6 +63,7 @@ App::get('/v1/project/usage') METRIC_BUILDS_STORAGE, METRIC_DATABASES_OPERATIONS_READS, METRIC_DATABASES_OPERATIONS_WRITES, + METRIC_FILES_IMAGES_TRANSFORMED, ], 'period' => [ METRIC_NETWORK_REQUESTS, @@ -363,6 +364,7 @@ App::get('/v1/project/usage') 'authPhoneTotal' => $authPhoneTotal, 'authPhoneEstimate' => $authPhoneEstimate, 'authPhoneCountryBreakdown' => $authPhoneCountryBreakdown, + 'imageTransformations' => $total[METRIC_FILES_IMAGES_TRANSFORMED], ]), Response::MODEL_USAGE_PROJECT); }); diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index 1006276b56..6f74ec561b 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -197,6 +197,13 @@ class UsageProject extends Model 'example' => [], 'array' => true ]) + ->addRule('imageTransformations', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'An array of aggregated number of image transformations.', + 'default' => [], + 'example' => [], + 'array' => true + ]) ; } From d5cfdc570f25dbab1a591df1f8e32e800fe216fa Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 28 Feb 2025 08:41:53 +0000 Subject: [PATCH 09/14] chore: updated specs --- app/config/specs/open-api3-latest-client.json | 10 +- .../specs/open-api3-latest-console.json | 211 ++++++++++------- app/config/specs/open-api3-latest-server.json | 178 ++++++++------- app/config/specs/swagger2-latest-client.json | 10 +- app/config/specs/swagger2-latest-console.json | 215 +++++++++++------- app/config/specs/swagger2-latest-server.json | 180 ++++++++------- 6 files changed, 460 insertions(+), 344 deletions(-) diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index 820b1f55e0..316fe13116 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -3383,7 +3383,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "schema": { "type": "string", @@ -3404,7 +3404,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3423,7 +3424,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ] }, "in": "path" @@ -4365,7 +4367,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 7f57dfc437..5b1d6f0d1e 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -3387,7 +3387,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "schema": { "type": "string", @@ -3408,7 +3408,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3427,7 +3428,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ] }, "in": "path" @@ -7823,7 +7825,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", @@ -11585,7 +11587,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 134, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -11692,7 +11694,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 130, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -11718,54 +11720,6 @@ ] } }, - "\/health\/queue": { - "get": { - "summary": "Get queue", - "operationId": "healthGetQueue", - "tags": [ - "health" - ], - "description": "Check the Appwrite queue messaging servers are up and connection is successful.", - "responses": { - "200": { - "description": "Health Status", - "content": { - "application\/json": { - "schema": { - "$ref": "#\/components\/schemas\/healthStatus" - } - } - } - } - }, - "x-appwrite": { - "method": "getQueue", - "weight": 129, - "cookies": false, - "type": "", - "deprecated": false, - "demo": "health\/get-queue.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue.md", - "rate-limit": 0, - "rate-time": 3600, - "rate-key": "url:{url},ip:{ip}", - "scope": "health.read", - "platforms": [ - "server" - ], - "packaging": false, - "auth": { - "Project": [] - } - }, - "security": [ - { - "Project": [], - "Key": [] - } - ] - } - }, "\/health\/queue\/builds": { "get": { "summary": "Get builds queue", @@ -11788,7 +11742,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 136, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -11849,7 +11803,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 135, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -11910,7 +11864,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 137, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -11982,7 +11936,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 138, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -12081,8 +12035,9 @@ "v1-audits", "v1-mails", "v1-functions", - "v1-usage", - "v1-usage-dump", + "v1-stats-resources", + "v1-stats-usage", + "v1-stats-usage-dump", "v1-webhooks", "v1-certificates", "v1-builds", @@ -12130,7 +12085,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 142, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -12191,7 +12146,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 133, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -12252,7 +12207,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 139, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -12313,7 +12268,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 140, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -12374,7 +12329,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 141, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -12413,14 +12368,14 @@ ] } }, - "\/health\/queue\/usage": { + "\/health\/queue\/stats-resources": { "get": { - "summary": "Get usage queue", - "operationId": "healthGetQueueUsage", + "summary": "Get stats resources queue", + "operationId": "healthGetQueueStatsResources", "tags": [ "health" ], - "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "description": "Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue.", "responses": { "200": { "description": "Health Queue", @@ -12434,13 +12389,13 @@ } }, "x-appwrite": { - "method": "getQueueUsage", - "weight": 143, + "method": "getQueueStatsResources", + "weight": 142, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage.md", + "demo": "health\/get-queue-stats-resources.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-resources.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12474,10 +12429,71 @@ ] } }, - "\/health\/queue\/usage-dump": { + "\/health\/queue\/stats-usage": { + "get": { + "summary": "Get stats usage queue", + "operationId": "healthGetQueueUsage", + "tags": [ + "health" + ], + "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "responses": { + "200": { + "description": "Health Queue", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/healthQueue" + } + } + } + } + }, + "x-appwrite": { + "method": "getQueueUsage", + "weight": 143, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "health\/get-queue-usage.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "health.read", + "platforms": [ + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [] + } + ], + "parameters": [ + { + "name": "threshold", + "description": "Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 5000 + }, + "in": "query" + } + ] + } + }, + "\/health\/queue\/stats-usage-dump": { "get": { "summary": "Get usage dump queue", - "operationId": "healthGetQueueUsageDump", + "operationId": "healthGetQueueStatsUsageDump", "tags": [ "health" ], @@ -12495,13 +12511,13 @@ } }, "x-appwrite": { - "method": "getQueueUsageDump", + "method": "getQueueStatsUsageDump", "weight": 144, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage-dump.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage-dump.md", + "demo": "health\/get-queue-stats-usage-dump.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage-dump.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12557,7 +12573,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 132, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -12714,7 +12730,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 131, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -17609,17 +17625,17 @@ }, "endpoint": { "type": "string", - "description": "Source's Appwrite Endpoint", + "description": "Source Appwrite endpoint", "x-example": "https:\/\/example.com" }, "projectId": { "type": "string", - "description": "Source's Project ID", + "description": "Source Project ID", "x-example": "" }, "apiKey": { "type": "string", - "description": "Source's API Key", + "description": "Source API Key", "x-example": "" } }, @@ -36052,6 +36068,20 @@ "$ref": "#\/components\/schemas\/metric" }, "x-example": [] + }, + "imageTransformations": { + "type": "array", + "description": "Aggregated number of files transformations per period.", + "items": { + "$ref": "#\/components\/schemas\/metric" + }, + "x-example": [] + }, + "imageTransformationsTotal": { + "type": "integer", + "description": "Total aggregated number of files transformations.", + "x-example": 0, + "format": "int32" } }, "required": [ @@ -36059,7 +36089,9 @@ "filesTotal", "filesStorageTotal", "files", - "storage" + "storage", + "imageTransformations", + "imageTransformationsTotal" ] }, "usageFunctions": { @@ -36597,6 +36629,14 @@ "$ref": "#\/components\/schemas\/metric" }, "x-example": [] + }, + "imageTransformations": { + "type": "array", + "description": "An array of aggregated number of image transformations.", + "items": { + "$ref": "#\/components\/schemas\/metric" + }, + "x-example": [] } }, "required": [ @@ -36628,7 +36668,8 @@ "authPhoneEstimate", "authPhoneCountryBreakdown", "databasesReads", - "databasesWrites" + "databasesWrites", + "imageTransformations" ] }, "headers": { diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index 68d408762a..280c080514 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -3077,7 +3077,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "schema": { "type": "string", @@ -3098,7 +3098,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3117,7 +3118,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ] }, "in": "path" @@ -7381,7 +7383,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", @@ -10461,7 +10463,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 134, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -10570,7 +10572,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 130, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -10597,55 +10599,6 @@ ] } }, - "\/health\/queue": { - "get": { - "summary": "Get queue", - "operationId": "healthGetQueue", - "tags": [ - "health" - ], - "description": "Check the Appwrite queue messaging servers are up and connection is successful.", - "responses": { - "200": { - "description": "Health Status", - "content": { - "application\/json": { - "schema": { - "$ref": "#\/components\/schemas\/healthStatus" - } - } - } - } - }, - "x-appwrite": { - "method": "getQueue", - "weight": 129, - "cookies": false, - "type": "", - "deprecated": false, - "demo": "health\/get-queue.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue.md", - "rate-limit": 0, - "rate-time": 3600, - "rate-key": "url:{url},ip:{ip}", - "scope": "health.read", - "platforms": [ - "server" - ], - "packaging": false, - "auth": { - "Project": [], - "Key": [] - } - }, - "security": [ - { - "Project": [], - "Key": [] - } - ] - } - }, "\/health\/queue\/builds": { "get": { "summary": "Get builds queue", @@ -10668,7 +10621,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 136, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -10730,7 +10683,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 135, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -10792,7 +10745,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 137, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -10865,7 +10818,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 138, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -10966,8 +10919,9 @@ "v1-audits", "v1-mails", "v1-functions", - "v1-usage", - "v1-usage-dump", + "v1-stats-resources", + "v1-stats-usage", + "v1-stats-usage-dump", "v1-webhooks", "v1-certificates", "v1-builds", @@ -11015,7 +10969,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 142, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -11077,7 +11031,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 133, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -11139,7 +11093,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 139, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -11201,7 +11155,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 140, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -11263,7 +11217,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 141, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -11303,14 +11257,14 @@ ] } }, - "\/health\/queue\/usage": { + "\/health\/queue\/stats-resources": { "get": { - "summary": "Get usage queue", - "operationId": "healthGetQueueUsage", + "summary": "Get stats resources queue", + "operationId": "healthGetQueueStatsResources", "tags": [ "health" ], - "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "description": "Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue.", "responses": { "200": { "description": "Health Queue", @@ -11324,13 +11278,13 @@ } }, "x-appwrite": { - "method": "getQueueUsage", - "weight": 143, + "method": "getQueueStatsResources", + "weight": 142, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage.md", + "demo": "health\/get-queue-stats-resources.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-resources.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11365,10 +11319,72 @@ ] } }, - "\/health\/queue\/usage-dump": { + "\/health\/queue\/stats-usage": { + "get": { + "summary": "Get stats usage queue", + "operationId": "healthGetQueueUsage", + "tags": [ + "health" + ], + "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "responses": { + "200": { + "description": "Health Queue", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/healthQueue" + } + } + } + } + }, + "x-appwrite": { + "method": "getQueueUsage", + "weight": 143, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "health\/get-queue-usage.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "health.read", + "platforms": [ + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [] + } + ], + "parameters": [ + { + "name": "threshold", + "description": "Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 5000 + }, + "in": "query" + } + ] + } + }, + "\/health\/queue\/stats-usage-dump": { "get": { "summary": "Get usage dump queue", - "operationId": "healthGetQueueUsageDump", + "operationId": "healthGetQueueStatsUsageDump", "tags": [ "health" ], @@ -11386,13 +11402,13 @@ } }, "x-appwrite": { - "method": "getQueueUsageDump", + "method": "getQueueStatsUsageDump", "weight": 144, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage-dump.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage-dump.md", + "demo": "health\/get-queue-stats-usage-dump.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage-dump.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11449,7 +11465,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 132, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -11609,7 +11625,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 131, + "weight": 130, "cookies": false, "type": "", "deprecated": false, diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index c0980c44ce..8960bfaa5c 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -3557,7 +3557,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "type": "string", "x-example": "amex", @@ -3577,7 +3577,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3596,7 +3597,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ], "in": "path" }, @@ -4547,7 +4549,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 94b0d55199..f13db98150 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -3577,7 +3577,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "type": "string", "x-example": "amex", @@ -3597,7 +3597,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3616,7 +3617,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ], "in": "path" }, @@ -8012,7 +8014,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", @@ -11810,7 +11812,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 134, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -11919,7 +11921,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 130, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -11945,56 +11947,6 @@ ] } }, - "\/health\/queue": { - "get": { - "summary": "Get queue", - "operationId": "healthGetQueue", - "consumes": [ - "application\/json" - ], - "produces": [ - "application\/json" - ], - "tags": [ - "health" - ], - "description": "Check the Appwrite queue messaging servers are up and connection is successful.", - "responses": { - "200": { - "description": "Health Status", - "schema": { - "$ref": "#\/definitions\/healthStatus" - } - } - }, - "x-appwrite": { - "method": "getQueue", - "weight": 129, - "cookies": false, - "type": "", - "deprecated": false, - "demo": "health\/get-queue.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue.md", - "rate-limit": 0, - "rate-time": 3600, - "rate-key": "url:{url},ip:{ip}", - "scope": "health.read", - "platforms": [ - "server" - ], - "packaging": false, - "auth": { - "Project": [] - } - }, - "security": [ - { - "Project": [], - "Key": [] - } - ] - } - }, "\/health\/queue\/builds": { "get": { "summary": "Get builds queue", @@ -12019,7 +11971,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 136, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -12080,7 +12032,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 135, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -12141,7 +12093,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 137, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -12211,7 +12163,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 138, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -12309,8 +12261,9 @@ "v1-audits", "v1-mails", "v1-functions", - "v1-usage", - "v1-usage-dump", + "v1-stats-resources", + "v1-stats-usage", + "v1-stats-usage-dump", "v1-webhooks", "v1-certificates", "v1-builds", @@ -12357,7 +12310,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 142, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -12418,7 +12371,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 133, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -12479,7 +12432,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 139, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -12540,7 +12493,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 140, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -12601,7 +12554,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 141, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -12638,10 +12591,10 @@ ] } }, - "\/health\/queue\/usage": { + "\/health\/queue\/stats-resources": { "get": { - "summary": "Get usage queue", - "operationId": "healthGetQueueUsage", + "summary": "Get stats resources queue", + "operationId": "healthGetQueueStatsResources", "consumes": [ "application\/json" ], @@ -12651,7 +12604,7 @@ "tags": [ "health" ], - "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "description": "Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue.", "responses": { "200": { "description": "Health Queue", @@ -12661,13 +12614,13 @@ } }, "x-appwrite": { - "method": "getQueueUsage", - "weight": 143, + "method": "getQueueStatsResources", + "weight": 142, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage.md", + "demo": "health\/get-queue-stats-resources.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-resources.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12699,10 +12652,71 @@ ] } }, - "\/health\/queue\/usage-dump": { + "\/health\/queue\/stats-usage": { + "get": { + "summary": "Get stats usage queue", + "operationId": "healthGetQueueUsage", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "health" + ], + "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "responses": { + "200": { + "description": "Health Queue", + "schema": { + "$ref": "#\/definitions\/healthQueue" + } + } + }, + "x-appwrite": { + "method": "getQueueUsage", + "weight": 143, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "health\/get-queue-usage.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "health.read", + "platforms": [ + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [] + } + ], + "parameters": [ + { + "name": "threshold", + "description": "Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.", + "required": false, + "type": "integer", + "format": "int32", + "default": 5000, + "in": "query" + } + ] + } + }, + "\/health\/queue\/stats-usage-dump": { "get": { "summary": "Get usage dump queue", - "operationId": "healthGetQueueUsageDump", + "operationId": "healthGetQueueStatsUsageDump", "consumes": [ "application\/json" ], @@ -12722,13 +12736,13 @@ } }, "x-appwrite": { - "method": "getQueueUsageDump", + "method": "getQueueStatsUsageDump", "weight": 144, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage-dump.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage-dump.md", + "demo": "health\/get-queue-stats-usage-dump.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage-dump.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12784,7 +12798,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 132, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -12945,7 +12959,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 131, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -18070,19 +18084,19 @@ }, "endpoint": { "type": "string", - "description": "Source's Appwrite Endpoint", + "description": "Source Appwrite endpoint", "default": null, "x-example": "https:\/\/example.com" }, "projectId": { "type": "string", - "description": "Source's Project ID", + "description": "Source Project ID", "default": null, "x-example": "" }, "apiKey": { "type": "string", - "description": "Source's API Key", + "description": "Source API Key", "default": null, "x-example": "" } @@ -36608,6 +36622,21 @@ "$ref": "#\/definitions\/metric" }, "x-example": [] + }, + "imageTransformations": { + "type": "array", + "description": "Aggregated number of files transformations per period.", + "items": { + "type": "object", + "$ref": "#\/definitions\/metric" + }, + "x-example": [] + }, + "imageTransformationsTotal": { + "type": "integer", + "description": "Total aggregated number of files transformations.", + "x-example": 0, + "format": "int32" } }, "required": [ @@ -36615,7 +36644,9 @@ "filesTotal", "filesStorageTotal", "files", - "storage" + "storage", + "imageTransformations", + "imageTransformationsTotal" ] }, "usageFunctions": { @@ -37185,6 +37216,15 @@ "$ref": "#\/definitions\/metric" }, "x-example": [] + }, + "imageTransformations": { + "type": "array", + "description": "An array of aggregated number of image transformations.", + "items": { + "type": "object", + "$ref": "#\/definitions\/metric" + }, + "x-example": [] } }, "required": [ @@ -37216,7 +37256,8 @@ "authPhoneEstimate", "authPhoneCountryBreakdown", "databasesReads", - "databasesWrites" + "databasesWrites", + "imageTransformations" ] }, "headers": { diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index e38495629c..749f87553b 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -3261,7 +3261,7 @@ "parameters": [ { "name": "code", - "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.", + "description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.", "required": true, "type": "string", "x-example": "amex", @@ -3281,7 +3281,8 @@ "union-china-pay", "visa", "mir", - "maestro" + "maestro", + "rupay" ], "x-enum-name": "CreditCard", "x-enum-keys": [ @@ -3300,7 +3301,8 @@ "Union China Pay", "Visa", "MIR", - "Maestro" + "Maestro", + "Rupay" ], "in": "path" }, @@ -7552,7 +7554,7 @@ "tags": [ "databases" ], - "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.", + "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console.\n", "responses": { "201": { "description": "Document", @@ -10689,7 +10691,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 134, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -10800,7 +10802,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 130, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -10827,57 +10829,6 @@ ] } }, - "\/health\/queue": { - "get": { - "summary": "Get queue", - "operationId": "healthGetQueue", - "consumes": [ - "application\/json" - ], - "produces": [ - "application\/json" - ], - "tags": [ - "health" - ], - "description": "Check the Appwrite queue messaging servers are up and connection is successful.", - "responses": { - "200": { - "description": "Health Status", - "schema": { - "$ref": "#\/definitions\/healthStatus" - } - } - }, - "x-appwrite": { - "method": "getQueue", - "weight": 129, - "cookies": false, - "type": "", - "deprecated": false, - "demo": "health\/get-queue.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue.md", - "rate-limit": 0, - "rate-time": 3600, - "rate-key": "url:{url},ip:{ip}", - "scope": "health.read", - "platforms": [ - "server" - ], - "packaging": false, - "auth": { - "Project": [], - "Key": [] - } - }, - "security": [ - { - "Project": [], - "Key": [] - } - ] - } - }, "\/health\/queue\/builds": { "get": { "summary": "Get builds queue", @@ -10902,7 +10853,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 136, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -10964,7 +10915,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 135, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -11026,7 +10977,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 137, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -11097,7 +11048,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 138, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -11197,8 +11148,9 @@ "v1-audits", "v1-mails", "v1-functions", - "v1-usage", - "v1-usage-dump", + "v1-stats-resources", + "v1-stats-usage", + "v1-stats-usage-dump", "v1-webhooks", "v1-certificates", "v1-builds", @@ -11245,7 +11197,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 142, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -11307,7 +11259,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 133, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -11369,7 +11321,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 139, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -11431,7 +11383,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 140, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -11493,7 +11445,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 141, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -11531,10 +11483,10 @@ ] } }, - "\/health\/queue\/usage": { + "\/health\/queue\/stats-resources": { "get": { - "summary": "Get usage queue", - "operationId": "healthGetQueueUsage", + "summary": "Get stats resources queue", + "operationId": "healthGetQueueStatsResources", "consumes": [ "application\/json" ], @@ -11544,7 +11496,7 @@ "tags": [ "health" ], - "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "description": "Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue.", "responses": { "200": { "description": "Health Queue", @@ -11554,13 +11506,13 @@ } }, "x-appwrite": { - "method": "getQueueUsage", - "weight": 143, + "method": "getQueueStatsResources", + "weight": 142, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage.md", + "demo": "health\/get-queue-stats-resources.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-resources.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11593,10 +11545,72 @@ ] } }, - "\/health\/queue\/usage-dump": { + "\/health\/queue\/stats-usage": { + "get": { + "summary": "Get stats usage queue", + "operationId": "healthGetQueueUsage", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "health" + ], + "description": "Get the number of metrics that are waiting to be processed in the Appwrite internal queue server.", + "responses": { + "200": { + "description": "Health Queue", + "schema": { + "$ref": "#\/definitions\/healthQueue" + } + } + }, + "x-appwrite": { + "method": "getQueueUsage", + "weight": 143, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "health\/get-queue-usage.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "health.read", + "platforms": [ + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [] + } + ], + "parameters": [ + { + "name": "threshold", + "description": "Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.", + "required": false, + "type": "integer", + "format": "int32", + "default": 5000, + "in": "query" + } + ] + } + }, + "\/health\/queue\/stats-usage-dump": { "get": { "summary": "Get usage dump queue", - "operationId": "healthGetQueueUsageDump", + "operationId": "healthGetQueueStatsUsageDump", "consumes": [ "application\/json" ], @@ -11616,13 +11630,13 @@ } }, "x-appwrite": { - "method": "getQueueUsageDump", + "method": "getQueueStatsUsageDump", "weight": 144, "cookies": false, "type": "", "deprecated": false, - "demo": "health\/get-queue-usage-dump.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-usage-dump.md", + "demo": "health\/get-queue-stats-usage-dump.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/health\/get-queue-stats-usage-dump.md", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11679,7 +11693,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 132, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -11843,7 +11857,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 131, + "weight": 130, "cookies": false, "type": "", "deprecated": false, From df3746271684ad08c1b1379bf9d784122bdd5262 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 28 Feb 2025 13:20:55 +0000 Subject: [PATCH 10/14] chore: fix typing and tests --- app/config/specs/open-api3-latest-console.json | 10 ++++------ app/config/specs/swagger2-latest-console.json | 11 ++++------- src/Appwrite/Utopia/Response/Model/UsageProject.php | 9 ++++----- tests/e2e/General/UsageTest.php | 2 +- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 5b1d6f0d1e..5b31a62c23 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -36631,12 +36631,10 @@ "x-example": [] }, "imageTransformations": { - "type": "array", - "description": "An array of aggregated number of image transformations.", - "items": { - "$ref": "#\/components\/schemas\/metric" - }, - "x-example": [] + "type": "integer", + "description": "Total aggregated number of image transformations.", + "x-example": 0, + "format": "int32" } }, "required": [ diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index f13db98150..5c2dabd318 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -37218,13 +37218,10 @@ "x-example": [] }, "imageTransformations": { - "type": "array", - "description": "An array of aggregated number of image transformations.", - "items": { - "type": "object", - "$ref": "#\/definitions\/metric" - }, - "x-example": [] + "type": "integer", + "description": "Total aggregated number of image transformations.", + "x-example": 0, + "format": "int32" } }, "required": [ diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index 6f74ec561b..bdb7d6a897 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -198,11 +198,10 @@ class UsageProject extends Model 'array' => true ]) ->addRule('imageTransformations', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'An array of aggregated number of image transformations.', - 'default' => [], - 'example' => [], - 'array' => true + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of image transformations.', + 'default' => 0, + 'example' => 0, ]) ; } diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index c0d0c80eb1..9061f95a96 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -150,7 +150,7 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(29, count($response['body'])); + $this->assertEquals(30, count($response['body'])); $this->validateDates($response['body']['network']); $this->validateDates($response['body']['requests']); $this->validateDates($response['body']['users']); From 02de0d2432750728768fe6efb0a81cd21eff54d9 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 28 Feb 2025 13:29:32 +0000 Subject: [PATCH 11/14] chore: fix stats count --- tests/e2e/General/UsageTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 9061f95a96..2e13dcdb98 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -331,7 +331,7 @@ class UsageTest extends Scope ] ); - $this->assertEquals(29, count($response['body'])); + $this->assertEquals(30, count($response['body'])); $this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); $this->validateDates($response['body']['requests']); @@ -552,7 +552,7 @@ class UsageTest extends Scope ] ); - $this->assertEquals(29, count($response['body'])); + $this->assertEquals(30, count($response['body'])); $this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals(1, count($response['body']['network'])); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); From 712c33064a3bd4d7af83278dab9ad13a17ff8759 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 1 Mar 2025 17:18:44 +0000 Subject: [PATCH 12/14] chore: fix sending of transformation stats --- app/controllers/api/project.php | 4 +++- src/Appwrite/Utopia/Response/Model/UsageProject.php | 6 ++++++ tests/e2e/General/UsageTest.php | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index cf2a128939..986264e3c5 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -76,6 +76,7 @@ App::get('/v1/project/usage') METRIC_BUILDS_MB_SECONDS, METRIC_DATABASES_OPERATIONS_READS, METRIC_DATABASES_OPERATIONS_WRITES, + METRIC_FILES_IMAGES_TRANSFORMED, ] ]; @@ -364,7 +365,8 @@ App::get('/v1/project/usage') 'authPhoneTotal' => $authPhoneTotal, 'authPhoneEstimate' => $authPhoneEstimate, 'authPhoneCountryBreakdown' => $authPhoneCountryBreakdown, - 'imageTransformations' => $total[METRIC_FILES_IMAGES_TRANSFORMED], + 'imageTransformations' => $usage[METRIC_FILES_IMAGES_TRANSFORMED], + 'imageTransformationsTotal' => $total[METRIC_FILES_IMAGES_TRANSFORMED], ]), Response::MODEL_USAGE_PROJECT); }); diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index bdb7d6a897..6ac8830ac5 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -197,6 +197,12 @@ class UsageProject extends Model 'example' => [], 'array' => true ]) + ->addRule('imageTransformationsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'An array of aggregated number of image transformations.', + 'default' => 0, + 'example' => 0, + ]) ->addRule('imageTransformations', [ 'type' => self::TYPE_INTEGER, 'description' => 'Total aggregated number of image transformations.', diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 2e13dcdb98..33a1408704 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -150,7 +150,7 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(30, count($response['body'])); + $this->assertEquals(31, count($response['body'])); $this->validateDates($response['body']['network']); $this->validateDates($response['body']['requests']); $this->validateDates($response['body']['users']); @@ -331,7 +331,7 @@ class UsageTest extends Scope ] ); - $this->assertEquals(30, count($response['body'])); + $this->assertEquals(31, count($response['body'])); $this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); $this->validateDates($response['body']['requests']); @@ -552,7 +552,7 @@ class UsageTest extends Scope ] ); - $this->assertEquals(30, count($response['body'])); + $this->assertEquals(31, count($response['body'])); $this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals(1, count($response['body']['network'])); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); From aaee99e08b950affc760ee193776e0ec4d8df767 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 1 Mar 2025 17:19:55 +0000 Subject: [PATCH 13/14] chore: generate specs --- app/config/specs/open-api3-latest-console.json | 7 +++++++ app/config/specs/swagger2-latest-console.json | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 5b31a62c23..bc216226fb 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -36630,6 +36630,12 @@ }, "x-example": [] }, + "imageTransformationsTotal": { + "type": "integer", + "description": "An array of aggregated number of image transformations.", + "x-example": 0, + "format": "int32" + }, "imageTransformations": { "type": "integer", "description": "Total aggregated number of image transformations.", @@ -36667,6 +36673,7 @@ "authPhoneCountryBreakdown", "databasesReads", "databasesWrites", + "imageTransformationsTotal", "imageTransformations" ] }, diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 5c2dabd318..2dddc72802 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -37217,6 +37217,12 @@ }, "x-example": [] }, + "imageTransformationsTotal": { + "type": "integer", + "description": "An array of aggregated number of image transformations.", + "x-example": 0, + "format": "int32" + }, "imageTransformations": { "type": "integer", "description": "Total aggregated number of image transformations.", @@ -37254,6 +37260,7 @@ "authPhoneCountryBreakdown", "databasesReads", "databasesWrites", + "imageTransformationsTotal", "imageTransformations" ] }, From 6900b717da261b71bfbb928c96e8fa264f6d5ea4 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 1 Mar 2025 17:45:20 +0000 Subject: [PATCH 14/14] chore: updated to use logsdb --- app/controllers/api/project.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 986264e3c5..b267e8e51e 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -40,14 +40,18 @@ App::get('/v1/project/usage') ->param('endDate', '', new DateTimeValidator(), 'End date for the usage') ->param('period', '1d', new WhiteList(['1h', '1d']), 'Period used', true) ->inject('response') + ->inject('project') ->inject('dbForProject') + ->inject('getLogsDB') ->inject('smsRates') - ->action(function (string $startDate, string $endDate, string $period, Response $response, Database $dbForProject, array $smsRates) { + ->action(function (string $startDate, string $endDate, string $period, Response $response, Document $project, Database $dbForProject, callable $getLogsDB, array $smsRates) { $stats = $total = $usage = []; $format = 'Y-m-d 00:00:00'; $firstDay = (new DateTime($startDate))->format($format); $lastDay = (new DateTime($endDate))->format($format); + $dbForLogs = call_user_func($getLogsDB, $project); + $metrics = [ 'total' => [ METRIC_EXECUTIONS, @@ -95,9 +99,11 @@ App::get('/v1/project/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) { + Authorization::skip(function () use ($dbForProject, $dbForLogs, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) { foreach ($metrics['total'] as $metric) { - $result = $dbForProject->findOne('stats', [ + $db = ($metric === METRIC_FILES_IMAGES_TRANSFORMED) ? $dbForLogs : $dbForProject; + + $result = $db->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -105,7 +111,9 @@ App::get('/v1/project/usage') } foreach ($metrics['period'] as $metric) { - $results = $dbForProject->find('stats', [ + $db = ($metric === METRIC_FILES_IMAGES_TRANSFORMED) ? $dbForLogs : $dbForProject; + + $results = $db->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::greaterThanEqual('time', $firstDay),