feat: deprecate-and-observe PR #984's audited apiv2 endpoints (registry)#1025
Merged
Conversation
…istry approach) Instead of #984's hard-deletes, wrap the 17 audited apiv2 endpoints in deprecation.Marker(endpoint, sunset) so they log a Loki hit per call and carry Deprecation/Sunset headers, and let monitor:deprecated-endpoints observe them. Design: the Marker() calls are the single source of truth (registry), exposed via GET /deprecated, because the served OpenAPI spec is go-swagger-GENERATED and its swagger:route form can't carry an x-sunset extension (empirically: x-sunset breaks generation; Deprecated:true survives). A registry (vs a config map) makes the observed set and the hit-logging the same act, so they can't drift into a false 'safe to retire'. - Go: Marker(endpoint,sunset)+registry+List()+GET /deprecated; 17 routes wrapped; tests. - PHP: DeprecatedEndpointService reads GET /deprecated (not swagger.json); config apiv2_swagger_url -> apiv2_deprecated_url; command + tests updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWbC1th5ZKGQswSoW1X2eg
In-container e2e caught it: GET http://apiv2:8192/deprecated 404s; the route is registered under the /api and /apiv2 groups, so the reachable URL is /apiv2/deprecated. Verified batch->apiv2 fetch returns all 17 registered endpoints. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWbC1th5ZKGQswSoW1X2eg
✅ Deploy Preview for golden-caramel-d2c3a7 canceled.
|
swagger.json is go-swagger-generated at build and x-sunset breaks generation, so the sunset date moved into deprecation.Marker() (served at GET /apiv2/deprecated). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWbC1th5ZKGQswSoW1X2eg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Applies the deprecate-and-observe mechanism (PR #1021) to the 17 audited apiv2 endpoints that PR #984 would hard-delete — so they're retired safely (mark → watch real traffic → delete once confirmed silent) instead of deleted on the strength of a static audit.
Each endpoint is wrapped in
deprecation.Marker("METHOD /path", "2026-08-01"), which:Deprecation+Sunsetresponse headers,monitor:deprecated-endpointsreport can observe it.Relationship to #984
This is the deprecate-and-observe alternative to #984's apiv2 hard-deletes. #984 should drop its apiv2 route/handler/test/swagger deletions (its routing/spatial deletions + OpenAPI doc audit can stand). Once the nightly report shows an endpoint silent past its sunset, a follow-up deletes it — the same end state, reached with evidence. (#984 is also 149 commits behind master, so it needs a rebase regardless; this PR is cut fresh from master.)
Why a registry, not the spec or a config map
The
monitor:deprecated-endpointscommand needs, per endpoint, a sunset date. Two things ruled out the obvious homes:swagger.jsonis go-swagger-generated at build (Dockerfile). Empirically:// Deprecated: truesurvives generation, but anx-sunsetvendor extension breaks generation entirely (swagger:routehas no slot for it). So the date can't live in the spec.{endpoint: sunset}can drift from the actualMarker()calls. A config entry without a matchingMarker()→ zero logs → the command falsely reports "safe to retire" and a live endpoint gets deleted. That's the exact failure the feat: safe endpoint deprecation-and-observe (deprecate → watch Loki → retire/chase) #1021 hardening pass guarded against.The registry (the
Marker()calls are the source of truth, served atGET /apiv2/deprecated) makes the observed set and the hit-logging the same act, so they can't drift. The batch command reads that endpoint — which is also simpler than parsing the spec (no{id}→:idmapping; Go emits the Fiber form directly).Endpoints deprecated (sunset 2026-08-01)
GET /activity,GET /messages,GET/PUT/PATCH/DELETE /isochrone,DELETE /message/:id,GET /modtools/admin/:id,GET /modtools/alert/:id,PATCH /config/admin,DELETE /noticeboard/:id,POST /story,DELETE /story/:id,POST /team,DELETE /team,PATCH /microvolunteering,GET /simulation.(routing + spatial endpoints in #984 stay hard-deleted — they're internal service-to-service, deploy-atomic, not reachable by the web/app/external populations.)
Test plan
Marker(endpoint, sunset)change compiles across the tree; newdeprecationtests cover headers, the logged pattern,List(), andGET /deprecated).DeprecatedEndpointServicenow reads/deprecated; command retire/still-in-use/could-not-check split; fail-loud on unreachable).GET /apiv2/deprecatedwith all 17 entries; the batch container fetches it and the command runs correctly ("No deprecated endpoints past their sunset date", since all sunset 2026-08-01). This caught a real bug pre-merge: the endpoint is under the/apiv2group prefix, soapiv2_deprecated_urlneeded/apiv2/deprecated.