Replace tenant-key administration with app access listing and revocation. Show the canonical conversation and rules before submitting a fixture, support opt-in medium AI scoring, and keep credentials server-only.
AI Platform
New AI Platform repository scaffold. The backend and SvelteKit implementation are being developed concurrently; this document records the intended local workflow, not a claim that every command already works.
Runtime layout
- Python 3.13 backend package:
src/ai_platform, served asai_platform.main:app. - PostgreSQL 16 with a new, project-specific Compose volume named
ai_platform_pgdata. - Alembic schema changes are applied as a one-shot Compose service before the backend starts.
- SvelteKit is a separate web image under
apps/web. old_repo/is archived source only and is excluded from Docker build contexts and local checks.
The local Compose stack runs one backend process. It is for development only; default credentials and loopback port mappings are not deployment settings. Keep production secrets outside .env and inject them through the deployment environment or a secrets manager.
Local setup
Copy the backend/Compose template and the separate SvelteKit server-only template. Both .env files are ignored by Git; the previous root .env is preserved under old_repo/.env as historical local data, not loaded by the rebuilt service.
cp .env.example .env
cp apps/web/.env.example apps/web/.env
make install
Start the database and run the backend and web servers in separate terminals:
make db-up
make migrate
make backend-dev
make web-dev
The local web server should call the backend through server-only configuration. Do not expose BACKEND_INTERNAL_URL, database credentials, or provider keys as browser-visible PUBLIC_* variables.
Compose can instead build and start all services, including the one-shot migration step:
docker compose up --build
The database is reachable from the host at 127.0.0.1:55432, backend at 127.0.0.1:8000, and web at 127.0.0.1:3000 by default. To discard only this new database and its data, run docker compose down -v; this does not target archived or unrelated volumes.
The local database starts with only the development database. To run tests safely, create a separate database in that same new PostgreSQL instance, then pass its URL explicitly:
docker compose exec postgres createdb -U ai_platform ai_platform_test
AI_PLATFORM_DATABASE_URL=postgresql+asyncpg://ai_platform:local-change-this-password@127.0.0.1:55432/ai_platform_test make test
make test rejects a database URL that does not contain ai_platform_test. CI provisions its own isolated PostgreSQL 16 test database.
Chấm điểm AI qua CLIProxy khi phát triển local
Không cần chạy AIHub để thử adapter OpenAI-compatible. Cấu hình URL trên backend (trong môi trường hoặc .env local đã có):
AI_PLATFORM_ENVIRONMENT=development
AI_PLATFORM_OPENAI_BASE_URL=http://127.0.0.1:8317
# AI_PLATFORM_OPENAI_API_KEY=... # chỉ cần nếu CLIProxy yêu cầu xác thực
Chạy make backend-dev trên máy host: 127.0.0.1:8317 bên trong Docker không trỏ tới CLIProxy trên host. Trong Admin Web, tạo và kích hoạt một phiên bản Cấu hình AI mới, chọn OpenAI-compatible, nhập URL http://127.0.0.1:8317, model gemini-3.5-flash-lite, prompt và timeout. AI_PLATFORM_OPENAI_BASE_URL là URL mặc định cho profile cũ và là địa chỉ duy nhất nhận AI_PLATFORM_OPENAI_API_KEY; URL khác nhập trong Web không được gửi key đó. Profile cũ mặc định AIHub; URL AIHub vẫn cấu hình bằng AI_PLATFORM_AIHUB_BASE_URL. Lựa chọn này áp dụng cho các run mới của Lead Scoring, không đổi các run đã nhận trước đó. Gửi POST /v1/lead-scoring/runs với ai_profile=medium, ai_weight>0 và tenant key; OpenAI-compatible không dùng X-Tenant-VKey. Nút “Chạy mẫu” trên Web hiện chỉ gửi mẫu quy tắc (ai_weight=0), nên hãy dùng API để thử AI.
Với endpoint OpenAI-compatible chạy ở production, URL phải dùng HTTPS. Key được cấu hình trên server chỉ gửi tới URL được gắn với key đó; thay URL trên Web không tự chuyển key. Không đặt key vào Web hoặc file versioned. CLIProxy local chỉ xác minh được đường gọi thử; chưa chứng minh các điều kiện phát hành production.
Terminal webhook và retention
Khi cấu hình đồng thời AI_PLATFORM_WEBHOOK_URL và AI_PLATFORM_WEBHOOK_SIGNING_SECRET (ít nhất 32 ký tự), backend gửi thông báo kết thúc run tới một URL Omni cố định. URL HTTP chỉ hợp lệ trên loopback khi phát triển. Body chỉ có event_id, run_id, tenant_id, status, occurred_at; header X-Webhook-Timestamp và X-Webhook-Signature chứa chữ ký HMAC-SHA256 trên timestamp + "." + raw body. Phản hồi 2xx xác nhận giao; lỗi được thử lại tối đa 5 lần rồi giữ bản ghi đánh dấu dead. Chỉ bật gửi thực tế sau khi Omni xác nhận fixture chữ ký, chống replay và GET/writeback.
Backend dọn run quá 90 ngày (gồm snapshot, fingerprint và thông báo liên quan) khi khởi động và mỗi ngày. Không áp dụng chính sách này cho backup; cần chốt vòng đời backup và tenant offboarding trước production.
Quality checks
The opt-in pre-commit runner is installed by make install as a project-local development dependency. Run:
make check-fast
make check
make check-fast runs the pinned Ruff and pre-commit-hooks rules. make check additionally runs Python type/import checks and tests; tests must use a separate test database, never a developer or production database. CI uses the same fast hooks and the Makefile test/check commands with an isolated PostgreSQL 16 service.
Operations notes
- Apply migrations as a release step; application startup must not migrate the database.
/health/liveis liveness;/health/readychecks readiness and PostgreSQL. The Compose backend health check waits for readiness.- Avoid logging credentials, request payloads containing personal data, or provider responses with sensitive content.
- The Compose PostgreSQL volume is disposable development data. Backup, restore, retention, secrets, TLS, and alerting must be defined for the eventual deployment target.
The web container currently assumes package.json, bun.lock, a production SvelteKit build at build/index.js, and Bun compatibility with the selected SvelteKit adapter. Confirm those assumptions with the web implementation before treating the image as verified.