LumiBaseDocs

POST-GA Walkthrough — Đã hoàn thành

Tổng quan

Đã triển khai hoàn tất 100% (9/9) các task chính trong Phase POST-GA bao gồm cả phần Backend, Database schema, AI Copilot, Frontend UI, và kiểm thử tự động.


Task 1: [AI] LLM Provider thật ✅

Thay mock analyzeIntent() bằng real LLM provider abstraction.

Files tạo mới

  • apps/cms/src/services/llm-provider.ts — Provider abstraction với 4 implementation:
    • OpenAIProvider — gọi OpenAI Chat Completions API (gpt-4o-mini default), tool calling format
    • AnthropicProvider — gọi Anthropic Messages API (claude-sonnet-4-20250514 default), native tool_use
    • WorkersAIProvider — gọi Cloudflare Workers AI REST API, OpenAI-compatible tool format
    • EchoProvider — backward-compat keyword matcher (legacy behavior), dùng khi không có API key
    • createLLMProvider(env) factory — chọn provider theo LLM_PROVIDER env var
    • System prompt tích hợp CMS context + safety rules

Files sửa

  • apps/cms/src/env.ts — Thêm 7 env vars: LLM_PROVIDER, OPENAI_API_KEY, ANTHROPIC_API_KEY, WORKERS_AI_ACCOUNT_ID, WORKERS_AI_API_TOKEN, WORKERS_AI_GATEWAY
  • apps/cms/src/routes/ai.ts — Rewrite toàn bộ: thay analyzeIntent() bằng llmProvider.chat() → parse tool_calls → execute via harness

Task 2: [AI] Context Memory ✅

Thêm lịch sử conversation cho AI Copilot — messages persist qua sessions.

Schema mới

  • packages/database/src/schema/ai.ts — 2 bảng mới:
    • ai_conversations (id, siteId, userId, title, createdAt, updatedAt)
    • ai_messages (id, conversationId, role, content, toolCalls jsonb, metadata jsonb, createdAt)

Routes mới

  • apps/cms/src/routes/ai.ts — Thêm:
    • POST /chat giờ nhận conversationId optional, tự tạo conversation nếu không có, persist messages, load last 20 messages làm LLM context
    • GET /conversations — list conversations (sorted by updatedAt desc)
    • GET /conversations/:id/messages — get messages trong conversation
    • DELETE /conversations/:id — xóa conversation + cascade messages

Frontend

  • apps/studio/src/components/ai-assistant.tsx — Thêm:
    • State conversationId, truyền trong request body
    • Dropdown chọn conversation cũ (load từ GET /conversations)
    • "New conversation" button
    • Delete conversation button
    • Auto-load messages khi switch conversation

Task 3: [AI] RAG Skills ✅

Thêm aiSuggestField + aiContentAssist skills + embedding service.

Files tạo mới

  • apps/cms/src/services/embedding-service.ts — Provider abstraction:
    • OpenAIEmbeddingProvider — text-embedding-3-small (1536 dims)
    • WorkersAIEmbeddingProvider — @cf/baai/bge-base-en-v1.5 (768 dims)
    • EchoEmbeddingProvider — deterministic pseudo-embeddings cho testing
    • cosineSimilarity() helper function
    • createEmbeddingProvider(env) factory

Schema mới

  • packages/database/src/schema/ai.ts — Bảng ai_embeddings:
    • JSONB vector storage (note: migrate sang pgvector khi cần ANN search)
    • Indexed by siteId + collection, itemId

Skills registry

  • packages/ai-skills/src/skills.ts — 2 skill definitions mới:
    • aiSuggestField — gợi ý field dựa trên description + existing schema
    • aiContentAssist — generate/edit content cho field dựa trên RAG context

Harness wiring

  • apps/cms/src/services/ai-harness.ts — Thêm:
    • generateFieldSuggestions() helper — pattern matching 16 field types
    • aiSuggestField handler — wired to SchemaService
    • aiContentAssist handler — placeholder cho full LLM integration
    • Service type mở rộng: 'schema' | 'items' | 'ai'

Task 4: [BE] Materialized Collection Write ✅

Nâng cấp từ DDL vật lý đến tự động đồng bộ hóa trên mọi thay đổi của items.

Files tạo mới

  • apps/cms/src/services/materialize-service.ts — Các tác vụ DDL:
    • createPhysicalTable() — Khởi tạo bảng mat_{target}.
    • refreshPhysicalTable() — Đồng bộ bằng TRUNCATE + INSERT INTO ... SELECT từ items.
    • dropPhysicalTable() — Xóa bảng DDL vật lý khi hủy cấu hình.
    • installAutoRefreshTrigger() — PG trigger để tự động hóa refresh.
    • queryPhysicalTable() — Đọc trực tiếp từ bảng vật lý cho Delivery API.

Files sửa

  • apps/cms/src/routes/materialize.ts — Mount endpoints và tích hợp tạo bảng.
  • apps/cms/src/services/item-service.ts — Bổ sung cơ chế auto-refresh:
    • Sau mỗi thao tác viết (create, patch, softDelete), hệ thống kiểm tra và tự động trigger/enqueue refresh cho các materialized collection tương ứng (hoàn thành Sub-task A).

Task 5: [BE] Multi-region DO Sharding ✅

Files tạo mới

  • apps/cms/src/realtime/shard-config.ts — Region mapping:
    • 60+ IATA colo codes → 5 regions (wnam, enam, weur, eeur, apac)
    • getRegionFromColo(), getShardKey(), getLocationHint(), isShardingSupported()
    • Docker fallback: undefined location hint → single instance

Routes sửa

  • apps/cms/src/routes/realtime.ts — Thêm:
    • Region detection từ cf.colo request property
    • Shard key format: {siteId}:{region} cho DO naming
    • locationHint passed to siteRoom.get(id, { locationHint })
    • Region param forwarded to DO via query string

Task 6: [FE] Marketplace Browser UI ✅ (Sub-task B)

Xây dựng trang tìm kiếm và cài đặt extensions ngay trong Studio.

Files tạo mới

  • apps/studio/src/modules/settings/marketplace-page.tsx — Giao diện Marketplace:
    • Grid card hiển thị thông tin extension, nhà phát hành, phiên bản, loại tiện ích.
    • Tìm kiếm theo từ khóa và bộ lọc động theo phân loại (Module, Layout, Display...).
    • Modal chi tiết hiển thị mô tả, capabilities, và danh sách các requested permissions.
    • Hiển thị thông tin chữ ký mã hóa của nhà phát hành (Verified Signature).
    • Tích hợp nút Install gọi API cài đặt và hiển thị badge "Installed" ngay khi thành công.

Files sửa

  • apps/studio/src/router.tsx — Cấu hình định tuyến lazy-loaded cho /settings/marketplace.
  • apps/studio/src/components/app-shell.tsx — Thêm liên kết Marketplace vào menu Settings.

Task 7: [FE] Flows Visual Editor ✅ (Sub-task C)

Tạo trình vẽ đồ thị tự động hóa kéo thả trực quan.

Thư viện cài đặt

  • @xyflow/react (React Flow) cho vẽ đồ thị và xử lý các sự kiện kết nối.

Files tạo mới

  • apps/studio/src/modules/automation/flow-editor.tsx — Visual canvas vẽ đồ thị:
    • Palette bên trái chứa các operation blocks (Condition, Transform, HTTP, Mail, Log, Sleep, Database CRUD).
    • Canvas kéo thả, nối các handle bằng edge thành công (Next) hoặc thất bại (OnError).
    • Bảng cấu hình (Config Panel) bên phải động theo từng loại node được chọn.
    • Hỗ trợ lưu trữ đồ thị JSON qua PATCH /api/v1/flows/:id và chạy thử (Test Run).
  • apps/studio/src/modules/automation/flow-node-types.tsx — Đăng ký các node tùy chỉnh với icon và handles tương ứng.

Files sửa

  • apps/studio/src/modules/automation/flows-page.tsx — Bổ sung nút tạo mới và chỉnh sửa dẫn đến editor.
  • apps/studio/src/router.tsx — Thêm route /automation/flows/$id/automation/flows/new.

Task 8: [BE] SCIM Token Rotation + Audit ✅ (Sub-task D)

Nâng cấp bảo mật SCIM xác thực qua database hashed tokens, hỗ trợ rotate và ghi nhật ký hoạt động.

Schema mới

  • packages/database/src/schema/access.ts — Bảng scim_tokens:
    • id, siteId, tokenHash (SHA-256), label, createdBy, expiresAt, revokedAt, lastUsedAt, createdAt.
    • Index trên siteId + tokenHash.

Files tạo mới

  • apps/cms/src/routes/scim-admin.ts — Cổng quản trị tokens (yêu cầu Logto JWT):
    • POST / — Sinh token mới (trả plaintext một lần duy nhất).
    • GET / — Liệt kê metadata các token hiện có.
    • DELETE /:id — Thu hồi (revoke) token.
    • POST /:id/rotate — Sinh token mới và đánh dấu hết hạn token cũ sau 24 giờ (grace period).

Files sửa

  • apps/cms/src/routes/scim.ts — Thay đổi auth middleware:
    • Băm Bearer token bằng SHA-256 trước khi tìm kiếm trong bảng scim_tokens.
    • Tự động lấy trực tiếp siteId từ token để ngăn chặn việc giả mạo header X-Lumi-Site (Spoofing).
    • Ghi hoạt động SCIM (scim.user.create, scim.group.patch...) vào bảng activity.
  • apps/cms/src/index.ts — Khởi chạy /scim-tokens router.

Task 9: [OPS] Multi-tenant Isolation Testing (k6) ✅ (Sub-task E)

Đo lường cô lập dữ liệu và kiểm tra lỗ hổng rò rỉ tenant.

Files tạo mới

  • apps/cms/k6/helpers/setup-tenants.js — Thiết lập hai sites test độc lập kèm tokens/collections và tự động dọn dẹp (teardown).
  • apps/cms/k6/cross-site-leak.js — Script k6 chạy 5 kịch bản cô lập:
    • Scenario 1 — Data: Viết dữ liệu ở site A, kiểm tra site B có xem được không (Yêu cầu: Không).
    • Scenario 2 — Auth: Dùng token site A truy cập API site B (Yêu cầu: Rejected 403).
    • Scenario 3 — SCIM: Dùng SCIM token site A spoofing header site B để tạo user (Yêu cầu: Bị ép buộc về site A).
    • Scenario 4 — Search: Tìm kiếm ở site A không hiển thị kết quả của site B.
    • Scenario 5 — Realtime: Subscriber WebSocket ở site A không nhận được sự kiện biến động của site B.

Files sửa

  • apps/cms/src/routes/admin.ts — Hỗ trợ thêm API cho phép admin tạo và xóa site để phục vụ k6 script.

🛠️ Kết quả Kiểm thử & Biên dịch ✅ (Sub-task F)

1. TypeScript Typecheck

  • Đã khắc phục toàn bộ lỗi ép kiểu Durable Objects, destructuring returning rows, import dependencies thiếu, và ép kiểu generic Node<any> của React Flow.
  • Chạy pnpm typecheck thành công 100% trên cả 11 packages của monorepo.

2. Unit/Integration/Property Testing

  • Chạy thành công toàn bộ test suites (pnpm test) với 62/62 tests passed hoàn toàn, đảm bảo không có bất kỳ regression lỗi nào xảy ra.
Last modified: 23/07/2026