Files
ai-contract-platform/yuqei-infra
yuqei 5ad6beac98
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 6m23s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Successful in 10m18s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 42m22s
ci: make source secret scan locale independent
2026-07-20 21:14:31 +08:00
..

Yuqei V2 Infrastructure

This directory contains the local and deployment baseline for the V2 rebuild.

Local Compose Startup

From repository root:

Copy-Item yuqei-infra\compose\.env.example yuqei-infra\compose\.env
docker compose --env-file yuqei-infra\compose\.env -f yuqei-infra\compose\docker-compose.yml up --build

Services:

  • Contract Web: http://localhost:3000
  • Contract API: http://localhost:8100
  • AI Platform API: http://localhost:8101
  • MinIO S3 API: http://localhost:9000
  • MinIO Console: http://localhost:9001

Migration Order

The compose file initializes databases and runs explicit Alembic migrations before starting the APIs:

  • postgres-init-databases
  • ai-platform-api-migrate
  • contract-api-migrate

Application containers keep *_DATABASE_AUTO_CREATE=false so schema changes are owned by migrations instead of implicit table creation.

The local compose baseline uses one PostgreSQL instance, but separates V2 data into dedicated databases:

  • yuqei_contract: Contract Platform business data.
  • yuqei_ai: AI Platform runtime, RAG, Prompt, Trace, and quality data.
  • yuqei_ops: infrastructure and operations data reserved for later services.

postgres-init-databases runs before migrations and creates missing databases idempotently. The two active platforms also keep separate Alembic histories:

  • ai_platform_alembic_version
  • contract_api_alembic_version

Contract API migrations must only target yuqei_contract; AI Platform and worker migrations/runtime data must only target yuqei_ai. Cross-platform references should use IDs such as ai_trace_id, never direct cross-database joins.

Runtime Verification

After services are up:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\verify-v2-runtime.ps1

The script checks:

  • Contract API /health.
  • Contract API /api/v1/runtime/config-check.
  • AI Platform /health.
  • AI Platform worker runtime health.
  • AI Platform object storage read/write/delete probe.
  • Contract Web /health page availability.

Remote Smoke Deploy

Use this before replacing the old contact.yuqei.com deployment. It deploys V2 to an independent directory and independent ports on 192.168.3.90, so it does not overwrite the V1 backend or the Aliyun frontend.

Default remote path:

/opt/apps/ai-contract-platform-v2-smoke

Default smoke URLs:

  • 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
  • MinIO Console: http://192.168.3.90:19001

Run from repository root:

$env:SSHPASS='YOUR_192_168_3_90_ROOT_PASSWORD'
powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\deploy-v2-smoke-docker.ps1 `
  -UseSshpass `
  -AllowDirtyWorktree

The script:

  • Packages only V2 source and infrastructure directories.
  • Excludes local .env* runtime files from the release archive.
  • Uploads the archive to 192.168.3.90.
  • Starts compose with yuqei_contract, yuqei_ai, and yuqei_ops.
  • Runs health checks for Contract Web, Contract API, and AI Platform API.
  • Runs the AI golden sample asset gate inside the ai-platform-api container.
  • Checks that the three V2 databases exist.
  • Runs the contract review worker --run-once smoke command.
  • Writes deploy artifacts to project-docs\qa-artifacts\v2-smoke-docker-deploy.

Latest passing smoke artifact:

  • project-docs\qa-artifacts\v2-smoke-docker-deploy\2026-07-16T11-12-47
  • AI golden sample asset gate passed with 90 samples, 6/6 suites, and 16/16 checks.
  • Contract review worker smoke completed.
  • Remote database baseline passed for yuqei_contract, yuqei_ai, and yuqei_ops.
  • Contract API runs with one Uvicorn worker and a 2-second read cache; all mutating requests invalidate the cache before and after execution.

After smoke passes, the old production deployment can be replaced deliberately: backend/AI/worker/database/MinIO on 192.168.3.90, frontend on Aliyun, and contact.yuqei.com kept as the public entry.

Production is now a separate, guarded path. Use compose/docker-compose.production.yml together with the shared compose file, then follow deploy/README.md. The production path requires digest-pinned images, loopback-only internal ports, TLS edge configuration, an off-host backup mount, protected provider secret files, and a passing deploy/preflight-production.py. It intentionally has no automatic traffic-cutover command.

Real-provider acceptance uses scripts/run-ai-provider-acceptance.py. It exercises 10 legal QA and 8 contract-review Phase13 samples and separates technical Provider success from named legal approval. The existing asset-count golden gate does not replace this runtime evaluation.

Release Quality Gate

Use this after a smoke deploy and interface benchmark to turn the release checks into one pass/fail gate:

When service authentication is enabled, load the protected smoke values into process environment variables first. Do not pass the values on the command line or write them to the artifact directory.

$env:CONTRACT_API_WEB_PROXY_SHARED_SECRET = "<load from protected smoke environment>"
$env:AI_PLATFORM_SERVICE_SHARED_SECRET = "<load from protected smoke environment>"
python yuqei-infra\scripts\run-release-quality-gate.py `
  --web-base-url http://192.168.3.90:13000 `
  --contract-api-base http://192.168.3.90:18100 `
  --ai-api-base http://192.168.3.90:18101 `
  --allow-ai-provider-warning

The gate verifies:

  • Contract API /api/v1/runtime/schema-check.
  • AI Platform API /api/v1/runtime/schema-check.
  • Latest Docker smoke summary under project-docs\qa-artifacts\v2-smoke-docker-deploy.
  • Latest interface benchmark summary under project-docs\qa-artifacts\v2-interface-benchmark.

To refresh the benchmark during the same gate run:

python yuqei-infra\scripts\run-release-quality-gate.py `
  --web-base-url http://192.168.3.90:13000 `
  --contract-api-base http://192.168.3.90:18100 `
  --ai-api-base http://192.168.3.90:18101 `
  --run-benchmark `
  --allow-ai-provider-warning

To require fresh summaries without rerunning every check:

python yuqei-infra\scripts\run-release-quality-gate.py `
  --web-base-url http://192.168.3.90:13000 `
  --contract-api-base http://192.168.3.90:18100 `
  --ai-api-base http://192.168.3.90:18101 `
  --max-smoke-summary-age-hours 24 `
  --max-benchmark-summary-age-hours 24

Artifacts are written to project-docs\qa-artifacts\v2-release-quality-gate. GitHub Actions also exposes a manual Release Quality Gate workflow for a self-hosted runner with access to 192.168.3.90.

--allow-ai-provider-warning is only for a smoke environment that intentionally disables real Provider calls and enables fallback. Omit it for production readiness; any provider_runtime warning then fails the gate. Both the gate and benchmark read service keys from environment variables and record only whether authentication was configured, never the values.

Latest passing release gate artifact:

  • project-docs\qa-artifacts\v2-release-quality-gate\2026-07-13T14-03-15
  • Run mode: --run-benchmark --allow-ai-provider-warning, with protected service keys loaded from environment variables.
  • Contract API schema-check, the expected smoke-only AI Provider warning, Docker smoke summary, and 7 interface benchmark scenarios passed.
  • Each scenario ran 60 measured requests at concurrency 6 with 0% errors. Contract list p95 was 199.31 ms and knowledge chunk hybrid search p95 was 66.74 ms.

Latest supporting artifacts:

  • Interface benchmark: project-docs\qa-artifacts\v2-release-quality-gate\2026-07-13T14-03-15\interface-benchmark.
  • Security scan: project-docs\qa-artifacts\v2-security-scan\2026-07-13-auth-hardening-final-2.
  • Source secret scan: PR CI for commit 6abca4eb passed npm audit, Bandit, pip-audit, and Linux detect-secrets with no unreviewed source secret.

Contract Review Worker Flow Verification

Use this after the APIs and worker are running to verify the T7 contract review path:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\verify-contract-review-worker-flow.ps1 `
  -ContractApiBaseUrl http://localhost:8100 `
  -WorkerExecutionMode docker-compose `
  -RequireConfidence

The script creates a temporary contract, uploads a readable source text file, starts a review task, runs or waits for the contract review worker, then checks that the review result was written back with an AI Trace id. Add -RequirePrimarySources in staging/production when the AI Platform knowledge base is expected to return legal or policy sources.

-WorkerExecutionMode supports:

  • api: call POST /api/v1/review-worker/run-once.
  • docker-compose: run python -m yuqei_contract_api.review_worker --run-once inside the contract-review-worker service.
  • none: do not trigger manually; wait for a background worker loop to consume the task.

Production Baseline

Production must override the local demo defaults:

CONTRACT_API_ENVIRONMENT=production
CONTRACT_API_DATABASE_URL=postgresql+psycopg://.../yuqei_contract
CONTRACT_API_DATABASE_AUTO_CREATE=false
CONTRACT_API_SEED_DEMO_DATA=false
CONTRACT_API_AI_PLATFORM_BASE_URL=http://ai-platform-api:8101
CONTRACT_API_UVICORN_WORKERS=1
CONTRACT_API_READ_CACHE_TTL_SECONDS=2
CONTRACT_API_REVIEW_WORKER_NAME=contract-review-worker-1
CONTRACT_API_REVIEW_WORKER_POLL_INTERVAL_SECONDS=5
CONTRACT_API_REVIEW_WORKER_BATCH_LIMIT=5
AI_PLATFORM_ENVIRONMENT=production
AI_PLATFORM_DATABASE_URL=postgresql+psycopg://.../yuqei_ai
AI_PLATFORM_DATABASE_AUTO_CREATE=false
AI_PLATFORM_UVICORN_WORKERS=1
YUQEI_WORKER_DATABASE_URL=postgresql+psycopg://.../yuqei_ai
YUQEI_WORKER_DATABASE_AUTO_CREATE=false

Start from yuqei-infra\compose\.env.production.example and replace every CHANGE_ME value before deployment.

Run migrations explicitly before replacing application containers.

The 2-second read cache is process-local and is automatically disabled when CONTRACT_API_UVICORN_WORKERS is greater than 1. Use a shared cache with cross-process invalidation before increasing the production worker count if the same list/detail p95 target must be retained.