Skip to content

feat(api-v2): config-resource bundle + /v2/alerts namespace - #224

Merged
Makisuo merged 1 commit into
mainfrom
feat/api-v2-config-bundle-alerts-namespace
Jul 17, 2026
Merged

Makisuo merged 1 commit into
mainfrom
feat/api-v2-config-bundle-alerts-namespace

Conversation

@Makisuo

@Makisuo Makisuo commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

What changed

Four new v2 public API resource groups (30 endpoints) — the config CRUD slice of the Phase 1 remainder in docs/api-v2.md:

Resource Surface Notes
/v2/ingest_keys retrieve + public/roll + private/roll Per-org singleton, admin-only; retrieve creates on first access
/v2/attribute_mappings CRUD Ingest-time attribute rewrite rules; amap_… IDs
/v2/scrape_targets CRUD + probe + checks Credentials write-only (has_credentials on responses); probe maps provider auth/transport failures to a new V2UpstreamError (502), distinct from storage-unavailable (503)
/v2/recommendations list + dismiss + reopen Mutations return the mutated object (v1 returns the full reconciled list)

All follow the established v2 pattern: annotated snake_case Schema.Struct wire models, Stripe list/error envelopes, prefixed public IDs (prefixes were already reserved), thin handler adapters over the existing services.

Alerts moved into a product namespace: /v2/alert_rules|alert_destinations|alert_incidents → /v2/alerts/rules|destinations|incidents (Stripe checkout/sessions-style). Since the scope family is derived from the first path segment under /v2, the three alert families collapse into a single alerts:read|write. Object types (alert_rule, …) and ID prefixes (alrt_, dest_, inc_) are unchanged.

Web: the API-key scope picker (create-api-key-dialog.tsx) and Settings → API Reference scope table (developer-section.tsx) now show the unified alerts family plus the four new families (which were missing from the key-creation UI). API clients need no path changes — they derive from the shared MapleApiV2 contract.

Why

Continues the v2 rollout (docs/api-v2.md Phase 1). The config bundle was the fastest burn-down (small CRUD groups, reserved prefixes, existing services). The alerts rename groups three inseparable resources under one namespace and one scope while v2 still has no external consumers — the only time this rename is cheap.

Reviewer notes

  • Breaking (intentionally, pre-launch): old /v2/alert_* paths now 404, and API keys scoped with alert_rules:*-style families lose alert access — no compat shim, per discussion. Dashboard-minted scoped keys predating this need re-minting if they used alert scopes.
  • Handler error mappers are split per endpoint shape (mapCommonError / mapMutationError / mapProbeError) because a single wide union doesn't typecheck against endpoints declaring narrower error lists.
  • v2-test-support.ts gains ConfigResourceServiceStubsLayer; every v2 HTTP harness must provide it (HttpApiBuilder.layer(MapleApiV2) requires all groups).
  • OpenAPI example IDs are real encodePublicId encodings — openapi.test.ts decodes them.

Verification

  • bun typecheck clean across all packages
  • api: 72 files / 847 tests pass (incl. new config-resources.http.test.ts PGlite HTTP round-trips: CRUD, scope enforcement, key rolling, 400/404 envelopes); domain: 216 pass; web alerts: 51 pass
  • Live dev server: /v2/docs renders all groups; GET /v2/alerts/rules → 401 (auth), GET /v2/alert_rules → 404

🤖 Generated with Claude Code

Ships four new v2 public API resource groups (30 endpoints), burning down
the Phase 1 remainder of docs/api-v2.md:

- /v2/ingest_keys — per-org singleton: retrieve (creates on first access)
  + public/private roll, admin-only
- /v2/attribute_mappings — CRUD over ingest-time attribute rewrite rules
- /v2/scrape_targets — CRUD + probe + checks; credentials stay write-only;
  probe surfaces provider failures via a new V2UpstreamError (502) so
  consumers can tell "upstream misbehaving" from "storage unavailable" (503)
- /v2/recommendations — list + dismiss/reopen; mutations return the mutated
  object (v1 returns the full reconciled list)

Also renames the alert groups into a Stripe-style product namespace:
/v2/alert_rules|alert_destinations|alert_incidents →
/v2/alerts/rules|destinations|incidents. Scope enforcement derives the
family from the first path segment, so the three alert scope families
collapse into a single alerts:read|write. Object types and public-ID
prefixes are unchanged. Breaking for any key scoped with the old
alert_*:* families (v2 has no external consumers yet).

Web: the API-key scope picker and Settings → API Reference scope table now
list the unified alerts family plus the four new config families.

Tests: new config-resources.http.test.ts PGlite HTTP round-trips; existing
v2 harnesses gain ConfigResourceServiceStubsLayer (every harness must
satisfy all mounted groups); OpenAPI surface snapshot and scope tests
updated to the new paths/family semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pullfrog

pullfrog Bot commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Your Pullfrog Router balance is exhausted.

You have a card on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.

Top up balance → · Enable auto-reload →

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Rerun failed job ➔ | View workflow run | via Pullfrog | Using Claude Opus | 𝕏

@Makisuo
Makisuo merged commit e268e5b into main Jul 17, 2026
8 checks passed
@Makisuo
Makisuo deleted the feat/api-v2-config-bundle-alerts-namespace branch July 17, 2026 20:18
Makisuo added a commit that referenced this pull request Jul 18, 2026
* feat(web): consume v2 API for the config-resource bundle

Migrate the dashboard off the v1 client (`MapleApiAtomClient`) onto the
already-shipped v2 endpoints (`MapleApiV2AtomClient`) for the four
config-resource groups whose v2 surface (#224) was built but still dark:

- ingest_keys      (get -> retrieve, reroll* -> roll*)
- attribute_mappings (v1 ingestAttributeMappings)
- scrape_targets
- recommendations  (v1 recommendationIssues)

Reads stay refetch-based (no txid): manual useAtomRefresh for
mappings/recommendations/ingest keys, reactivityKeys for scrape targets.
Both clients share appRegistry, so the PlanetScale card's v1 integrations
mutations still invalidate the migrated v2 scrape-target list.

Notable deltas handled beyond mechanical snake_case/param renames:
- v2 payload schemas are Schema.Struct -> pass plain snake_case objects
  (no `new V2…Params`).
- Prefixed public IDs round-trip to raw internal IDs at the client
  boundary, so row ids and the /recommendations/$recommendationKey route
  param are unchanged.
- v2 lists are cursor-paginated (default 20): attribute_mappings and
  recommendations page through all pages via a runtime.atom cursor loop;
  scrape_targets keeps .query(...) with limit:100 to preserve its
  reactivityKeys invalidation.

Left as-is: alert_incidents and scrape_targets listChecks (Electric), and
the integrations OAuth group in the catalog (v1). Deleting the now-unused
v1 groups is a follow-up.

Verified: apps/web typecheck clean; browser e2e for all four groups —
reads + create/update/delete/probe/dismiss/reopen hit /v2/... with correct
snake_case shapes and refetch reconciliation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* m

* fix iconsistencies with api v2

* stuff

* fux

* fix Effect review findings

* refine v2 pagination and error handling

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
pr-preview — 50992f6f Deployed Jul 17, 2026 by Makisuo via deploy-pr-preview #895
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