7.3 KiB
Architecture
Status and scope
This document describes the intended architecture for the rebuilt AI Platform, not a verified description of working code. The root Lead Scoring provider specification is docs/specs/ai-platform-lead-scoring.md; it remains draft/review_ready pending review. Its ownership boundary is authoritative only after approval. The archived code and documents under old_repo/ are historical evidence, not the new architecture or implementation.
AI Platform is a provider service: it executes bounded rule scoring and a selected AI profile, maintains scoring-run lifecycle, and exposes result retrieval. DotB-Omni owns customer-configured rules/weights, HITL and customer actions, snapshot construction, user authorization, and CRM writeback. Omni is notified of terminal outcome through an agreed signed HMAC webhook and then calls the authenticated GET endpoint for run details. DotB EMS remains the CRM system of record. There is no customer-facing settings or review UI in this service scope.
Intended backend boundaries
The proposed modular monolith has one runtime and one deployable backend. These names describe target ownership, not files already present.
- Bootstrap/composition: loads validated settings and composes framework, database, provider client, and application workflows. Resource lifetime is established here.
- Platform: tenant-key verification and tenant isolation, shared persistence/runtime concerns, and operational interfaces. It does not own Omni customer configuration or user permissions.
- Lead Scoring domain: rule execution, scoring-run state/invariants, and profile semantics. Deterministic scoring rules should be pure functions; run identity and lifecycle belong in an entity/value model where useful.
- Lead Scoring application: admission, idempotency, execution coordination, result retrieval, and notification workflow. Use cases own transaction meaning; infrastructure supplies mechanisms. Its versioned AI profile selects AIHub or OpenAI-compatible for the service and contains model, prompts and timeout; OpenAI-compatible URL is also versioned, while API key stays in server settings. App-provided rules and weights arrive in each run body. Bootstrap constructs the AIHub adapter and an OpenAI-compatible adapter for the URL captured in the run's profile; raw V-Key is forwarded only for AIHub.
- Infrastructure: database mappings/repositories, separate AIHub and OpenAI-compatible HTTP adapters, HMAC signing, and delivery adapters. Provider details stop at these boundaries.
- Presentation: HTTP request/response mapping, tenant-auth dependency at the edge, health/readiness, and API error mapping. Transport schemas do not become domain objects by accident.
Dependency direction is inward: presentation and infrastructure may depend on application/domain contracts; domain does not depend on frameworks, persistence, network, environment, or application orchestration. Bootstrap is the composition root. Avoid generic base services, empty ports, service locators, and multiple deployment processes unless evidence requires them.
Lifecycle and data invariants
- Authenticate and establish the tenant boundary before accessing a run.
- Validate bounded request input and calculate a stable canonical-body fingerprint.
- Scope client-supplied UUID idempotency to the tenant. Same UUID/same canonical body resolves to the existing run; same UUID/different body conflicts. The service generates a distinct run UUID.
- Commit admitted run before acknowledging acceptance. Execution holds raw V-Key only in current process memory; it is never persisted.
- Rules-only requires no AIHub or V-Key; medium bounded two-pass is the default when AI is requested. Light/heavy are deferred until verified demand, not placeholders.
- Persist terminal outcome independently from notification delivery. Signed webhook informs Omni, which performs authenticated GET for the authoritative result.
- One-process recovery terminalizes work that cannot resume after interruption. It does not restore the lost V-Key or promise an automatic retry.
- Delete/redact sensitive run material at 90 days under an approved policy; tenant offboarding and backup treatment need operational decisions.
These are target constraints, not statements that the code currently enforces them. See the spec for unresolved contract and review gates.
Transaction and effect boundaries
- Application use cases define atomic boundaries, including run transition and any durable notification intent where selected. Persistence adapters implement transactions.
- AIHub requests are network effects with explicit timeout and bounded policy once AIHub behavior has been verified. Never add speculative provider retries.
- HMAC delivery is an effect with bounded retry and observable terminal delivery state. Exact signing and replay rules are contract decisions with Omni.
- Clock, UUID generation, provider client, and persistence are explicit inputs at the application boundary when deterministic testing or lifecycle behavior requires them.
- Domain functions are deterministic and I/O-free. Stateful objects are justified by identity, invariant, or lifecycle rather than used as namespaces.
Admin Web design system
Admin Web dùng SvelteKit 5, Tailwind CSS v4 semantic tokens, shadcn-svelte component source cho button/input/card/badge/table khi UI cần, Bits UI cho dialog/dropdown/popover hoặc tương tác phức tạp, và một icon family Lucide nếu cần icon. Chỉ thêm component đang dùng, không scaffold cả catalog. src/lib/components/ui/ chỉ chứa primitives không biết domain; route giữ thành phần chỉ dùng tại route. HTML native là lựa chọn đúng cho form, label và bảng đơn giản khi không cần behavior phức tạp. Style tokens có một nguồn trong apps/web/src/app.css; UI phải kiểm tra focus, keyboard, validation, responsive và contrast. Browser chỉ gọi SvelteKit; backend auth/credentials và BACKEND_INTERNAL_URL thuộc $lib/server/. Không tạo frontend Clean Architecture giả lập.
Verification structure (target)
- Unit: domain calculations, validation and transitions without network/database.
- Integration: persistence/migrations on the selected production database and AIHub HTTP adapter with controlled transport.
- Functional: HTTP request through application/persistence and back, including tenant isolation and idempotency.
- Architecture: import direction, framework isolation, and composition-root rules.
- Contract: shared provider/Omni fixtures for requests, replay conflicts, result GET, HMAC delivery, acknowledgements, and errors.
- Operational: process interruption, recovery terminality, 90-day redaction, secret-leak sentinels, and deployment restore drills.
Actual test commands, directories, and enforcement must follow checked-in tooling once present; do not describe this target taxonomy as an existing test suite.
Deferred decisions
Production hosting/orchestrator, network and TLS topology, secret manager and rotation ownership, database backup/restore and deletion guarantees, alerting/observability destination, load/SLO targets, exact contract publication/versioning, and AIHub protocol/model/timeouts remain deferred. Resolve them with accountable owners before the corresponding implementation or deployment. No production-readiness claim is warranted while these remain open.