Isolate cloud model access before enabling product RAG workflows
Some checks failed
verify / verify (push) Has been cancelled

The API and ingestion tools now use a fixed internal model gateway while
governed profiles, embedding cache assignments, traceable citations, and
stable API errors establish the boundaries required by later workflows.

Constraint: The current Alibaba Cloud workspace rejects all three live model calls with authentication failures
Rejected: Give the API or seed tools the Bailian key and direct egress | combines database access, cloud credentials, and public network access
Rejected: Mix offline and Bailian vectors in one demo namespace | makes profile activation and retrieval ambiguous
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep Bailian credentials and egress exclusive to model-gateway and create a new immutable profile hash for any embedding identity change
Tested: make verify; 121 backend tests; 14 frontend tests; fresh and populated Alembic upgrade-downgrade-upgrade; two idempotent offline seeds; Docker health and HTTP retrieval; isolated provider smoke
Not-tested: Successful live Bailian responses because the supplied workspace credential currently fails authentication
This commit is contained in:
2026-07-13 04:09:06 +08:00
parent 99b7df64ea
commit 75592af33a
28 changed files with 3932 additions and 254 deletions

View File

@@ -0,0 +1,65 @@
from __future__ import annotations
import uuid
import httpx
import pytest
from fastapi import APIRouter
from app.core.problems import ApiProblem
from app.main import create_app
@pytest.mark.asyncio
async def test_application_factory_generates_openapi_without_runtime_secrets() -> None:
app = create_app()
schema = app.openapi()
assert schema["openapi"].startswith("3.")
assert "/api/v1/health/live" in schema["paths"]
assert "/api/v1/meta" in schema["paths"]
assert "/health/live" not in schema["paths"]
@pytest.mark.asyncio
async def test_trace_id_accepts_only_uuid_and_is_returned() -> None:
app = create_app()
transport = httpx.ASGITransport(app=app)
supplied = str(uuid.uuid4())
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
accepted = await client.get("/api/v1/health/live", headers={"x-request-id": supplied})
replaced = await client.get(
"/api/v1/health/live",
headers={"x-request-id": "secret-or-unbounded-client-value"},
)
assert accepted.headers["x-request-id"] == supplied
assert uuid.UUID(replaced.headers["x-request-id"])
assert replaced.headers["x-request-id"] != "secret-or-unbounded-client-value"
@pytest.mark.asyncio
async def test_formal_api_problem_is_sanitized_and_traceable() -> None:
app = create_app()
router = APIRouter()
@router.get("/api/v1/problem-test")
async def fail() -> None:
raise ApiProblem(
status=409,
code="VERSION_CONFLICT",
title="Version conflict",
detail="The resource changed; reload and retry.",
)
app.include_router(router)
transport = httpx.ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/v1/problem-test")
payload = response.json()
assert response.status_code == 409
assert response.headers["content-type"].startswith("application/problem+json")
assert payload["code"] == "VERSION_CONFLICT"
assert uuid.UUID(payload["trace_id"])
assert payload["field_errors"] == []