1cec45e0ac
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
3.4 KiB
Markdown
65 lines
3.4 KiB
Markdown
# 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 over `Payment`, which uses a
|
|
**composite key** (`customernumber` + `checknumber`, not a single id
|
|
like `Customer`/`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) and
|
|
`create-payment` (admin only — verified against `PaymentPermission`'s
|
|
actual logic in `authentication/permissions.py`, not guessed: writes are
|
|
admin-only in practice, `customer` can only write their own via the
|
|
REST API directly, not exposed as an MCP tool). **One `KongRoute` for
|
|
all three MCP HTTP methods**, one `ai-mcp-proxy` binding — see
|
|
`../STATUS.md` section 18 for why this matters (a second route +
|
|
binding for the same plugin creates a duplicate-tool-name bug, found
|
|
and fixed on `customers-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
|
|
`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.
|