feat(insights): add response models

Adds the Insight, InsightCta, and InsightCtaResult response models and
registers their model identifiers on the Response class so endpoints can
serialise insights consistently across the SDK surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jake Barnby
2026-05-01 12:40:22 +12:00
co-authored by Claude Opus 4.7
parent 1889ccdd12
commit 1c8cc6fc92
4 changed files with 233 additions and 0 deletions
+6
View File
@@ -330,6 +330,12 @@ class Response extends SwooleResponse
public const MODEL_HEALTH_CERTIFICATE = 'healthCertificate';
public const MODEL_HEALTH_STATUS_LIST = 'healthStatusList';
// Insights
public const MODEL_INSIGHT = 'insight';
public const MODEL_INSIGHT_LIST = 'insightList';
public const MODEL_INSIGHT_CTA = 'insightCta';
public const MODEL_INSIGHT_CTA_RESULT = 'insightCtaResult';
// Console
public const MODEL_CONSOLE_VARIABLES = 'consoleVariables';
public const MODEL_CONSOLE_OAUTH2_PROVIDER_PARAMETER = 'consoleOAuth2ProviderParameter';
@@ -0,0 +1,125 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class Insight extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Insight ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Insight creation date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Insight update date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$permissions', [
'type' => self::TYPE_STRING,
'description' => 'Insight permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).',
'default' => [],
'example' => ['read("any")'],
'array' => true,
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Insight type. One of databaseIndex, databasePerformance, sitePerformance, siteAccessibility, siteSeo, functionPerformance.',
'default' => '',
'example' => 'databaseIndex',
])
->addRule('severity', [
'type' => self::TYPE_STRING,
'description' => 'Insight severity. One of info, warning, critical.',
'default' => 'info',
'example' => 'warning',
])
->addRule('resourceType', [
'type' => self::TYPE_STRING,
'description' => 'Type of the resource the insight is about. Plural noun, e.g. databases, sites, functions.',
'default' => '',
'example' => 'databases',
])
->addRule('resourceId', [
'type' => self::TYPE_STRING,
'description' => 'ID of the resource the insight is about.',
'default' => '',
'example' => 'main',
])
->addRule('resourceInternalId', [
'type' => self::TYPE_STRING,
'description' => 'Internal ID of the resource the insight is about.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('title', [
'type' => self::TYPE_STRING,
'description' => 'Insight title.',
'default' => '',
'example' => 'Missing index on collection orders',
])
->addRule('summary', [
'type' => self::TYPE_STRING,
'description' => 'Short markdown summary describing the insight.',
'default' => '',
'example' => 'Queries against `orders.status` are scanning the full collection.',
])
->addRule('payload', [
'type' => self::TYPE_JSON,
'description' => 'Type-specific structured payload for the insight.',
'default' => new \stdClass(),
'example' => ['databaseId' => 'main', 'collectionId' => 'orders'],
])
->addRule('ctas', [
'type' => Response::MODEL_INSIGHT_CTA,
'description' => 'List of call-to-action buttons attached to this insight.',
'default' => [],
'example' => [],
'array' => true,
])
->addRule('analyzedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Time the insight was analyzed in ISO 8601 format.',
'default' => null,
'example' => self::TYPE_DATETIME_EXAMPLE,
'required' => false,
])
->addRule('dismissedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Time the insight was dismissed in ISO 8601 format. Empty when not dismissed.',
'default' => null,
'example' => self::TYPE_DATETIME_EXAMPLE,
'required' => false,
])
->addRule('dismissedBy', [
'type' => self::TYPE_STRING,
'description' => 'User ID that dismissed the insight. Empty when not dismissed.',
'default' => '',
'example' => '5e5ea5c16897e',
'required' => false,
]);
}
public function getName(): string
{
return 'Insight';
}
public function getType(): string
{
return Response::MODEL_INSIGHT;
}
}
@@ -0,0 +1,48 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class InsightCta extends Model
{
public function __construct()
{
$this
->addRule('id', [
'type' => self::TYPE_STRING,
'description' => 'CTA identifier, unique within the parent insight.',
'default' => '',
'example' => 'createIndex',
])
->addRule('label', [
'type' => self::TYPE_STRING,
'description' => 'Human-readable label for the CTA, used in UI.',
'default' => '',
'example' => 'Create missing index',
])
->addRule('action', [
'type' => self::TYPE_STRING,
'description' => 'Registered server-side action name to execute when this CTA is triggered.',
'default' => '',
'example' => 'databases.createIndex',
])
->addRule('params', [
'type' => self::TYPE_JSON,
'description' => 'Parameter map passed to the action when this CTA is triggered.',
'default' => new \stdClass(),
'example' => ['databaseId' => 'main', 'collectionId' => 'orders', 'key' => '_idx_status'],
]);
}
public function getName(): string
{
return 'InsightCta';
}
public function getType(): string
{
return Response::MODEL_INSIGHT_CTA;
}
}
@@ -0,0 +1,54 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class InsightCtaResult extends Model
{
public function __construct()
{
$this
->addRule('insightId', [
'type' => self::TYPE_STRING,
'description' => 'ID of the insight the CTA was triggered against.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('ctaId', [
'type' => self::TYPE_STRING,
'description' => 'ID of the CTA that was triggered.',
'default' => '',
'example' => 'createIndex',
])
->addRule('action', [
'type' => self::TYPE_STRING,
'description' => 'Registered server-side action that was executed.',
'default' => '',
'example' => 'databases.createIndex',
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Outcome of the CTA execution. One of succeeded, failed.',
'default' => 'succeeded',
'example' => 'succeeded',
])
->addRule('result', [
'type' => self::TYPE_JSON,
'description' => 'Action-specific result data. May reference the resource that was created or updated.',
'default' => new \stdClass(),
'example' => ['indexId' => '_idx_status'],
]);
}
public function getName(): string
{
return 'InsightCtaResult';
}
public function getType(): string
{
return Response::MODEL_INSIGHT_CTA_RESULT;
}
}