diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 02f8524..b60c933 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -166,8 +166,52 @@ "Alert Channels" ], "summary": "List active alert channels for the authenticated org", + "description": "Supports filtering by `type` (channel integration), `managedBy` (creating surface), and `search` (case-insensitive contains on name). Unrecognised query parameters are silently ignored — pin to the documented set above.", "operationId": "list_14", "parameters": [ + { + "name": "type", + "in": "query", + "description": "Filter by channel integration type (e.g. SLACK, WEBHOOK, EMAIL)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "pagerduty", + "opsgenie", + "teams", + "discord" + ] + } + }, + { + "name": "managedBy", + "in": "query", + "description": "Filter by managed-by source (DASHBOARD, CLI, TERRAFORM, MCP, API)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive contains-match on the channel name", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "pageable", "in": "query", @@ -6374,17 +6418,27 @@ "Monitors" ], "summary": "List monitors for the authenticated org", + "description": "Supports filtering by `enabled`, `status` (alias active|paused for enabled), `type`, `managedBy`, `tag` / `tags`, `search`, and `environmentId`. Unrecognised query parameters are silently ignored (Spring's default binding behaviour) — pin to the documented set above.", "operationId": "list_8", "parameters": [ { "name": "enabled", "in": "query", - "description": "Filter by enabled state", + "description": "Filter by enabled state (true/false)", "required": false, "schema": { "type": "boolean" } }, + { + "name": "status", + "in": "query", + "description": "Lifecycle status alias: 'active' (enabled=true) or 'paused' (enabled=false). Ignored when ?enabled is also supplied.", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "type", "in": "query", @@ -6421,7 +6475,16 @@ { "name": "tags", "in": "query", - "description": "Filter by tag names, comma-separated (e.g. prod,critical)", + "description": "Filter by tag names, comma-separated (e.g. prod,critical); OR semantics", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "tag", + "in": "query", + "description": "Filter by a single tag name (alias for ?tags=); merged with ?tags using OR semantics", "required": false, "schema": { "type": "string" @@ -21729,6 +21792,18 @@ "description": "SHA-256 hash of the channel config; use for change detection", "nullable": true }, + "managedBy": { + "type": "string", + "description": "Source that created/owns this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on channels created before this attribution column existed.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + }, "lastDeliveryAt": { "type": "string", "description": "Timestamp of the most recent delivery attempt", @@ -22929,6 +23004,18 @@ "$ref": "#/components/schemas/WebhookChannelConfig" } ] + }, + "managedBy": { + "type": "string", + "description": "Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } } }, @@ -23189,12 +23276,14 @@ "maxLength": 100, "minLength": 0, "type": "string", - "description": "iCal RRULE for recurring windows (max 100 chars); null for one-time", + "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", "nullable": true }, "reason": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Human-readable reason for the maintenance", + "description": "Human-readable reason for the maintenance (max 500 chars)", "nullable": true }, "suppressAlerts": { @@ -23241,7 +23330,6 @@ "CreateMonitorRequest": { "required": [ "config", - "managedBy", "name", "type" ], @@ -23309,7 +23397,8 @@ }, "managedBy": { "type": "string", - "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Use the value matching your surface so audit logs, drift detection, and analytics attribute correctly.", + "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", + "nullable": true, "enum": [ "DASHBOARD", "CLI", @@ -23510,6 +23599,18 @@ "description": "Recovery cooldown in minutes after group incident resolves (0–60)", "format": "int32", "nullable": true + }, + "managedBy": { + "type": "string", + "description": "Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } }, "description": "Request body for creating a resource group" @@ -23811,6 +23912,18 @@ "REVIEW", "AUTOMATIC" ] + }, + "managedBy": { + "type": "string", + "description": "Source creating this page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } } }, @@ -26436,7 +26549,7 @@ }, "repeatRule": { "type": "string", - "description": "iCal RRULE for recurring windows; null for one-time", + "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", "nullable": true }, "reason": { @@ -27271,6 +27384,18 @@ "description": "Alert channel IDs linked to this monitor; populated on single-monitor responses", "format": "uuid" } + }, + "currentStatus": { + "type": "string", + "description": "Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + "nullable": true, + "enum": [ + "up", + "degraded", + "down", + "paused", + "unknown" + ] } }, "description": "Full monitor representation" @@ -28461,6 +28586,18 @@ "$ref": "#/components/schemas/ResourceGroupMemberDto" } }, + "managedBy": { + "type": "string", + "description": "Source that created/owns this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on groups created before this attribution column existed.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + }, "createdAt": { "type": "string", "description": "Timestamp when the group was created", @@ -28721,6 +28858,7 @@ "up", "degraded", "down", + "paused", "unknown" ] }, @@ -31056,6 +31194,18 @@ "UNDER_MAINTENANCE" ] }, + "managedBy": { + "type": "string", + "description": "Source that created/owns this status page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on pages created before this attribution column existed.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + }, "createdAt": { "type": "string", "format": "date-time" @@ -32999,6 +33149,18 @@ "$ref": "#/components/schemas/WebhookChannelConfig" } ] + }, + "managedBy": { + "type": "string", + "description": "New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } } }, @@ -33239,7 +33401,7 @@ "properties": { "monitorId": { "type": "string", - "description": "Monitor to attach this maintenance window to; null preserves current", + "description": "Monitor this window applies to; null switches the window to org-wide", "format": "uuid", "nullable": true }, @@ -33257,17 +33419,19 @@ "maxLength": 100, "minLength": 0, "type": "string", - "description": "Updated iCal RRULE; null clears the repeat rule", + "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored); null clears it", "nullable": true }, "reason": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Updated reason; null clears the existing reason", + "description": "Updated reason (max 500 chars); null clears the existing reason", "nullable": true }, "suppressAlerts": { "type": "boolean", - "description": "Whether to suppress alerts; null preserves current", + "description": "Whether to suppress alerts during this window; null defaults to true", "nullable": true } } @@ -33605,6 +33769,18 @@ "description": "Recovery cooldown in minutes; null clears", "format": "int32", "nullable": true + }, + "managedBy": { + "type": "string", + "description": "New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } }, "description": "Request body for updating a resource group" @@ -33809,6 +33985,18 @@ "REVIEW", "AUTOMATIC" ] + }, + "managedBy": { + "type": "string", + "description": "New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] } } }, diff --git a/skills/devhelm-communicate/references/_generated/status-pages.fields.md b/skills/devhelm-communicate/references/_generated/status-pages.fields.md index 9541826..69b201d 100644 --- a/skills/devhelm-communicate/references/_generated/status-pages.fields.md +++ b/skills/devhelm-communicate/references/_generated/status-pages.fields.md @@ -14,6 +14,7 @@ | `visibility` | "PUBLIC" \| "PASSWORD" \| "IP_RESTRICTED" | | ✓ | Page visibility: PUBLIC, PASSWORD, or IP_RESTRICTED (default: PUBLIC) | | `enabled` | boolean | | ✓ | Whether the page is enabled (default: true) | | `incidentMode` | "MANUAL" \| "REVIEW" \| "AUTOMATIC" | | ✓ | Incident mode: MANUAL, REVIEW, or AUTOMATIC (default: AUTOMATIC) | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source creating this page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. | ## `UpdateStatusPageRequest` @@ -25,6 +26,7 @@ | `visibility` | "PUBLIC" \| "PASSWORD" \| "IP_RESTRICTED" | | ✓ | Page visibility; null preserves current | | `enabled` | boolean | | ✓ | Whether the page is enabled; null preserves current | | `incidentMode` | "MANUAL" \| "REVIEW" \| "AUTOMATIC" | | ✓ | Incident mode: MANUAL, REVIEW, or AUTOMATIC; null preserves current | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. | ## `StatusPageDto` (response shape) @@ -43,6 +45,7 @@ | `componentCount` | integer (int32) | | ✓ | | | `subscriberCount` | integer (int64) | | ✓ | | | `overallStatus` | "OPERATIONAL" \| "DEGRADED_PERFORMANCE" \| "PARTIAL_OUTAGE" \| "MAJOR_OUTAGE" \| "UNDER_MAINTENANCE" | | ✓ | | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source that created/owns this status page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on pages created before this attribution column existed. | | `createdAt` | string (date-time) | ✓ | | | | `updatedAt` | string (date-time) | ✓ | | | diff --git a/skills/devhelm-configure/references/_generated/alert-channels.fields.md b/skills/devhelm-configure/references/_generated/alert-channels.fields.md index e49e8c9..e85c6f1 100644 --- a/skills/devhelm-configure/references/_generated/alert-channels.fields.md +++ b/skills/devhelm-configure/references/_generated/alert-channels.fields.md @@ -9,6 +9,7 @@ |---|---|---|---|---| | `name` | string | ✓ | | Human-readable name for this alert channel | | `config` | any | ✓ | | | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. | ## `UpdateAlertChannelRequest` @@ -16,6 +17,7 @@ |---|---|---|---|---| | `name` | string | ✓ | | New channel name (full replacement, not partial update) | | `config` | any | ✓ | | | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. | ## `AlertChannelDto` (response shape) @@ -28,6 +30,7 @@ | `createdAt` | string (date-time) | ✓ | | Timestamp when the channel was created | | `updatedAt` | string (date-time) | ✓ | | Timestamp when the channel was last updated | | `configHash` | string | | ✓ | SHA-256 hash of the channel config; use for change detection | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source that created/owns this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on channels created before this attribution column existed. | | `lastDeliveryAt` | string (date-time) | | ✓ | Timestamp of the most recent delivery attempt | | `lastDeliveryStatus` | string | | ✓ | Outcome of the most recent delivery (SUCCESS, FAILED, etc.) | diff --git a/skills/devhelm-configure/references/_generated/monitors.fields.md b/skills/devhelm-configure/references/_generated/monitors.fields.md index 926e687..7dcf172 100644 --- a/skills/devhelm-configure/references/_generated/monitors.fields.md +++ b/skills/devhelm-configure/references/_generated/monitors.fields.md @@ -13,7 +13,7 @@ | `frequencySeconds` | integer (int32) | | ✓ | Check frequency in seconds (30–86400); null defaults to plan minimum (60s on most paid plans) | | `enabled` | boolean | | ✓ | Whether the monitor is active (default: true) | | `regions` | string[] | | ✓ | Probe regions to run checks from, e.g. us-east, eu-west | -| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | ✓ | | Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Use the value matching your surface so audit logs, drift detection, and analytics attribute correctly. | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly. | | `environmentId` | string (uuid) | | ✓ | Environment to associate with this monitor | | `assertions` | CreateAssertionRequest[] | | ✓ | Assertions to evaluate against each check result | | `auth` | any | | ✓ | | @@ -62,4 +62,5 @@ | `auth` | any | | ✓ | | | `incidentPolicy` | any | | ✓ | | | `alertChannelIds` | string (uuid)[] | | ✓ | Alert channel IDs linked to this monitor; populated on single-monitor responses | +| `currentStatus` | "up" \| "degraded" \| "down" \| "paused" \| "unknown" | | ✓ | Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet | diff --git a/skills/devhelm-configure/references/_generated/resource-groups.fields.md b/skills/devhelm-configure/references/_generated/resource-groups.fields.md index 75cd0d2..e95a7a8 100644 --- a/skills/devhelm-configure/references/_generated/resource-groups.fields.md +++ b/skills/devhelm-configure/references/_generated/resource-groups.fields.md @@ -20,6 +20,7 @@ | `suppressMemberAlerts` | boolean | | ✓ | Suppress member-level alert notifications when group manages alerting | | `confirmationDelaySeconds` | integer (int32) | | ✓ | Confirmation delay in seconds before group incident creation (0–600) | | `recoveryCooldownMinutes` | integer (int32) | | ✓ | Recovery cooldown in minutes after group incident resolves (0–60) | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. | ## `UpdateResourceGroupRequest` @@ -38,6 +39,7 @@ | `suppressMemberAlerts` | boolean | | ✓ | Suppress member-level alert notifications; null preserves current value | | `confirmationDelaySeconds` | integer (int32) | | ✓ | Confirmation delay in seconds; null clears | | `recoveryCooldownMinutes` | integer (int32) | | ✓ | Recovery cooldown in minutes; null clears | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. | ## `ResourceGroupDto` (response shape) @@ -61,6 +63,7 @@ | `recoveryCooldownMinutes` | integer (int32) | | ✓ | Cooldown minutes after group incident resolves before a new one can open | | `health` | ResourceGroupHealthDto | ✓ | | | | `members` | ResourceGroupMemberDto[] | | ✓ | Member list with individual statuses; populated on detail GET only | +| `managedBy` | "DASHBOARD" \| "CLI" \| "TERRAFORM" \| "MCP" \| "API" | | ✓ | Source that created/owns this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on groups created before this attribution column existed. | | `createdAt` | string (date-time) | ✓ | | Timestamp when the group was created | | `updatedAt` | string (date-time) | ✓ | | Timestamp when the group was last updated | diff --git a/src/lib/api-zod.generated.ts b/src/lib/api-zod.generated.ts index f427af5..5968a5d 100644 --- a/src/lib/api-zod.generated.ts +++ b/src/lib/api-zod.generated.ts @@ -75,6 +75,9 @@ const CreateAlertChannelRequest = z TeamsChannelConfig, WebhookChannelConfig, ]), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), }) .strict(); const UpdateAlertChannelRequest = z @@ -89,6 +92,9 @@ const UpdateAlertChannelRequest = z TeamsChannelConfig, WebhookChannelConfig, ]), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), }) .strict(); const TestAlertChannelRequest = z @@ -198,7 +204,7 @@ const CreateMaintenanceWindowRequest = z startsAt: z.string().datetime({ offset: true }), endsAt: z.string().datetime({ offset: true }), repeatRule: z.string().min(0).max(100).nullish(), - reason: z.string().nullish(), + reason: z.string().min(0).max(500).nullish(), suppressAlerts: z.boolean().nullish(), }) .strict(); @@ -208,7 +214,7 @@ const UpdateMaintenanceWindowRequest = z startsAt: z.string().datetime({ offset: true }), endsAt: z.string().datetime({ offset: true }), repeatRule: z.string().min(0).max(100).nullish(), - reason: z.string().nullish(), + reason: z.string().min(0).max(500).nullish(), suppressAlerts: z.boolean().nullish(), }) .strict(); @@ -672,7 +678,9 @@ const CreateMonitorRequest = z frequencySeconds: z.number().int().nullish(), enabled: z.boolean().nullish(), regions: z.array(z.string()).nullish(), - managedBy: z.enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), environmentId: z.string().uuid().nullish(), assertions: z.array(CreateAssertionRequest).nullish(), auth: MonitorAuthConfig.nullish(), @@ -895,6 +903,9 @@ const CreateResourceGroupRequest = z suppressMemberAlerts: z.boolean().nullish(), confirmationDelaySeconds: z.number().int().gte(0).lte(600).nullish(), recoveryCooldownMinutes: z.number().int().gte(0).lte(60).nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), }) .strict(); const UpdateResourceGroupRequest = z @@ -912,6 +923,9 @@ const UpdateResourceGroupRequest = z suppressMemberAlerts: z.boolean().nullish(), confirmationDelaySeconds: z.number().int().gte(0).lte(600).nullish(), recoveryCooldownMinutes: z.number().int().gte(0).lte(60).nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), }) .strict(); const AddResourceGroupMemberRequest = z @@ -1018,6 +1032,9 @@ const CreateStatusPageRequest = z visibility: z.enum(["PUBLIC", "PASSWORD", "IP_RESTRICTED"]).nullish(), enabled: z.boolean().nullish(), incidentMode: z.enum(["MANUAL", "REVIEW", "AUTOMATIC"]).nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), }) .strict(); const UpdateStatusPageRequest = z @@ -1028,6 +1045,9 @@ const UpdateStatusPageRequest = z visibility: z.enum(["PUBLIC", "PASSWORD", "IP_RESTRICTED"]).nullable(), enabled: z.boolean().nullable(), incidentMode: z.enum(["MANUAL", "REVIEW", "AUTOMATIC"]).nullable(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullable(), }) .partial() .strict(); @@ -1287,6 +1307,9 @@ const AlertChannelDto = z createdAt: z.string().datetime({ offset: true }), updatedAt: z.string().datetime({ offset: true }), configHash: z.string().nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), lastDeliveryAt: z.string().datetime({ offset: true }).nullish(), lastDeliveryStatus: z.string().nullish(), }) @@ -2231,6 +2254,9 @@ const MonitorDto = z auth: MonitorAuthConfig.nullish(), incidentPolicy: IncidentPolicyDto.nullish(), alertChannelIds: z.array(z.string().uuid()).nullish(), + currentStatus: z + .enum(["up", "degraded", "down", "paused", "unknown"]) + .nullish(), }) .strict(); const MonitorReference = z @@ -2401,13 +2427,16 @@ const ResourceGroupDto = z recoveryCooldownMinutes: z.number().int().nullish(), health: ResourceGroupHealthDto, members: z.array(ResourceGroupMemberDto).nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), createdAt: z.string().datetime({ offset: true }), updatedAt: z.string().datetime({ offset: true }), }) .strict(); const ResultSummaryDto = z .object({ - currentStatus: z.enum(["up", "degraded", "down", "unknown"]), + currentStatus: z.enum(["up", "degraded", "down", "paused", "unknown"]), latestPerRegion: z.array(RegionStatusDto), chartData: z.array(ChartBucketDto), uptime24h: z.number().nullish(), @@ -2822,6 +2851,9 @@ const StatusPageDto = z "UNDER_MAINTENANCE", ]) .nullish(), + managedBy: z + .enum(["DASHBOARD", "CLI", "TERRAFORM", "MCP", "API"]) + .nullish(), createdAt: z.string().datetime({ offset: true }), updatedAt: z.string().datetime({ offset: true }), }) diff --git a/src/lib/api.generated.ts b/src/lib/api.generated.ts index 2f2f685..ceba7c8 100644 --- a/src/lib/api.generated.ts +++ b/src/lib/api.generated.ts @@ -11,7 +11,10 @@ export interface paths { path?: never; cookie?: never; }; - /** List active alert channels for the authenticated org */ + /** + * List active alert channels for the authenticated org + * @description Supports filtering by `type` (channel integration), `managedBy` (creating surface), and `search` (case-insensitive contains on name). Unrecognised query parameters are silently ignored — pin to the documented set above. + */ get: operations["list_14"]; put?: never; /** Create a new alert channel with encrypted config */ @@ -757,7 +760,10 @@ export interface paths { path?: never; cookie?: never; }; - /** List monitors for the authenticated org */ + /** + * List monitors for the authenticated org + * @description Supports filtering by `enabled`, `status` (alias active|paused for enabled), `type`, `managedBy`, `tag` / `tags`, `search`, and `environmentId`. Unrecognised query parameters are silently ignored (Spring's default binding behaviour) — pin to the documented set above. + */ get: operations["list_8"]; put?: never; /** Create a new monitor */ @@ -2502,6 +2508,11 @@ export interface components { updatedAt: string; /** @description SHA-256 hash of the channel config; use for change detection */ configHash?: string | null; + /** + * @description Source that created/owns this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on channels created before this attribution column existed. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; /** * Format: date-time * @description Timestamp of the most recent delivery attempt @@ -3086,6 +3097,11 @@ export interface components { /** @description Human-readable name for this alert channel */ name: string; config: components["schemas"]["DiscordChannelConfig"] | components["schemas"]["EmailChannelConfig"] | components["schemas"]["OpsGenieChannelConfig"] | components["schemas"]["PagerDutyChannelConfig"] | components["schemas"]["SlackChannelConfig"] | components["schemas"]["TeamsChannelConfig"] | components["schemas"]["WebhookChannelConfig"]; + /** + * @description Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; CreateApiKeyRequest: { /** @description Human-readable name to identify this API key */ @@ -3146,9 +3162,9 @@ export interface components { * @description Scheduled end of the maintenance window (ISO 8601) */ endsAt: string; - /** @description iCal RRULE for recurring windows (max 100 chars); null for one-time */ + /** @description Reserved: iCal RRULE for recurring windows (stored but not yet honored) */ repeatRule?: string | null; - /** @description Human-readable reason for the maintenance */ + /** @description Human-readable reason for the maintenance (max 500 chars) */ reason?: string | null; /** @description Whether to suppress alerts during this window (default: true) */ suppressAlerts?: boolean | null; @@ -3188,10 +3204,10 @@ export interface components { /** @description Probe regions to run checks from, e.g. us-east, eu-west */ regions?: string[] | null; /** - * @description Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Use the value matching your surface so audit logs, drift detection, and analytics attribute correctly. - * @enum {string} + * @description Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly. + * @enum {string|null} */ - managedBy: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API"; + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; /** * Format: uuid * @description Environment to associate with this monitor @@ -3269,6 +3285,11 @@ export interface components { * @description Recovery cooldown in minutes after group incident resolves (0–60) */ recoveryCooldownMinutes?: number | null; + /** + * @description Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; CreateSecretRequest: { /** @description Unique secret key within the workspace (max 255 chars) */ @@ -3396,6 +3417,11 @@ export interface components { * @enum {string|null} */ incidentMode?: "MANUAL" | "REVIEW" | "AUTOMATIC" | null; + /** + * @description Source creating this page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; /** @description Request body for creating a tag */ CreateTagRequest: { @@ -4613,7 +4639,7 @@ export interface components { * @description Scheduled end of the maintenance window */ endsAt: string; - /** @description iCal RRULE for recurring windows; null for one-time */ + /** @description Reserved: iCal RRULE for recurring windows (stored but not yet honored) */ repeatRule?: string | null; /** @description Human-readable reason for the maintenance */ reason?: string | null; @@ -4859,6 +4885,11 @@ export interface components { incidentPolicy?: components["schemas"]["IncidentPolicyDto"] | null; /** @description Alert channel IDs linked to this monitor; populated on single-monitor responses */ alertChannelIds?: string[] | null; + /** + * @description Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet + * @enum {string|null} + */ + currentStatus?: "up" | "degraded" | "down" | "paused" | "unknown" | null; }; /** @description Monitors that reference this secret; null on create/update responses */ MonitorReference: { @@ -5437,6 +5468,11 @@ export interface components { health: components["schemas"]["ResourceGroupHealthDto"]; /** @description Member list with individual statuses; populated on detail GET only */ members?: components["schemas"]["ResourceGroupMemberDto"][] | null; + /** + * @description Source that created/owns this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on groups created before this attribution column existed. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; /** * Format: date-time * @description Timestamp when the group was created @@ -5586,7 +5622,7 @@ export interface components { * @description Derived current status across all regions * @enum {string} */ - currentStatus: "up" | "degraded" | "down" | "unknown"; + currentStatus: "up" | "degraded" | "down" | "paused" | "unknown"; /** @description Latest check result per region */ latestPerRegion: components["schemas"]["RegionStatusDto"][]; /** @description Time-bucketed chart data for the requested window */ @@ -6453,6 +6489,11 @@ export interface components { subscriberCount?: number | null; /** @enum {string|null} */ overallStatus?: "OPERATIONAL" | "DEGRADED_PERFORMANCE" | "PARTIAL_OUTAGE" | "MAJOR_OUTAGE" | "UNDER_MAINTENANCE" | null; + /** + * @description Source that created/owns this status page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on pages created before this attribution column existed. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ @@ -7106,6 +7147,11 @@ export interface components { /** @description New channel name (full replacement, not partial update) */ name: string; config: components["schemas"]["DiscordChannelConfig"] | components["schemas"]["EmailChannelConfig"] | components["schemas"]["OpsGenieChannelConfig"] | components["schemas"]["PagerDutyChannelConfig"] | components["schemas"]["SlackChannelConfig"] | components["schemas"]["TeamsChannelConfig"] | components["schemas"]["WebhookChannelConfig"]; + /** + * @description New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; /** @description Request body for updating alert sensitivity on a service subscription */ UpdateAlertSensitivityRequest: { @@ -7144,7 +7190,7 @@ export interface components { UpdateMaintenanceWindowRequest: { /** * Format: uuid - * @description Monitor to attach this maintenance window to; null preserves current + * @description Monitor this window applies to; null switches the window to org-wide */ monitorId?: string | null; /** @@ -7157,11 +7203,11 @@ export interface components { * @description Updated end time (ISO 8601) */ endsAt: string; - /** @description Updated iCal RRULE; null clears the repeat rule */ + /** @description Reserved: iCal RRULE for recurring windows (stored but not yet honored); null clears it */ repeatRule?: string | null; - /** @description Updated reason; null clears the existing reason */ + /** @description Updated reason (max 500 chars); null clears the existing reason */ reason?: string | null; - /** @description Whether to suppress alerts; null preserves current */ + /** @description Whether to suppress alerts during this window; null defaults to true */ suppressAlerts?: boolean | null; }; UpdateMonitorAuthRequest: { @@ -7277,6 +7323,11 @@ export interface components { * @description Recovery cooldown in minutes; null clears */ recoveryCooldownMinutes?: number | null; + /** + * @description New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; UpdateSecretRequest: { /** @description New secret value, stored encrypted (max 32KB) */ @@ -7360,6 +7411,11 @@ export interface components { * @enum {string|null} */ incidentMode?: "MANUAL" | "REVIEW" | "AUTOMATIC" | null; + /** + * @description New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value. + * @enum {string|null} + */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API" | null; }; /** @description Request body for updating a tag; null fields are left unchanged */ UpdateTagRequest: { @@ -7575,6 +7631,12 @@ export interface operations { list_14: { parameters: { query: { + /** @description Filter by channel integration type (e.g. SLACK, WEBHOOK, EMAIL) */ + type?: "email" | "webhook" | "slack" | "pagerduty" | "opsgenie" | "teams" | "discord"; + /** @description Filter by managed-by source (DASHBOARD, CLI, TERRAFORM, MCP, API) */ + managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API"; + /** @description Case-insensitive contains-match on the channel name */ + search?: string; pageable: components["schemas"]["Pageable"]; }; header?: never; @@ -12785,14 +12847,18 @@ export interface operations { list_8: { parameters: { query: { - /** @description Filter by enabled state */ + /** @description Filter by enabled state (true/false) */ enabled?: boolean; + /** @description Lifecycle status alias: 'active' (enabled=true) or 'paused' (enabled=false). Ignored when ?enabled is also supplied. */ + status?: string; /** @description Filter by monitor type */ type?: "HTTP" | "DNS" | "MCP_SERVER" | "TCP" | "ICMP" | "HEARTBEAT"; /** @description Filter by managed-by source */ managedBy?: "DASHBOARD" | "CLI" | "TERRAFORM" | "MCP" | "API"; - /** @description Filter by tag names, comma-separated (e.g. prod,critical) */ + /** @description Filter by tag names, comma-separated (e.g. prod,critical); OR semantics */ tags?: string; + /** @description Filter by a single tag name (alias for ?tags=); merged with ?tags using OR semantics */ + tag?: string; /** @description Case-insensitive name search */ search?: string; /** @description Filter by environment ID */ diff --git a/src/lib/descriptions.generated.ts b/src/lib/descriptions.generated.ts index fd881af..59908f9 100644 --- a/src/lib/descriptions.generated.ts +++ b/src/lib/descriptions.generated.ts @@ -9,7 +9,7 @@ export const fieldDescriptions: Record> = "frequencySeconds": "Check frequency in seconds (30–86400); null defaults to plan minimum (60s on most paid plans)", "enabled": "Whether the monitor is active (default: true)", "regions": "Probe regions to run checks from, e.g. us-east, eu-west", - "managedBy": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Use the value matching your surface so audit logs, drift detection, and analytics attribute correctly.", + "managedBy": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", "environmentId": "Environment to associate with this monitor", "assertions": "Assertions to evaluate against each check result", "alertChannelIds": "Alert channels to notify when this monitor triggers" @@ -33,10 +33,12 @@ export const fieldDescriptions: Record> = "body": "Detailed description or context for the incident" }, "CreateAlertChannelRequest": { - "name": "Human-readable name for this alert channel" + "name": "Human-readable name for this alert channel", + "managedBy": "Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted." }, "UpdateAlertChannelRequest": { - "name": "New channel name (full replacement, not partial update)" + "name": "New channel name (full replacement, not partial update)", + "managedBy": "New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value." }, "CreateNotificationPolicyRequest": { "name": "Human-readable name for this policy", @@ -88,7 +90,8 @@ export const fieldDescriptions: Record> = "healthThresholdValue": "Health threshold value: count (0+) or percentage (0–100)", "suppressMemberAlerts": "Suppress member-level alert notifications when group manages alerting", "confirmationDelaySeconds": "Confirmation delay in seconds before group incident creation (0–600)", - "recoveryCooldownMinutes": "Recovery cooldown in minutes after group incident resolves (0–60)" + "recoveryCooldownMinutes": "Recovery cooldown in minutes after group incident resolves (0–60)", + "managedBy": "Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted." }, "UpdateResourceGroupRequest": { "name": "Human-readable name for this group", @@ -102,7 +105,8 @@ export const fieldDescriptions: Record> = "healthThresholdValue": "Health threshold value; null disables threshold", "suppressMemberAlerts": "Suppress member-level alert notifications; null preserves current value", "confirmationDelaySeconds": "Confirmation delay in seconds; null clears", - "recoveryCooldownMinutes": "Recovery cooldown in minutes; null clears" + "recoveryCooldownMinutes": "Recovery cooldown in minutes; null clears", + "managedBy": "New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value." }, "CreateWebhookEndpointRequest": { "url": "HTTPS endpoint that receives webhook event payloads", @@ -126,17 +130,17 @@ export const fieldDescriptions: Record> = "monitorId": "Monitor to attach this maintenance window to; null for org-wide", "startsAt": "Scheduled start of the maintenance window (ISO 8601)", "endsAt": "Scheduled end of the maintenance window (ISO 8601)", - "repeatRule": "iCal RRULE for recurring windows (max 100 chars); null for one-time", - "reason": "Human-readable reason for the maintenance", + "repeatRule": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", + "reason": "Human-readable reason for the maintenance (max 500 chars)", "suppressAlerts": "Whether to suppress alerts during this window (default: true)" }, "UpdateMaintenanceWindowRequest": { - "monitorId": "Monitor to attach this maintenance window to; null preserves current", + "monitorId": "Monitor this window applies to; null switches the window to org-wide", "startsAt": "Updated start time (ISO 8601)", "endsAt": "Updated end time (ISO 8601)", - "repeatRule": "Updated iCal RRULE; null clears the repeat rule", - "reason": "Updated reason; null clears the existing reason", - "suppressAlerts": "Whether to suppress alerts; null preserves current" + "repeatRule": "Reserved: iCal RRULE for recurring windows (stored but not yet honored); null clears it", + "reason": "Updated reason (max 500 chars); null clears the existing reason", + "suppressAlerts": "Whether to suppress alerts during this window; null defaults to true" }, "ResolveIncidentRequest": { "body": "Optional resolution message or post-mortem notes" diff --git a/src/lib/yaml/transform.ts b/src/lib/yaml/transform.ts index 0979184..0e3d4f8 100644 --- a/src/lib/yaml/transform.ts +++ b/src/lib/yaml/transform.ts @@ -43,7 +43,11 @@ export function toCreateSecretRequest(secret: YamlSecret): Schemas['CreateSecret // ── Alert Channel ────────────────────────────────────────────────────── export function toCreateAlertChannelRequest(channel: YamlAlertChannel): Schemas['CreateAlertChannelRequest'] { - return {name: channel.name, config: channel.config as Schemas['CreateAlertChannelRequest']['config']} + return { + name: channel.name, + config: channel.config as Schemas['CreateAlertChannelRequest']['config'], + managedBy: 'CLI', + } } // ── Notification Policy ──────────────────────────────────────────────── @@ -121,6 +125,7 @@ export function toCreateResourceGroupRequest( suppressMemberAlerts: group.suppressMemberAlerts, confirmationDelaySeconds: group.confirmationDelaySeconds ?? null, recoveryCooldownMinutes: group.recoveryCooldownMinutes ?? null, + managedBy: 'CLI', } } @@ -304,6 +309,7 @@ export function toCreateStatusPageRequest(page: YamlStatusPage): Schemas['Create visibility: page.visibility ?? null, enabled: page.enabled ?? null, incidentMode: page.incidentMode ?? null, + managedBy: 'CLI', } } diff --git a/test/commands/monitors-test-config.test.ts b/test/commands/monitors-test-config.test.ts index 51ee01b..a02b16b 100644 --- a/test/commands/monitors-test-config.test.ts +++ b/test/commands/monitors-test-config.test.ts @@ -62,12 +62,17 @@ describe('monitors test --config', () => { }) test('reports a clear validation error for a malformed config', () => { - const cfg = write('bad.yml', 'name: bad\ntype: HTTP\nconfig:\n url: not-a-url\n') + // `name` is required on CreateMonitorRequest; omitting it must surface + // a typed Zod error before the request hits the API. We used to assert + // on the missing `managedBy` field, but that became optional in the + // API spec (server defaults to "API" / surface-injected value), so we + // pivot to `name` which remains required. + const cfg = write('bad.yml', 'type: HTTP\nconfig:\n url: https://example.com\n method: GET\n') const out = run( `monitors test --config ${cfg} --api-token devhelm-dev-token --api-url http://127.0.0.1:9999`, ) expect(out).toContain('failed CreateMonitorRequest validation') - expect(out).toContain('managedBy') + expect(out).toContain('name') }) test('errors when the config file does not exist', () => { diff --git a/test/yaml/spec-field-parity.test.ts b/test/yaml/spec-field-parity.test.ts index 81ddc9e..0bca010 100644 --- a/test/yaml/spec-field-parity.test.ts +++ b/test/yaml/spec-field-parity.test.ts @@ -66,15 +66,17 @@ const YAML_ONLY_FIELDS: Record = { dependency: ['service', 'alertSensitivity', 'component'], } -// API fields that YAML intentionally does not expose (set by CLI internally, or UUID-only) +// API fields that YAML intentionally does not expose (set by CLI internally, or UUID-only). +// `managedBy` is set automatically by the CLI transform layer to "CLI" so the +// API records correct attribution; users must not set it themselves in YAML. const API_ONLY_FIELDS: Record = { monitor: ['managedBy', 'environmentId', 'alertChannelIds', 'clearEnvironmentId', 'clearAuth'], - alertChannel: [], + alertChannel: ['managedBy'], notificationPolicy: [], resourceGroup: [ - 'alertPolicyId', 'defaultEnvironmentId', + 'managedBy', 'alertPolicyId', 'defaultEnvironmentId', ], - statusPage: [], + statusPage: ['managedBy'], statusPageComponent: ['monitorId', 'resourceGroupId', 'groupId', 'displayOrder', 'removeFromGroup'], webhook: ['enabled'], tag: [],