dotb_ai-platform/docs/specs/ai-platform-lead-scoring.md
hungtran24 6577bb74be refactor: simplify scoring service, AI profile revisions and test suite
Phase 2 and 3 of the platform rework.

- Neutral request/response contract: external_id, metadata, X-AI-Key,
  run_id in the response; client-specific fields removed.
- AI profile is a revision table: saving creates an inactive revision,
  activation is separate, try-run does not store a run. One
  chat-completions gateway serves AIHub and OpenAI-compatible profiles.
- Add between and in rule operators.
- Contracts moved to contracts/lead-scoring/ with a score-response fixture.
- Admin Web updated for revisions, runs and the neutral fixture.
- Consolidate tests; remove rewrite_architect.md and the stale handoff doc;
  rewrite spec, CONTEXT and ARCHITECTURE for the current design.

Not verified: live AIHub/OpenAI behavior, Omni/EMS integration.
2026-10-09 08:23:21 +07:00

5.4 KiB

title, description, status
title description status
AI Platform Lead Scoring Hành vi dịch vụ chấm điểm lead đồng bộ và ranh giới với client. review_ready

Lead Scoring

Dịch vụ AI scoring dùng chung, không giữ trạng thái nghiệp vụ. Client gửi snapshot lead cùng rules/weights, dịch vụ trả điểm, breakdown, tóm tắt, tín hiệu và gợi ý hành động; client tự quyết định phần còn lại (ngưỡng, HITL, CRM writeback). Wire shape do contracts/lead-scoring/openapi.json và fixtures/ xác định; contracts/lead-scoring/README.md là tóm tắt cho client.

Sở hữu

  • Client (hiện là DotB-Omni) sở hữu user/account, quyền EMS, snapshot, rules, weights, ngưỡng điểm, HITL và CRM writeback. Dịch vụ không biết client cụ thể; dữ liệu riêng của client đi trong metadata, được lưu và trả lại nguyên vẹn.
  • AI Platform xác thực app bằng app key, chấm điểm, lưu lần chấm để replay và để Admin Web xem. Admin Web quản lý AI profile, chạy fixtures, xem runs và thu hồi app access.

Endpoint

POST /v1/lead-scoring/score, đồng bộ, trả 200 khi chấm xong.

  • Authorization: Bearer <app_key>: thiếu, sai hoặc bị revoke trả 401.
  • Idempotency-Key: UUID bắt buộc. Unique theo (app_id, idempotency_key), kèm SHA-256 của body chuẩn hóa. Cùng key, cùng body trả kết quả đã lưu và không gọi AI lần hai. Cùng key, khác body trả 422. Hai POST đồng thời cùng key chỉ tạo một bản ghi.
  • X-AI-Key (tùy chọn): khóa AI cho profile AIHub, tối đa 4096 ký tự, không CR/LF (sai thì 422). Chỉ giữ trong RAM trong lúc gọi; không lưu, log hay trả về.
  • Body: snapshot, scoring_config (rule_weight, ai_weight, rules[], tổng weight bằng 1), metadata (tối đa 10KB). Snapshot tối đa 10 conversations, 50 messages, 20.000 ký tự nội dung, 100KB. Field lạ bị 422.
  • Rule: id, field, operator, value, points, description tùy chọn (tối đa 99 ký tự, chỉ gửi cho AI làm ngữ cảnh, không đổi kết quả khớp). field là lead_profile.<name|phone|email|status|external_id>, custom_fields.<key> hoặc metrics.<key>. Operator: eq ne gt gte lt lte contains exists between in. between nhận [min, max] số, gồm cả hai đầu. in nhận list scalar (1 đến 100 phần tử), so khớp nguyên giá trị. Field sai kiểu thì không khớp, không lỗi.

Kết quả

run_id, final_score, rule_score, ai_score, result_mode, error_code, breakdown[], ai {summary, suggested_action, signals[]}, metrics, metadata.

  • ai_weight=0: rules_only, không gọi AI.
  • ai_weight>0 và AI thành công: hybrid, final_score = clamp(round(rule_score*rule_weight + ai_score*ai_weight), 0, 100).
  • Thiếu AI key (AIHub), không có profile active, AI lỗi hoặc quá timeout_seconds: rules_only_fallback, final_score = rule_score, error_code là ai_key_missing, ai_profile_missing, ai_timeout hoặc mã lỗi provider. Không tự retry.
  • Lỗi code hoặc DB trả 5xx; DB không sẵn sàng trả 503 với thông báo an toàn.

AI profile

Admin Web lưu AI profile theo revision tự tăng. Lưu tạo revision mới (không active), kích hoạt là bước riêng và kích hoạt revision cũ là rollback. Profile gồm provider (aihub hoặc openai_compatible), base_url, model, timeout_seconds (1 đến 60), reasoning_effort, instructions (rubric do admin viết), include_reference_date, timezone, suggested_action_enabled. Khung kỹ thuật của prompt nằm trong code. Mỗi run lưu profile_revision. Chạy thử một profile nháp không lưu run và không đổi revision active. Đổi URL có hiệu lực ngay, không restart.

Một lần gọi AI trả JSON {signals[], score, summary, suggested_action}. base_url phải qua safe_http_url: HTTPS, hoặc HTTP chỉ với loopback ở development, không userinfo, query hay fragment. AIHub dùng khóa trong X-AI-Key. OpenAI-compatible dùng AI_PLATFORM_OPENAI_API_KEY, chỉ gửi tới AI_PLATFORM_OPENAI_BASE_URL.

Credential và runtime

  • Một app ID ổn định và một key cho mỗi installation. DB chỉ lưu SHA-256 verifier. Rotate giữ app ID và các run cũ; key cũ hết hiệu lực. Cấp, rotate, revoke qua CLI create-app, rotate-app-key, revoke-app-key; raw key chỉ xuất ở thao tác CLI. Admin session độc lập, password hash, CSRF; Web chỉ list và revoke.
  • App key và AI key không xuất hiện trong DB, log, response hay lỗi.
  • Một backend process. Startup đọc migration head, không tự migrate. Schema chưa phát hành là một migration 0001_initial; database local mang revision cũ cần dựng lại hoặc xử lý riêng.

Nghiệm thu và chưa xác minh

Đã kiểm tra bằng test cục bộ: các chế độ kết quả, replay và xung đột idempotency, truy cập đồng thời, xác thực, hình dạng prompt và request tới provider qua transport giả, contract khớp code, migration khớp models.

Chưa xác minh: hành vi AI thật (AIHub, model, reasoning_effort, temperature, độ trễ, quota), tích hợp Omni/EMS, chất lượng điểm bằng dữ liệu có nhãn, và hạ tầng production (hosting, TLS, secret, backup, alerting, retention). Không tuyên bố production-ready từ kiểm tra cục bộ.