4.1 KiB
V2 Phase 3 AI Platform Request Tenant Context
Date: 2026-07-02
Status
Completed and smoke verified on 192.168.3.90.
This slice closes the request-level tenant boundary for the AI Platform high-frequency data paths:
- Knowledge documents, chunks, import batches, reindex executions, and ingestion jobs.
- AI Trace list/detail/update paths.
- Quality improvement action create/list/detail/update paths.
The API now accepts X-Tenant-Id and uses it as the request tenant context. If the header is omitted or blank, the system continues to use the backward-compatible default tenant.
Implementation
Added:
yuqei_ai_platform_api.tenant_context- Request middleware in
yuqei_ai_platform_api.main - Tenant-aware SQLAlchemy filtering for knowledge, audit, and quality persistence
- Tenant-aware in-memory repository behavior for tests and demo mode
Important behavior:
- New tenant-scoped rows are written with the current request tenant.
- Read paths filter by the current request tenant.
- AI Trace detail returns
404when accessed from a different tenant. - Existing callers without
X-Tenant-Idcontinue to read/write thedefaulttenant.
The legal, audit, and knowledge route handlers are async so the request tenant context is preserved across FastAPI execution.
Smoke Verification
Smoke environment:
- Contract Web:
http://192.168.3.90:13000 - Contract API:
http://192.168.3.90:18100 - AI Platform API:
http://192.168.3.90:18101
Runtime checks:
GET http://192.168.3.90:18100/api/v1/runtime/schema-check -> ok
GET http://192.168.3.90:18101/api/v1/runtime/schema-check -> ok
AI Platform schema-check result:
{
"status": "ok",
"alembic": {
"actual": "20260702_0020",
"expected_head": "20260702_0020"
},
"tenant_columns": "ok",
"trace_governance_columns": "ok",
"secret_ref_columns": "ok",
"pgvector_schema": "ok"
}
Tenant smoke result:
{
"status": "pass",
"tenant_a": "tenant-smoke-20260702231614-a",
"tenant_b": "tenant-smoke-20260702231614-b",
"knowledge_search": {
"tenant_a_count": 1,
"tenant_b_count": 0
},
"ai_runs": {
"tenant_a_run_tenant": "tenant-smoke-20260702231614-a",
"tenant_b_run_tenant": "tenant-smoke-20260702231614-b",
"cross_tenant_detail_status": 404
},
"quality_actions": {
"created_tenant": "tenant-smoke-20260702231614-a",
"tenant_b_visible_count": 0
}
}
Verified endpoints:
POST /api/v1/knowledge-documentsGET /api/v1/knowledge-documents/searchPOST /api/v1/legal/qaGET /api/v1/audit/ai-runsGET /api/v1/audit/ai-runs/{run_id}POST /api/v1/audit/quality-improvement-actionsGET /api/v1/audit/quality-improvement-actions
Deployment Note
During verification, the prior smoke deployment had contract-api exited with code 139. Direct python -X faulthandler import and uvicorn startup with .env.smoke did not reproduce the crash. Restarting the existing smoke services with the same .env.smoke recovered the stack and all services became healthy.
Diagnostic note: remote compose commands for this smoke stack must include:
docker compose -p yuqei-contract-v2-smoke --env-file .env.smoke -f docker-compose.yml ...
Running ad-hoc compose commands without .env.smoke can use local defaults that do not match the existing smoke Postgres volume.
Local Validation
Previously passed locally:
python -m pytest yuqei-ai-platform\services\ai-platform-api\tests\test_platform_data.py::test_request_tenant_context_isolates_knowledge_traces_and_quality_actions -q
python -m pytest yuqei-ai-platform\services\ai-platform-api\tests -q
Result:
- AI Platform API tests: 56 passed.
Remaining Items
Still pending for the broader AI Platform governance track:
- Later tenant-aware auth/permission enforcement.
- Later row-level security design, if required for production isolation.
Recommended next slice:
- Continue later hardening for scheduled Trace governance worker loops and policy-specific redaction rules.
Trace governance worker implementation is recorded in:
project-docs/V2-phase3-ai-platform-trace-governance-worker-2026-07-02.md