Repository navigation
feat(slos): SLO model, table and /v2/slos API - #2293
Merged
Merged
Maple Review Bot / Maple / review
succeeded
Nov 6, 2026 in 1m 29s
Confidence 10/10 · No issues found
🟢 Confidence 10/10 · safe to merge. Only F1 is left: the duplicate-name race still answers 503, deferred to #2296; tenancy filters and CRUD are pinned by the PGlite route tests.
1 note · tests covered · risk medium · 3/3 new units observable
Adds the slos table, SlosService and the /v2/slos CRUD group with slo_… ids, audit actions and org-deletion scoping. Safe to merge apart from the duplicate-name race (F1) the author has deferred to #2296; the open VcsWebhookEnqueueFailure error in http-graph.ts is untouched by this diff and not fixed.
slostable plus migration, unique on(org_id, name)SlosServiceCRUD with target/window/threshold validation and name uniqueness/v2/sloslist, create, retrieve, update, delete needingalerts:managefor writesSlosadded toORG_SCOPED_TABLESso an org delete takes its SLOs
Before merge
- Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261105234830_slos/migration.sql
Still open from earlier reviews
- 🔵 Note · F1 · An overlapping duplicate SLO name escapes the guard as a 503 ·
packages/backend/src/services/slos/SlosService.ts:191
Production impact
Open errors in the changed files (1)
| Issue | Service | Occurrences | File |
|---|---|---|---|
| @maple/api/routes/VcsWebhookEnqueueFailure | maple-api | 6 | apps/api/src/runtime/http-graph.ts |
After this merges, Maple checks whether they stop.
Telemetry this change adds and removes (7)
- ➕ span name
SlosService.list·packages/backend/src/services/slos/SlosService.ts:162 - ➕ span name
SlosService.get·packages/backend/src/services/slos/SlosService.ts:174 - ➕ attribute
maple.slo.id·packages/backend/src/services/slos/SlosService.ts:175 - ➕ span name
SlosService.create·packages/backend/src/services/slos/SlosService.ts:179 - ➕ attribute
maple.slo.sli·packages/backend/src/services/slos/SlosService.ts:180 - ➕ span name
SlosService.update·packages/backend/src/services/slos/SlosService.ts:220 - ➕ span name
SlosService.delete·packages/backend/src/services/slos/SlosService.ts:272
What was checked
- Every read and write filters
orgId(SlosService.ts:150,:167,:262,:277), so a foreignslo_…id answers 404 - Validation is enforced at the HTTP boundary: target, window and threshold are literal/range schemas in
V2SloCreateParams - DB access goes through
makeDbExecute, and each service method is anEffect.fnspan; v2 routes appear asGET/POSTspans onmaple-api
Observability coverage: 3 of 3 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| /v2/slos HTTP group (list, create, retrieve, update, delete) | server | yes | Registered in apps/api/src/runtime/http-graph.ts:198; sibling v2 groups surface as GET/POST spans on maple-api (search_traces) |
SlosService methods |
service method | yes | Effect.fn("SlosService.create") etc. with orgId and maple.slo.id annotations (SlosService.ts:162-273) |
Postgres reads/writes for slos |
database | yes | All go through makeDbExecute(database, "SlosService", toPersistenceError) (SlosService.ts:144) |
9232463 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading