feat(portal-bff): ai-bridge controller — SSE chat + JSON rag/models
CI / scan (pull_request) Successful in 2m59s
CI / commits (pull_request) Successful in 3m6s
CI / check (pull_request) Successful in 3m32s
CI / a11y (pull_request) Successful in 1m50s
Docs site / build (pull_request) Successful in 2m34s
CI / perf (pull_request) Successful in 4m4s
CI / scan (pull_request) Successful in 2m59s
CI / commits (pull_request) Successful in 3m6s
CI / check (pull_request) Successful in 3m32s
CI / a11y (pull_request) Successful in 1m50s
Docs site / build (pull_request) Successful in 2m34s
CI / perf (pull_request) Successful in 4m4s
Wires the AI relay into the BFF per ADR-0024 (now accepted): - AiBridgeController exposes POST /api/ai/chat (text/event-stream), GET /api/ai/rag/search, GET /api/ai/models under /api/ai/*. Session-gated (req.session.user) without an admin role — AI is an end-user surface. CSRF and double-submit token handled by the global middleware mounted in main.ts. - sse.writer translates ChatEvent oneof cases to kebab-case SSE event names (token / citation / agent-step / tool-call / error / done), JSON-encodes the inner payload, and produces a relay-side error frame on upstream failures (mapped from gRPC Status codes into the urn:apf-ai:* namespace the AI service already uses). - DTOs (class-validator) cap message count + length, restrict the role enum to user/assistant/system (tool messages are constructed caller-side by the BFF when tool dispatch lands), and bound RAG top_k between 1 and 50. - Browser disconnect (req 'close' event) → AbortController → call.cancel(), upstream LLM stops without leaking the stream. - AiClientModule now implements OnApplicationShutdown to close the four gRPC stubs on SIGTERM/SIGINT; main.ts calls app.enableShutdownHooks() to make it fire. - ADR-0024 promoted from proposed to accepted; README index + the CLAUDE.md roll-up updated. apps/portal-bff/.env.example documents AI_SERVICE_GRPC_ENDPOINT / CLIENT_ID / TLS for local boot.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
status: proposed
|
||||
status: accepted
|
||||
date: 2026-05-19
|
||||
decision-makers: R&D Lead
|
||||
tags: [backend, security, observability]
|
||||
|
||||
@@ -67,4 +67,4 @@ ADRs are listed in numerical order. To slice by topic, filter on the `Tags` colu
|
||||
| [0021](0021-phase-2-security-baseline.md) | Phase-2 security baseline — helmet, CORS allowlist, double-submit CSRF, rate limiting, structured error envelope | accepted | `security`, `backend` | 2026-05-13 |
|
||||
| [0022](0022-docs-site-vitepress.md) | Documentation site — VitePress + Mermaid plugin, separate static deployment | accepted | `process`, `infrastructure` | 2026-05-15 |
|
||||
| [0023](0023-charts-d3-observable-plot.md) | Charts + dashboards — D3 + Observable Plot wrapped in `libs/shared/charts` | accepted | `frontend`, `accessibility`, `performance` | 2026-05-16 |
|
||||
| [0024](0024-ai-service-relay-grpc-sse-bridge.md) | AI service relay — vendored gRPC protos, NestJS gRPC client, SSE bridge to the SPA, POC unsigned principal | proposed | `backend`, `security`, `observability` | 2026-05-19 |
|
||||
| [0024](0024-ai-service-relay-grpc-sse-bridge.md) | AI service relay — vendored gRPC protos, NestJS gRPC client, SSE bridge to the SPA, POC unsigned principal | accepted | `backend`, `security`, `observability` | 2026-05-19 |
|
||||
|
||||
Reference in New Issue
Block a user