dev/ declares this repo's GitRepository, the Kustomization that deploys ./kong, and its ExternalSecrets — but nothing watched dev/, so those files were applied once by hand and never re-read. Editing them in git changed nothing until someone remembered to kubectl apply, which is what silently swallowed the CONTROL_PLANE_REF_NAME rollout: correct in git for hours while the cluster still held the old value. Add the bootstrap Kustomization that watches ./dev and, living in ./dev, manages itself. This is what `flux bootstrap` would have created; flux-operator installs the controllers and no root. It sits in the domain namespace rather than flux-system, because sourceRef resolves in the Kustomization's own namespace and because this is the team's to own. Needs one kubectl apply to exist. That is the last one this repo needs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
payments-api
Kong routing/policy layer for the payments slice of
classic-models-api (see /Users/stephanetailland/git/classic-models-api),
split out per the DDD decomposition in ../kong-konnect-deployment-strategy.md.
The backend itself stays a single monolith — only Kong does the domain
split. Structure mirrors ../customers-api, not ../catalog-api — see
../STATUS.md section 18 for why (catalog-api's two-route MCP pattern
has a latent bug; customers-api's single-route pattern is the corrected
one to copy going forward).
Two exposure surfaces, both proxying to the real classic-models-api
backend:
- REST (
kong/rest/) — 6 routes overPayment, which uses a composite key (customernumber+checknumber, not a single id likeCustomer/Product) — both URI segments are captured and passed through to the backend's own composite-key URL pattern. - MCP (
kong/mcp/) —list-payments/get-payment(all 5 roles) andcreate-payment(admin only — verified againstPaymentPermission's actual logic inauthentication/permissions.py, not guessed: writes are admin-only in practice,customercan only write their own via the REST API directly, not exposed as an MCP tool). OneKongRoutefor all three MCP HTTP methods, oneai-mcp-proxybinding — see../STATUS.mdsection 18 for why this matters (a second route + binding for the same plugin creates a duplicate-tool-name bug, found and fixed oncustomers-mcp, built correctly here from the start).
| Route | Method | Backend path |
|---|---|---|
/payments/v1/payments/ |
GET, POST | /classic-models/api/v1/payments/ |
/payments/v1/payments/{customernumber}/{checknumber}/ |
GET, PUT, PATCH, DELETE | /classic-models/api/v1/payments/{customernumber}/{checknumber}/ |
/payments-mcp |
GET, POST, DELETE | MCP streamable-http (tools call into the REST routes above) |
Auth
openid-connect on both surfaces, distinct audience each (payments-api
for REST, mcp-payments for MCP) with a real RFC 8693 exchange chain:
MCP → payments-api → classic-models-api, same pattern as
catalog-api/customers-api. IdP is the local Keycloak
(https://keycloak.sttlab.local/realms/classic-models) — see
../STATUS.md sections 15/16. payments-api-audience and
mcp-payments-audience client scopes + payments-api/mcp-payments
resource clients created on the local Keycloak, attached to
kong-token-exchange-broker's default scopes (REST audience) and to
librechat's optional scopes (MCP audience) respectively — no dedicated
protocol mappers on either new client itself, same practice as every
other domain built this session. mcp-payments's OAuth callback added to
librechat's redirectUris, and a payments-mcp server entry added to
LibreChat's librechat.yaml (infra-librechat repo).
Other policies
Per-consumer rate limiting, response caching (GET/HEAD), audit log
(http-log, endpoint still a placeholder — no real log collector in this
lab, same caveat as the other domains).
Structure
Same dev/ + kong/rest/ layout as customers-api. Deploy key
(kong-v2/payments-api/git-deploy-key) is a copy of catalog-api's,
not a freshly generated one — per the user's explicit instruction this
session ("no reason a working key for catalog-api wouldn't work for
customers-api"), the same reused key is used here too rather than minting
yet another one per domain.