Skip to content

Phase 3 cutover: single listener, datastore type-swap, Keycloak removal, deliberate breaks live #134

@SyniRon

Description

@SyniRon

Parent

Part of #112 (PRD: Goodbye gRPC) — Phase 3 (Rewrite). The cutover deploy — the one that swaps stacks.

What to build

Cut the public surface over to the new stack, in one revertible deploy:

  • Single public listener serves every route through the new chain (sentry → metrics → auth → gzip → mux). The second port stops listening. Docs UI + spec keep serving at unchanged URLs, with the version templated from the build-time variable (this replaces the CI proto-sed step).
  • The datastore type-swap rides this change (the PRD's deliberate answer to the dual-stack trap): the Datastore interface and its implementations move from generated proto types to the types package — import surgery plus enum constants and slice allocation. Whatever old-stack serving code the swap breaks is unwired/removed here; the full toolchain sweep stays in Phase 4.
  • Keycloak surface removed: route → standard JSON 404, fields gone from both profile shapes, the datastore lookup method deleted. This delivers what Remove MilpacService.GetUserViaKeycloakId (Phase 2 of 2) #100 scoped — close it as superseded by this change.
  • Vestigial-join cleanup rides the swap: the roster queries LEFT JOIN xf_user_connected_account purely vestigially (measured: 1,397 rows scanned for 845 profiles; gorm dedups in Go); the join only matters for the discord/keycloak WHERE variants. Behavior-preserving removal — the roster goldens prove it.
  • The deliberate breaks go live (the PRD's complete enumerated list — same list the consumer heads-up carries).
  • The datastore behavior tests get their mechanical type update.

After the deploy: close #94 (gateway dial deprecations — superseded; the dial leaves the serving path) and close #100 (delivered here).

Workflow: /tdd — the full golden corpus is the red suite; this issue is done when it's green against the deployed configuration.

Acceptance criteria

Live spot-check notes: temporary API key recipe — xf_cav7_api_key row with key_hash = UNHEX(SHA2('<plaintext>',256)), unique user_id, is_active=1, plus xf_cav7_api_key_scope rows for both scopes; delete after use. Local mirror at ~/srv/xenforo-mirror (DB env per that compose file — credentials stay out of issues; no Redis needed once Phase 2 has landed).

Blocked by

Metadata

Metadata

Assignees

Labels

7cavready-for-agentFully specified, ready for an AFK agent to implementrefactorCode restructure without functional change

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions