Liên kết phòng khám dùng DentIQ

Khi một phòng khám đã dùng DentIQ làm PMS, ta không muốn họ gõ tay đơn hai nơi. Luồng này dựng một cạnh kết nối kỹ thuật có đồng thuận giữa DentIQ và DentIQ Lab: labo phát mã, phòng khám đồng ý, rồi từ trạng thái linked, tạo đơn labo bên DentIQ là tự sync sang DentIQ Lab và trạng thái sản xuất map ngược về cho phòng khám. Một case, hai projection — hết double-entry.

Bảng kết nối phía labo: danh sách phòng khám DentIQ đã/để kết nối, trạng thái cạnh, nút phát mã và gỡ
Bảng kết nối phía labo: mỗi dòng là một phòng khám DentIQ với trạng thái cạnh, nút phát mã kết nối và nút gỡ. Đơn từ cạnh linked tự chảy sang DentIQ Lab.

Bối cảnh

Labo đã có tài khoản DentIQ Lab. Một phòng khám đối tác đang dùng DentIQ và đã có dòng "nhà cung cấp labo" trỏ tới labo này, nhưng chưa có cạnh kết nối kỹ thuật — hôm nay họ vẫn chép đơn thủ công qua Zalo/điện thoại. Hai bên muốn bật đồng bộ tự động: một lần bắt tay, sau đó mỗi đơn labo bên DentIQ tự thành work order submitted bên DentIQ Lab, và tiến độ sản xuất hiện ngược cho phòng khám. Kết nối là tùy chọn cộng thêm: chưa link thì mọi thứ chạy y hệt như trước.

Diễn viên & quyền cần

Vai tròQuyền/điều kiệnHành động
Chủ / quản lý laboVai quản lý labo trên DentIQ LabPhát mã kết nối (QR/mã), thu hồi/tạm dừng, theo dõi các cạnh đã kết nối
Admin phòng khám (trên DentIQ)Quyền quản master-data "nhà cung cấp labo"Dán mã vào dòng nhà cung cấp labo → đồng ý kết nối; gỡ bất cứ lúc nào
Hệ thống (connector)Xác thực handshake, lập secret webhook, suy ra suspended khi webhook lỗi quá ngưỡng, giữ idempotency theo external-ref

Quy trình từng bước

  1. Labo phát mã. Labo sinh một mã kết nối (QR/mã) ngắn hạn, dùng-một-lần. Cạnh chuyển unlinked → code_issued.
  2. Clinic đồng ý. Admin phòng khám dán mã vào dòng "nhà cung cấp labo" trên DentIQ → handshake xác thực hai phía → lập secret webhook. Cạnh code_issued → linked. Nếu mã hết hạn trước khi đồng ý → code_issued → expired.
  3. Sync chạy. Từ linked, khi DentIQ gửi đơn labo → tự đẩy sang DentIQ Lab thành work order submitted (kênh DentIQ-connected intake), không gõ lại.
  4. Map ngược trạng thái. Vòng đời sản xuất của case bên DentIQ Lab map ngược về DentIQ, phòng khám thấy tiến độ mà không cần hỏi. Transport (webhook/outbox/idempotency) và bảng map trạng thái nằm ở tài liệu kỹ thuật dentiq-sync.
  5. Tạm dừng / gỡ. Webhook lỗi quá ngưỡng hoặc xoay secret → suspended (đơn xếp hàng, không mất). Bên nào cũng gỡ được → revoked. Muốn nối lại → labo phát mã mới (→ code_issued).

Kết quả mong đợi

  • Cạnh ở linked: tạo đơn labo một phía tự dựng projection phía kia — hết double-entry.
  • Đồng thuận hai chiều: labo phát, clinic đồng ý; không bên nào tự kết nối bên kia. Cả hai gỡ được bất cứ lúc nào.
  • Handshake an toàn: mã ngắn hạn dùng-một-lần, secret xoay được, payload webhook ký + verify, replay idempotent.
  • Gỡ/hết hạn không mất dữ liệu: case đã sync giữ nguyên, hai bên rớt về cập nhật thủ công, không hồi quy.

Khi nào hỏng & cách xử lý

Triệu chứngNguyên nhânKhắc phục
Dán mã không đồng ý đượcMã đã hết TTL hoặc đã dùng rồi (dùng-một-lần)Cạnh → expired; labo phát mã mới rồi dán lại (LC-4)
Cạnh tự chuyển suspended, đơn không chảyWebhook lỗi quá ngưỡng hoặc đang xoay secretĐơn được xếp hàng không mất; sửa webhook/secret rồi nối lại — không cần tạo case lại (LC-5)
Đồng ý lại/phát lại tạo cạnh trùngLo nhân đôi cạnh kết nốiKhông xảy ra: idempotent theo external-ref, một labo ↔ một phòng khám DentIQ đúng một cạnh (LC-1)
Phòng khám lo mất dữ liệu khi gỡHiểu nhầm gỡ = xoárevoked/suspended/expired không xoá case đã sync; giữ lab_work_order, rớt về thủ công (LC-5)
Bên thứ ba tự ý kết nốiSai mô hình đồng thuậnTừ chối: labo chỉ phát, clinic phải chủ động đồng ý — đồng thuận hai chiều (LC-3)
Lưu ý

Đây là kênh kết nối kỹ thuật cho phòng khám dùng DentIQ, khác với kênh quan hệ ở Labo go-live / nâng cấp tài khoản clinic (mời phòng khám không dùng PMS qua connectionless intake). Chưa kết nối thì phòng khám DentIQ vận hành y hệt hôm nay — sync là cộng thêm, không bao giờ bắt buộc, không hồi quy.