Mở rộng & tuỳ biến
Thêm field vào contacts
Phần tiêu đề “Thêm field vào contacts”-
Thêm field vào
shared/types/contact.ts(interfaceContact— cho TypeScript). -
Thêm field vào
app/data/contacts-schema.ts(mảngfields, đúngcollection: "c_contacts") — áp dụng cho cài đặt mới chạy wizard từ đầu. -
Nếu backend đã tồn tại (không chạy lại wizard), tạo field trực tiếp qua ODP API hoặc Data Studio.
-
Thêm tên field vào layout tương ứng trong
app/config/form-layouts.ts(PERSON_FORM_LAYOUT/ORGANIZATION_FORM_LAYOUT/PROFILE_FORM_TAB) để field xuất hiện trên form — field registry tự đọc metadata (type, interface, required…) từ backend, bạn chỉ cần khai báo field này ở tab/section nào. -
Nếu cần đọc field ở trang chi tiết (không phải form), thêm vào
app/config/info-layouts.ts.
Thêm sub-collection mới (vd c_contact_documents)
Phần tiêu đề “Thêm sub-collection mới (vd c_contact_documents)”-
Thêm collection + field + relation vào
contacts-schema.ts(tôn trọng thứ tự phụ thuộc FK — bảng con luôn sauc_contacts). -
Thêm controller mới trong
backend/extensions/contacts/src/endpoints/controllers/(tham khảonotes.controller.tshoặcsocial-links.controller.tsnếu chỉ cần CRUD O2M đơn giản), đăng ký route trongroutes.tsvới đúng action guard (read/update…). -
Nếu form cần field metadata của collection mới, thêm entry vào
COLLECTION_MAPtrongbackend/extensions/contacts/src/endpoints/controllers/meta.controller.ts(map tên rút gọn → tên bảng thật). -
Nếu xoá contact cần xoá luôn bản ghi con mới, thêm tên collection vào
CHILD_COLLECTIONStrongcascade-delete.ts. -
Thêm route BFF trong
server/api/contacts/[id]/<ten>/(theo mẫusocial-links/), rồi composableuse-contact-<ten>.tsgọi các route đó. -
Thêm component + wire vào trang chi tiết (
contact-info-tab.vuehoặc một tab riêng).
Cắm tab vào trang chi tiết contact (từ module của bạn)
Phần tiêu đề “Cắm tab vào trang chi tiết contact (từ module của bạn)”Không cần sửa gì trong Contacts — chỉ cần một plugin trong module của bạn:
export default defineNuxtPlugin(() => { const ext = useExtensionStore()
ext.register("contacts.detail.tabs", { id: "your-module-id", // duy nhất trong điểm mở rộng này label: "Tên tab hiển thị", icon: "i-ph-...", component: defineAsyncComponent(() => import("../components/contacts/your-tab.vue")), sort: 40, // thứ tự so với tab lõi (info=0, notes=10) visible: ctx => ctx.contact?.type === "person", // tuỳ điều kiện })})Component nhận prop contact (object contact đầy đủ) — xem chi tiết cơ chế ở Extension store.
Thêm một intake source mới
Phần tiêu đề “Thêm một intake source mới”Không cần thay đổi code phía Contacts — intake là source-agnostic theo thiết kế. Chỉ cần module của bạn gọi:
await $fetch("/api/intakes", { method: "POST", body: { name, email, phone, source_module: "ten-module-cua-ban", source_ref: "id-tham-chieu-o-module-ban", source_label: "Mô tả người-đọc-được", raw_payload: { /* dữ liệu gốc tuỳ ý */ }, suggested_type: "lead", // tuỳ chọn },})Ràng buộc duy nhất: phải có email hoặc phone. Chi tiết ở Intake pipeline.
Đóng góp type mới vào danh sách quan hệ
Phần tiêu đề “Đóng góp type mới vào danh sách quan hệ”Nếu module của bạn cần một loại quan hệ riêng (vd hr:employee) hiện trong bộ lọc/filter của Contacts mà không cần ghi vào bảng shared_types dùng chung:
export default defineNuxtPlugin(() => { const { register } = useContactTypeRegistry() register({ key: "hr:employee", label: "Employee", icon: "i-ph-user-light", color: "info", owner_module: "hr" })})Đọc tiếp
Phần tiêu đề “Đọc tiếp”- Extension store — cơ chế đầy đủ đứng sau việc cắm tab
- Data model — thứ tự FK, quan hệ, cascade delete
- Intake pipeline — API intake đầy đủ
- Frontend (Nuxt layer + BFF) — field registry, form system