From 90172d898682aac6edbd5f35e235bc134bea837c Mon Sep 17 00:00:00 2001 From: caballeto Date: Wed, 29 Apr 2026 18:38:28 +0200 Subject: [PATCH] chore(forensics): refresh types after mono details JSONB + reason cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up the schema changes from devhelmhq/mono#316: - IncidentStateTransitionDto gains a `details: dict[str, Any]` field. User-driven transitions carry `details["source"] = "public-api"`; pipeline-driven ones carry `details["source"] = "pipeline"`. - Transition `reason` description aligns with what the engine actually writes (trigger | confirm | resolve | auto_clear | reopen). The earlier `manually_resolved` was a parallel reason value for the same logical edge — replaced by reason="resolve" + details.source="public-api". Pure regen via `./scripts/typegen.sh`. The mono PR also added `@Schema(additionalProperties = TRUE)` on the Java DTO so Springdoc emits `additionalProperties: true` instead of `additionalProperties: {type: "object"}`, yielding `dict[str, Any]` here instead of `dict[str, dict[str, Any]]`. Without that fix the Pydantic model would fail to parse real responses (`details.source` is a string, not a nested dict). Made-with: Cursor --- docs/openapi/monitoring-api.json | 31 +++- src/devhelm/_generated.py | 260 ++++++++++++++++--------------- 2 files changed, 164 insertions(+), 127 deletions(-) diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 0ce2ea6..41903c1 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -25631,24 +25631,24 @@ }, "triggeringCheckId": { "type": "string", - "description": "Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions", + "description": "Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions. Omitted from JSON (undefined to SDKs) when null, treat missing as null.", "format": "uuid", "nullable": true }, "triggeredByRuleSnapshotHashHex": { "type": "string", - "description": "Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule", + "description": "Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule. Omitted from JSON when null, treat missing as null.", "nullable": true }, "triggeredByRuleIndex": { "type": "integer", - "description": "Index of the fired rule inside the policy's trigger_rules array", + "description": "Index of the fired rule inside the policy's trigger_rules array. Omitted from JSON when null, treat missing as null.", "format": "int32", "nullable": true }, "engineVersion": { "type": "string", - "description": "Detection engine semver that evaluated the rule", + "description": "Detection engine semver that evaluated the rule. Omitted from JSON when null, treat missing as null.", "nullable": true } }, @@ -25864,6 +25864,7 @@ "required": [ "affectedRegions", "checkId", + "details", "engineVersion", "fromStatus", "id", @@ -25910,7 +25911,7 @@ "reason": { "minLength": 1, "type": "string", - "description": "Why the transition fired (rule_matched | confirmation_met | auto_cleared_by_timeout | recovery_met | reopened | manually_resolved | policy_changed)" + "description": "Why the transition fired (trigger | confirm | resolve | auto_clear | reopen)" }, "triggeringEvaluationIds": { "type": "array", @@ -25943,6 +25944,9 @@ "type": "string", "description": "Scheduler-minted check execution ID (V92) of the triggering result", "format": "uuid" + }, + "details": { + "$ref": "#/components/schemas/StateTransitionDetails" } }, "description": "State-machine transitions this check caused (may be empty if nothing fired)" @@ -30579,6 +30583,23 @@ "minDaysRemaining" ] }, + "StateTransitionDetails": { + "required": [ + "source" + ], + "type": "object", + "properties": { + "source": { + "type": "string", + "description": "Actor that produced this transition (pipeline | public-api)", + "enum": [ + "pipeline", + "public-api" + ] + } + }, + "description": "Typed metadata about this transition (currently: actor source)" + }, "StatusCodeAssertion": { "required": [ "type", diff --git a/src/devhelm/_generated.py b/src/devhelm/_generated.py index 128a493..b7d4a8b 100644 --- a/src/devhelm/_generated.py +++ b/src/devhelm/_generated.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: .openapi-preprocessed.json -# timestamp: 2026-04-27T13:26:18+00:00 +# timestamp: 2026-04-29T17:00:31+00:00 from __future__ import annotations from typing import Annotated, Any, Literal @@ -2204,28 +2204,28 @@ class IncidentDto(BaseModel): UUID | None, Field( alias="triggeringCheckId", - description="Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions", + description="Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions. Omitted from JSON (undefined to SDKs) when null, treat missing as null.", ), ] = None triggered_by_rule_snapshot_hash_hex: Annotated[ str | None, Field( alias="triggeredByRuleSnapshotHashHex", - description="Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule", + description="Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule. Omitted from JSON when null, treat missing as null.", ), ] = None triggered_by_rule_index: Annotated[ int | None, Field( alias="triggeredByRuleIndex", - description="Index of the fired rule inside the policy's trigger_rules array", + description="Index of the fired rule inside the policy's trigger_rules array. Omitted from JSON when null, treat missing as null.", ), ] = None engine_version: Annotated[ str | None, Field( alias="engineVersion", - description="Detection engine semver that evaluated the rule", + description="Detection engine semver that evaluated the rule. Omitted from JSON when null, treat missing as null.", ), ] = None @@ -2337,86 +2337,6 @@ class IncidentsSummaryDto(BaseModel): mttr30d: float | None = None -class IncidentStateTransitionDto(BaseModel): - model_config = ConfigDict(extra="forbid") - id: Annotated[UUID, Field(description="Forensic row UUID")] - occurred_at: Annotated[ - AwareDatetime, - Field(alias="occurredAt", description="When the state transition occurred"), - ] - monitor_id: Annotated[ - UUID, - Field(alias="monitorId", description="Monitor this transition pertains to"), - ] - incident_id: Annotated[ - UUID | None, - Field( - alias="incidentId", - description="Incident this transition belongs to; null for pre-incident (auto-cleared) transitions", - ), - ] = None - from_status: Annotated[ - str, - Field( - alias="fromStatus", - description="Previous status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)", - min_length=1, - ), - ] - to_status: Annotated[ - str, - Field( - alias="toStatus", - description="New status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)", - min_length=1, - ), - ] - reason: Annotated[ - str, - Field( - description="Why the transition fired (rule_matched | confirmation_met | auto_cleared_by_timeout | recovery_met | reopened | manually_resolved | policy_changed)", - min_length=1, - ), - ] - triggering_evaluation_ids: Annotated[ - list[UUID], - Field( - alias="triggeringEvaluationIds", - description="rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", - ), - ] - affected_regions: Annotated[ - list[str], - Field( - alias="affectedRegions", - description="Regions whose evaluations contributed to this transition", - ), - ] - policy_snapshot_hash_hex: Annotated[ - str, - Field( - alias="policySnapshotHashHex", - description="Hex-encoded hash of the policy snapshot that governed this transition", - min_length=1, - ), - ] - engine_version: Annotated[ - str, - Field( - alias="engineVersion", - description="Detection engine version that emitted this transition", - min_length=1, - ), - ] - check_id: Annotated[ - UUID, - Field( - alias="checkId", - description="Scheduler-minted check execution ID (V92) of the triggering result", - ), - ] - - class OldStatus(StrEnum): watching = "WATCHING" triggered = "TRIGGERED" @@ -4511,6 +4431,21 @@ class SslExpiryAssertion(BaseModel): ] +class Source2(StrEnum): + pipeline = "pipeline" + public_api = "public-api" + + +class StateTransitionDetails(BaseModel): + model_config = ConfigDict(extra="forbid") + source: Annotated[ + Source2, + Field( + description="Actor that produced this transition (pipeline | public-api)" + ), + ] + + class StatusCodeAssertion(BaseModel): model_config = ConfigDict(extra="forbid") type: Literal["status_code"] = "status_code" @@ -4883,15 +4818,6 @@ class TableValueResultIncidentDto(BaseModel): total_pages: Annotated[int | None, Field(alias="totalPages")] = None -class TableValueResultIncidentStateTransitionDto(BaseModel): - model_config = ConfigDict(extra="forbid") - data: list[IncidentStateTransitionDto] - has_next: Annotated[bool, Field(alias="hasNext")] - has_prev: Annotated[bool, Field(alias="hasPrev")] - total_elements: Annotated[int | None, Field(alias="totalElements")] = None - total_pages: Annotated[int | None, Field(alias="totalPages")] = None - - class TableValueResultInviteDto(BaseModel): model_config = ConfigDict(extra="forbid") data: list[InviteDto] @@ -6205,29 +6131,6 @@ class BulkMonitorActionResult(BaseModel): ] -class CheckTraceDto(BaseModel): - model_config = ConfigDict(extra="forbid") - check_id: Annotated[ - UUID, - Field( - alias="checkId", description="The check execution ID this trace is keyed by" - ), - ] - evaluations: Annotated[ - list[RuleEvaluationDto], - Field(description="All rule evaluations that ran for this check"), - ] - transitions: Annotated[ - list[IncidentStateTransitionDto], - Field( - description="State-machine transitions this check caused (may be empty if nothing fired)" - ), - ] - policy_snapshot: Annotated[ - PolicySnapshotDto | None, Field(alias="policySnapshot") - ] = None - - class ComponentUptimeDayDto(BaseModel): model_config = ConfigDict(extra="forbid") date: Annotated[ @@ -6736,6 +6639,87 @@ class IncidentPolicyDto(BaseModel): ] = None +class IncidentStateTransitionDto(BaseModel): + model_config = ConfigDict(extra="forbid") + id: Annotated[UUID, Field(description="Forensic row UUID")] + occurred_at: Annotated[ + AwareDatetime, + Field(alias="occurredAt", description="When the state transition occurred"), + ] + monitor_id: Annotated[ + UUID, + Field(alias="monitorId", description="Monitor this transition pertains to"), + ] + incident_id: Annotated[ + UUID | None, + Field( + alias="incidentId", + description="Incident this transition belongs to; null for pre-incident (auto-cleared) transitions", + ), + ] = None + from_status: Annotated[ + str, + Field( + alias="fromStatus", + description="Previous status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)", + min_length=1, + ), + ] + to_status: Annotated[ + str, + Field( + alias="toStatus", + description="New status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)", + min_length=1, + ), + ] + reason: Annotated[ + str, + Field( + description="Why the transition fired (trigger | confirm | resolve | auto_clear | reopen)", + min_length=1, + ), + ] + triggering_evaluation_ids: Annotated[ + list[UUID], + Field( + alias="triggeringEvaluationIds", + description="rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", + ), + ] + affected_regions: Annotated[ + list[str], + Field( + alias="affectedRegions", + description="Regions whose evaluations contributed to this transition", + ), + ] + policy_snapshot_hash_hex: Annotated[ + str, + Field( + alias="policySnapshotHashHex", + description="Hex-encoded hash of the policy snapshot that governed this transition", + min_length=1, + ), + ] + engine_version: Annotated[ + str, + Field( + alias="engineVersion", + description="Detection engine version that emitted this transition", + min_length=1, + ), + ] + check_id: Annotated[ + UUID, + Field( + alias="checkId", + description="Scheduler-minted check execution ID (V92) of the triggering result", + ), + ] + details: StateTransitionDetails + + class IncidentTimelineDto(BaseModel): model_config = ConfigDict(extra="forbid") transitions: Annotated[ @@ -7180,11 +7164,6 @@ class SingleValueResponseBulkMonitorActionResult(BaseModel): data: BulkMonitorActionResult -class SingleValueResponseCheckTraceDto(BaseModel): - model_config = ConfigDict(extra="forbid") - data: CheckTraceDto - - class SingleValueResponseDashboardOverviewDto(BaseModel): model_config = ConfigDict(extra="forbid") data: DashboardOverviewDto @@ -7352,6 +7331,15 @@ class TableValueResultComponentUptimeDayDto(BaseModel): total_pages: Annotated[int | None, Field(alias="totalPages")] = None +class TableValueResultIncidentStateTransitionDto(BaseModel): + model_config = ConfigDict(extra="forbid") + data: list[IncidentStateTransitionDto] + has_next: Annotated[bool, Field(alias="hasNext")] + has_prev: Annotated[bool, Field(alias="hasPrev")] + total_elements: Annotated[int | None, Field(alias="totalElements")] = None + total_pages: Annotated[int | None, Field(alias="totalPages")] = None + + class TableValueResultIntegrationDto(BaseModel): model_config = ConfigDict(extra="forbid") data: list[IntegrationDto] @@ -7637,6 +7625,29 @@ class BatchComponentUptimeDto(BaseModel): ] +class CheckTraceDto(BaseModel): + model_config = ConfigDict(extra="forbid") + check_id: Annotated[ + UUID, + Field( + alias="checkId", description="The check execution ID this trace is keyed by" + ), + ] + evaluations: Annotated[ + list[RuleEvaluationDto], + Field(description="All rule evaluations that ran for this check"), + ] + transitions: Annotated[ + list[IncidentStateTransitionDto], + Field( + description="State-machine transitions this check caused (may be empty if nothing fired)" + ), + ] + policy_snapshot: Annotated[ + PolicySnapshotDto | None, Field(alias="policySnapshot") + ] = None + + class CheckTypeDetailsDto(RootModel[Http | Tcp | Icmp | Dns | McpServer]): root: Annotated[ Http | Tcp | Icmp | Dns | McpServer, @@ -7681,6 +7692,11 @@ class SingleValueResponseBatchComponentUptimeDto(BaseModel): data: BatchComponentUptimeDto +class SingleValueResponseCheckTraceDto(BaseModel): + model_config = ConfigDict(extra="forbid") + data: CheckTraceDto + + class SingleValueResponseStatusPageIncidentDto(BaseModel): model_config = ConfigDict(extra="forbid") data: StatusPageIncidentDto