KB-393F
Điều 17-18: Đa domain + i18n + Thay đổi
5 min read Revision 1
lawdieu-17dieu-18multi-domaini18nchatwootlark18-fields
ĐIỀU 17-18: LUẬT ĐA DOMAIN + i18n + SẴN SÀNG THAY ĐỔI
ĐIỀU 17: LUẬT ĐA NGÔN NGỮ + ĐA DOMAIN — 1 HỆ THỐNG, NHIỀU GƯƠNG MẶT
§1. Nguyên tắc
1 codebase + 1 Directus + 1 VPS → NHIỀU domain, NHIỀU ngôn ngữ, NHIỀU thương hiệu. Thêm domain = thêm record + nginx + SSL. Không deploy lại code.
§2. Kiến trúc
User → Nginx (route by domain) → Nuxt SSR (đọc host)
→ Query `domains` WHERE domain_name = host
→ brand, logo, theme, languages → Render cùng code, khác UI
§3. Collection domains — 18 fields (thay thế globals)
| # | Field | Type | Mô tả |
|---|---|---|---|
| 1 | code | DOM-NNN | Mã prefix chuẩn |
| 2 | domain_name | string (unique) | Tên domain |
| 3 | brand_name | string | Tên thương hiệu |
| 4 | tagline | string | Slogan |
| 5 | logo_light | file | Logo nền sáng |
| 6 | logo_dark | file | Logo nền tối |
| 7 | favicon | file | Favicon |
| 8 | theme | json | Màu sắc, font, spacing |
| 9 | languages | M2M | Ngôn ngữ hỗ trợ |
| 10 | default_language | string | Ngôn ngữ mặc định |
| 11 | contact_email | string | Email liên hệ |
| 12 | contact_phone | string | SĐT |
| 13 | social_links | json | Mạng xã hội |
| 14 | og_image | file | Ảnh Open Graph |
| 15 | ssl_status | enum | active/pending/expired |
| 16 | dns_status | enum | configured/pending |
| 17 | nginx_configured | boolean | Nginx đã cấu hình |
| 18 | status | enum | draft/active/deprecated/retired |
§4. i18n — 3 ngôn ngữ BẮT BUỘC
| Ngôn ngữ | Code | Vai trò |
|---|---|---|
| Tiếng Việt | vi-VN | Ngôn ngữ chính |
| Tiếng Nhật | ja-JP | Thị trường mục tiêu |
| Tiếng Anh | en-US | Quốc tế + AI/agents |
Directus _translations. @nuxtjs/i18n. Permalink KHÔNG dịch — giữ slug tiếng Việt.
§5. Kết nối bên ngoài — Chatwoot + Lark Enterprise
Chatwoot (CHỐT DÙNG):
- CSKH đa kênh (Web chat, Zalo, Messenger)
- Webhook → Agent Data (verify HMAC). Chi tiết HMAC: cần RFC riêng (header, clock skew, nonce, secret rotation).
- Log hội thoại thô tại Chatwoot, chỉ insight/ticket chọn lọc → Directus
Lark Suite Enterprise (CHỐT DÙNG):
- Chat nội bộ + Lark Base (kết nối PG native) + Docs + webhook
- 2 mode kết nối Lark↔PG (cần RFC chốt sau PoC):
- FDW read-biased: PG Foreign Data Wrapper đọc Lark Base tables
- Webhook event-biased: Lark Enterprise webhook → PG LISTEN/NOTIFY / Directus Flows
- PG capabilities đủ mạnh cho Assembly First — KHÔNG CẦN n8n/Zapier
- Checklist webhook (áp dụng cho cả Chatwoot + Lark): retry logic, dedupe (idempotency key), ordering guarantee, dead-letter queue cho failed events
§6. Workflow thêm Domain
dot-domain-create --name="domain2.com" --brand="X" --languages="vi-VN,en-US"
→ 1. Tạo record `domains` (DOM-NNN)
→ 2. nginx server block → 3. Certbot SSL → 4. Reload nginx
→ 5. Content skeleton → 6. Verify curl 200 → 7. Update registries
ĐIỀU 18: LUẬT SẴN SÀNG CHO THAY ĐỔI
§1. Nguyên tắc
Có workflow sẵn cho MỌI loại thay đổi. Không "xảy ra rồi mới nghĩ".
§2. Danh sách thay đổi cần workflow (15 loại)
| # | Thay đổi | Workflow | Status |
|---|---|---|---|
| 1 | Thêm domain | dot-domain-create | ❌ TD-088 |
| 2 | Bỏ domain | dot-domain-retire | ❌ |
| 3 | Thêm ngôn ngữ | languages record + locale files | ❌ TD-087 |
| 4 | Thêm collection | dot-entity-create qua Directus API | 🟡 |
| 5 | Thêm module | dot-module-register | 🟡 |
| 6 | Thêm agent | agents record + config | 🟡 |
| 7 | Thêm workflow (state machine) | Chưa thiết kế | ❌ TD-079 |
| 8 | Backup restore test | dot-backup-test-restore | ❌ TD-091 |
| 9 | VPS migration | dot-vps-setup | ❌ TD-092 |
| 10 | Directus upgrade | dot-directus-upgrade | ❌ TD-093 |
| 11 | Scale VPS | Thủ công | ❌ |
| 12 | Disaster recovery | Recovery runbook | ❌ TD-090 |
| 13 | Rotate secrets | keys-refresh | ✅ |
| 14 | Kết nối Lark↔PG | FDW / webhook | ❌ |
| 15 | Cấu hình Chatwoot | webhook + Agent Data + HMAC | ❌ |
§3. Mỗi workflow phải có
Trigger rõ ràng, checklist bước có verify, rollback plan, notify, registry update.
§4. Phát hiện "chưa sẵn sàng"
Chưa có workflow → GHI TD ngay. Tư duy PHÒNG NGỪA.