Skip to content

refactor: type-safe snapshot system derived from OpenAPI schemas#4

Merged
caballeto merged 7 commits intomainfrom
fix/cli-quality-hardening
Apr 11, 2026
Merged

refactor: type-safe snapshot system derived from OpenAPI schemas#4
caballeto merged 7 commits intomainfrom
fix/cli-quality-hardening

Conversation

@caballeto
Copy link
Copy Markdown
Contributor

Summary

  • Derive snapshot types from OpenAPI Update*Request schemas via Required<Schemas['UpdateXRequest']> — if the API contract changes (field added/removed/renamed), the TypeScript compiler immediately errors in the snapshot functions, preventing silent drift between YAML engine and API.
  • Remove dead code: alwaysChanged plumbing from HandlerDef/defineHandler, 14 custom *Snapshot interfaces, 7 old normalization helpers.
  • Centralize as any casts for dynamic API paths into api-client.ts helper functions (apiGet, apiPost, apiPut, apiPatch, apiDelete), cleaning them out of all other files.
  • Add generic RefEntry<K> to resolver.ts and RefTypeDtoMap to types.ts for compile-time DTO mapping on reference lookups.
  • Fix bugs discovered during audit: webhook snapshot now tracks enabled; resource group field name corrected (defaultAlertChannelIdsdefaultAlertChannels to match API); toDesiredSnapshot/toCurrentSnapshot are now required (not optional).

Three resources keep documented custom snapshot types where update semantics don't map 1:1:

  • secret: write-only value, compared by SHA-256 hash
  • alertChannel: complex config union, compared by content-addressed hash
  • dependency: no single update endpoint (split across two API calls)

Test plan

  • npx tsc --noEmit — clean typecheck
  • npm test — all 384 tests pass
  • No linter errors introduced
  • Integration tests via make test-surface SURFACE=cli

Made with Cursor

Replace all hand-written *Snapshot interfaces with types derived from
the generated OpenAPI Update*Request schemas via Required<Schemas[...]>.
This guarantees that when the API contract changes (field added, removed,
or renamed), the TypeScript compiler immediately errors in the snapshot
functions, preventing silent drift between YAML engine and API.

Key changes:
- Remove dead alwaysChanged plumbing from HandlerDef / defineHandler
- Replace 14 custom snapshot interfaces with Required<UpdateXRequest>
  type aliases (tag, environment, notificationPolicy, webhook,
  resourceGroup, monitor) or documented custom types for special cases
  (secret: hash-based, alertChannel: hash-based, dependency: split API)
- Remove 7 old normalization helpers, replace with 4 API-type-aligned
  helpers (sortAssertions, apiAssertionsToSnapshot,
  apiIncidentPolicyToSnapshot, apiTagsToSnapshot)
- Export toCreateAssertionRequest and toIncidentPolicy from transform.ts
- Centralize as-any casts into api-client.ts helper functions
- Add typed RefEntry<K> generics to resolver.ts
- Add RefTypeDtoMap to types.ts for compile-time DTO mapping
- Fix webhook snapshot to also track enabled field
- Fix resourceGroup snapshot field name (defaultAlertChannelIds →
  defaultAlertChannels) to match API contract
- Make toDesiredSnapshot / toCurrentSnapshot required (not optional)

Made-with: Cursor
@caballeto caballeto force-pushed the fix/cli-quality-hardening branch from 8137bfe to da3cf9a Compare April 11, 2026 12:19
- Exit codes: plan/deploy exit 0 by default; add --detailed-exitcode
  opt-in flag (exit 10 when changes pending, 11 for partial failure)
- JSON output: add -o json to plan/deploy/validate for structured
  machine-readable output (ChangesetJson format)
- Lock timeout: add --lock-timeout flag with 5s retry backoff
- Force-unlock: add standalone `deploy force-unlock` command with
  confirmation prompt
- Bump default lock TTL from 10min to 30min
- Fix: integrate handleApiError into checkedFetch, remove dead code
- Fix: environment handler uses slug for update/delete paths
- Fix: group membership differ properly diffs against API state
- Fix: webhook enabled field now controllable from YAML config
- Remove dead monitor.resourceGroup field from schema/validator
- Add monitors versions list/get commands

Made-with: Cursor
… extraction

- Update monitoring-api.json with latest spec (includes @Schema descriptions)
- Regenerate api.generated.ts and descriptions.generated.ts
- Add AcquireDeployLockRequest to extract-descriptions TARGET_SCHEMAS
- Add cross-reference comment pointing to monorepo MUST_HAVE list

Made-with: Cursor
- Environment handler now uses slug for update/delete paths (not ID)
- Webhook snapshot now includes `enabled` field
- Remove dead resourceGroup validation test (field was removed)

Made-with: Cursor
@caballeto caballeto merged commit 1b6ce49 into main Apr 11, 2026
3 checks passed
@caballeto caballeto deleted the fix/cli-quality-hardening branch April 11, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant