ONE-ANNA — Tổng quan¶
Tài liệu nội bộ cho đội dự án và người dùng portal. Viết từ code nhánh
feat/lich-hop(commitda90b4b4), cấu hình Workerone-anna-api, D1one-anna-buffer(chỉ SELECT) và cấu trúc các Lark Base (đọc qua Lark API), ngày 22/10/2026. Chỗ ghi cần xác nhận là chỗ chưa kiểm chứng được từ nguồn.
1. Mục đích¶
ONE-ANNA là portal nội bộ của Kính mắt ANNA gom việc của Nhân sự (HR), Chăm sóc khách hàng (CSKH) và Vận hành cửa hàng vào một chỗ, chạy trong app Lark:
- Nhân viên xem chấm công, phiếu lương, hồ sơ, KPI, học tập của chính mình; đặt lịch họp; gửi yêu cầu pháp chế; dùng tài liệu.
- Quản lý (AM, RSM, QLCH, Leader SS…) xem báo cáo doanh thu, lượt khách, xử lý ticket CSKH, chấm KPI, phỏng vấn ứng viên.
- HR / CSKH / Pháp chế / BOD xem báo cáo tổng hợp, quản trị dữ liệu và phân quyền.
- Tự động hoá: ~70 job định kỳ và các event Base tạo dòng dữ liệu, đối soát, sao lưu và gửi thông báo Lark (bot ONE - ANNA).
Dữ liệu gốc nằm trên Lark Base; ONE-ANNA đọc/ghi Base qua Lark Open API và giữ bộ đệm, nhật ký, khoá ở Cloudflare D1/KV.
2. Kiến trúc¶
| Thành phần | Chi tiết |
|---|---|
| Worker | one-anna-api (apps/api, src/index.js, nodejs_compat). URL: https://one-anna-api.tungpham-hn219.workers.dev |
| Giao diện | Bundle tĩnh trong apps/api/portal-assets (nguồn: apps/web/* — lark-shell, cskh, kpi, lich-hop, phan-quyen, luot-khach…). Giao diện cũ (?ui=old) từ legacy/gas/Index.html |
| RPC | POST /rpc — gọi theo tên hàm. Hàm "native" chạy trong Worker; một số hàm còn chuyển sang GAS (GAS_ASYNC_RPCS) |
| Lưu trữ | D1 one-anna-buffer, KV ANNA_KV, 4 Queue (xem Lưu trữ) |
| Quan sát | Workers Observability (head sampling 0.2) |
| Pages | Project one-anna chỉ còn chuyển hướng / OAuth dự phòng |
Các route chính của Worker¶
| Route | Việc |
|---|---|
/app |
Portal (giao diện). ?ui=old\|lark\|auto chọn giao diện; ?cskh_table=&cskh_record= mở thẳng bản ghi CSKH |
/login, /auth/callback |
Đăng nhập Lark OAuth |
/rpc |
Gọi hàm dữ liệu |
/api/me, /api/me/attendance/month, /api/me/attendance/sync |
Thông tin người đăng nhập, chấm công tháng |
/ats-photo, /cv-file |
Ảnh, CV ứng viên |
/api/cskh/drive/folder\|file, /api/cskh/mark-notify-viewed |
Tệp và đánh dấu đã xem của CSKH |
/webhook, /api/webhook/* |
Event Base, thẻ tương tác, Lark Automation (xem Trigger) |
/cron, /api/run |
Chạy tay một cron / job (cần secret) |
/health, /api/version, /api/d1/ping, /diag* |
Kiểm tra sức khoẻ, phiên bản, chẩn đoán |
3. Đăng nhập¶
- Trong app Lark (Workplace › ONE-ANNA): tự đăng nhập (
tt.requestAuthCode→completeLarkLoginWithCode), không cần thao tác. - Trình duyệt: mở
https://one-anna-api.tungpham-hn219.workers.dev/app→ chuyển tới/login→ đăng nhập Lark (OAuth) → quay về/auth/callback→/app. - Quyền trong portal theo bảng Phân quyền Portal (mục 5). Điều kiện chính xác để một tài khoản Lark vào được portal và thời hạn phiên: cần xác nhận.
Chi tiết: Trang chủ & Đăng nhập.
4. Danh sách module¶
| Module | Vị trí trên portal (Rail) | Tài liệu |
|---|---|---|
| Trang chủ & Đăng nhập | Hôm nay (home) | Base dữ liệu · ERD |
| Trung tâm nhân sự (TT nhân sự) | TT nhân sự (ns) | Base dữ liệu · ERD |
| Báo cáo nhân sự (M1–M5) | Nhân sự (hr) › Báo cáo nhân sự | Base dữ liệu · ERD |
| KPI | Nhân sự (hr) › KPI; TT nhân sự › KPI cá nhân | Base dữ liệu · ERD |
| Tuyển dụng (ATS) | Tuyển dụng (td) | Base dữ liệu · ERD |
| Đào tạo | Đào tạo (dt); TT nhân sự › Học tập | Base dữ liệu · ERD |
| Báo cáo doanh thu (RSM) & Lượt khách | Doanh thu (kd) | Base dữ liệu · ERD |
| Chăm sóc khách hàng (CSKH) | CSKH (cskh) | Base dữ liệu · ERD |
| Pháp chế | Pháp chế (pc) | Base dữ liệu · ERD |
| Lịch họp | Lịch họp (hop) | Base dữ liệu · ERD |
| Tài liệu (Lark Wiki) | Tài liệu (tl) | Base dữ liệu · ERD |
| Quản trị (phân quyền, truy cập, Chứng từ, KSNB, HR Admin) | Quản trị (qt) | Base dữ liệu · ERD |
| Vận hành cửa hàng (tự động hoá Base Vận hành) | Không có rail riêng — thông báo Lark | Base dữ liệu · ERD |
Thanh Rail bên trái portal: Hôm nay · TT nhân sự · Nhân sự · Tuyển dụng · Đào tạo · Doanh thu · CSKH · Pháp chế · Lịch họp · Tài liệu · Quản trị (mục hiện theo quyền).
5. Vai trò và phân quyền¶
5.1 Nguồn quyền¶
Quyền đọc từ bảng HRIS Phân quyền Portal (tblBk8DNs33GZt7N): mỗi dòng một người (cột "User ID" = mã nhân viên), cột vai trò, Chi nhánh / Khu vực phụ trách (cắt phạm vi số liệu doanh thu), Trạng thái (Ngưng = chặn), và các cột checkbox chức năng. Danh mục chức năng: apps/api/src/portal/role-core/catalog.js. Màn sửa: Quản trị phân quyền.
5.2 Vai trò (thứ tự ưu tiên khi một người có nhiều vai trò)¶
super admin › admin › bod › hr › quản lý cskh › ksnb › rsm › am › leader ss › ss › cskh › qlch › ktv › stylist › nhân viên.
- Không giới hạn chức năng: super admin, admin, hr — trừ các ô Admin phải tick rõ (bên dưới).
- Mặc định khi chưa tick gì: bod, rsm, am, leader ss, ss → quyền tự phục vụ nhân sự + Báo cáo RSM/AM + Tài liệu; vai trò khác → quyền tự phục vụ nhân sự + Tài liệu.
- Admin phải tick rõ: Báo cáo RSM/AM, các ô CSKH, Báo cáo KPI.
- Chỉ Super Admin: Quản trị phân quyền.
- Vai trò CSKH (AM, QLCH, KTV…) trong module CSKH còn đọc từ vai trò trên Base CSKH.
5.3 Cột chức năng (checkbox trên bảng Phân quyền Portal)¶
| Nhóm | Cột trên Base | Khoá | Mở cái gì |
|---|---|---|---|
| Trung tâm nhân sự | Chấm công · Phiếu lương · Quản lý đơn từ · Thông tin cá nhân · KPI Cá nhân | HRM_ATTENDANCE · HRM_PAYSLIP · HRM_LEAVE · HRM_PROFILE · HRM_KPI | TT nhân sự |
| Báo cáo nhân sự | M1 Hồ sơ · M2 Công & Lương · M3 Luân chuyển · M4 Vòng đời | REPORTS_PROFILE · REPORTS_WORKPAY · REPORTS_MOBILITY · REPORTS_LIFECYCLE | Nhân sự › Báo cáo |
| Tuyển dụng | Xem ứng viên · Đánh giá ứng viên | RECRUITMENT_VIEW · RECRUITMENT_EVAL | Tuyển dụng |
| Doanh thu | Báo cáo RSM/AM | RSM_REPORTS | Doanh thu |
| CSKH | Báo cáo CSKH · Xử lý ticket CSKH · Hồ sơ 360 nhân sự | CSKH_REPORTS · CSKH_OPERATE · CSKH_EMPLOYEE_360 | CSKH |
| KPI | Báo cáo KPI | KPI_VIEW | Nhân sự › KPI |
| Tài liệu | Tài liệu | TAI_LIEU | Tài liệu |
| Quản trị | HR Admin · Lịch sử truy cập · Quản trị phân quyền | ADMIN_HR · ADMIN_ACCESS_LOG · ADMIN_PERMISSIONS | Quản trị |
5.4 Quyền không đi qua bảng Phân quyền¶
| Module | Quy tắc |
|---|---|
| Đào tạo, TT nhân sự › Học tập | Đang chạy thử: Tùng + danh sách trong config/training-access.mjs |
| Pháp chế | Mọi người: Quản lý yêu cầu, Báo cáo yêu cầu. Nhân sự pháp chế (config/phap-che-access.mjs) hoặc BOD: Báo cáo tổng hợp, Vận hành, Quản lý hồ sơ |
| Lịch họp | Mọi người đã đăng nhập; sửa/huỷ: người tạo, Host, Admin |
| Màn mới đang thử (canary) | Chỉ Tùng (config/ui-lark.mjs › canaryUsers): Dashboard của tôi, Dashboard quản trị, Chứng từ, KSNB, HR Admin giao diện mới, Cài đặt KPI, r252, dashboard Tài liệu / Lịch họp |
Luật hiển thị phía giao diện: apps/web/lark-shell/src/v16/perm.ts; máy chủ kiểm lại mỗi RPC.
6. Lưu trữ¶
| Nơi | Dùng cho |
|---|---|
| Lark Base | Dữ liệu nghiệp vụ gốc (HRIS, CSKH, KPI, RSM, ATS, Đào tạo, Lượt khách, Vận hành, Pháp chế, Sinh nhật) |
D1 one-anna-buffer |
Bộ đệm và nhật ký: access_log, audit_logs, cskh_write_log, rpc_write_log, employee_attendance_cache, att_dirty, payroll_*, report_snapshot, meetings/meeting_*, pc_*, perm_*, revoked_users, trigger_runs, trigger_switches, scheduled_job_locks, short_locks, deploy_lock, deploy_log, lark_event_dedup, webhook_inbox, im_send_outbox, pending_records, data_reconciliation_*, lark_user_tokens (mã hoá)… Migration: apps/api/migrations |
KV ANNA_KV |
Khoá gửi-một-lần, con trỏ đồng bộ, cache ngắn |
| Queues | one-anna-lark-events (event Lark), one-anna-media (ảnh/tệp), one-anna-jobs (job định kỳ nặng), one-anna-dlq (thư lỗi) |
Bảng lark_api_usage có trong tài liệu cũ (migration 008) nhưng không thấy trên D1 live — cần xác nhận.
7. Trigger và cron¶
Nguồn sự thật: config/triggers.registry.mjs; trang đầy đủ docs/04-van-hanh/triggers.md sinh bằng node tools/triggers/render.mjs (kiểm: node tools/triggers/check.mjs). Tổng: 71 job theo lịch · 35 cron · 17 event Base · 10 webhook.
- Bật/tắt/dry-run một job không cần deploy: ghi bảng D1
trigger_switches(tên job, enabled, dry_run, lý do, người sửa). - Job nặng chạy qua Queue
one-anna-jobscho các cron trongJOBS_QUEUE_CRONS. Cột "Chạy bằng":native= trong Worker,GAS= còn gọi Apps Script. - Lịch họp:
meetingLarkReconcilemỗi 5 phút, nhắc họp chạy cùng lượt.
7.1 Job theo lịch¶
| Job — mô tả | Nhóm | Tác động | Giờ chạy (VN) | Chạy bằng |
|---|---|---|---|---|
runDailySync — Đồng bộ giờ cửa hàng → bảng 3.11 |
Chấm công | sync | 02:00 VN hằng ngày | GAS |
runMonthEndCatchUp — Chốt kỳ địa điểm tháng trước → bảng 3.11 (chỉ ngày 1) |
Chấm công | seed | 00:30 VN hằng ngày | GAS |
runMonthlySummary — Tổng hợp bảng 3.12 |
Chấm công | sync | 22:15 VN hằng ngày | GAS |
scanDuplicateRecords — Quét bản ghi trùng 3.4/3.6/3.7 mỗi 30 phút 06:00–23:00 VN → DM thẻ có nút xoá (chỉ nút mới xoá; mặc định dry-run) |
Chấm công | notify | 0,30 23 * * * mỗi 30 phút, 07–22h VN 23:00 VN hằng ngày |
native |
seed36StoreGapsDaily — 02:35 VN — seed 3.6 Kiểm tra bảng công ngày cho hôm qua (NV Cửa hàng ∩ đang làm 2.3); thay workflow Lark |
Chấm công | seed | 02:30 VN hằng ngày | native |
seed36StoreGapsToday — 15:00 VN — seed 3.6 cho HÔM NAY (workflow Lark đã tắt 11/10); khoá chung + đếm trùng sau khi tạo |
Chấm công | seed | 15:00 VN hằng ngày | native |
syncAttendanceCacheBatch — Quét chấm công tháng hiện tại → D1 employee_attendance_cache |
Chấm công | cache | mỗi 15 phút, 07–19h VN | native |
syncNoAccountTimesheet — Phiếu công NV chưa có tài khoản (Approved, chưa Done) → bảng công chi tiết, 20 phút/lần |
Chấm công | sync | mỗi 20 phút cả ngày | native |
bcltLockBackfillOnce — MỘT LẦN (28/09): bù BC → BCLT cho record BC có event trong ngày bị kẹt Queue — upsert ép ghi theo khoá, không xoá; kết quả KV bclt:backfill:20260928, xong thì tự bỏ qua |
CSKH | reconcile | — | native |
cskhArchiveHourly — Sao lưu BC Base CSKH → bảng LT mỗi giờ |
CSKH | archive | phút 00 mỗi giờ | GAS |
cskhAuditToBase — Mỗi giờ :45 — chép nhật ký sửa ô CSKH (D1 cskh_write_log, con trỏ KV) sang Base "LOG - Nhật ký chỉnh sửa CSKH" |
CSKH | sync | phút 45 mỗi giờ | native |
cskhBcltLockPendingDrain — Chạy tiếp event khoá BC → BCLT dở (hàng chờ D1) — chỉ tạo dòng BCLT thiếu |
CSKH | reconcile | mỗi 5 phút cả ngày | native |
cskhBcltLockReconcile — Khoá dòng BC → BCLT (đối soát định kỳ) |
CSKH | reconcile | phút 00 mỗi giờ | native |
cskhCameraRemindCron — Nhắc hạn CAMERA (1 lần / bản ghi) |
CSKH | notify | mỗi 20 phút cả ngày | native |
cskhHeatmapFreezeD1 — Heatmap CSKH: đóng băng đếm thô ngày D-1 → HM tổng/AM/cửa hàng (00:05 VN) |
CSKH | sync | 00:05 VN hằng ngày | native |
cskhMapsRemindCron — Nhắc hạn MAPS (1 lần / bản ghi) |
CSKH | notify | mỗi 20 phút cả ngày | native |
cskhOpsDayDigests — Digest TRỰC PAGE / MAPS / HAPPY CALL 17:00 |
CSKH | notify | 17:00 VN hằng ngày | native |
cskhPagesRemindCron — Nhắc hạn TRỰC PAGE (1 lần / bản ghi) |
CSKH | notify | mỗi 20 phút cả ngày | native |
cskhSaiSoAmNoteDigest — Digest SAI SỐ cho AM 17:00 |
CSKH | notify | 17:00 VN hằng ngày | native |
cskhSyncBcCameraAllStoreStartOfMonth — BC Camera toàn hệ thống: seed mùng 1 VN (tháng mới) |
CSKH | seed | 02:00 VN hằng ngày | GAS |
cskhSyncBcCameraStaffDaily — BC Camera theo NV: bổ sung NV mới |
CSKH | seed | 02:00 VN hằng ngày | GAS |
cskhSyncBcCameraStaffStartOfMonth — BC Camera theo NV: seed NV cửa hàng (chạy hằng ngày 01:00 VN, create-if-missing) |
CSKH | seed | 01:00 VN hằng ngày | GAS |
cskhSyncBcCdntKtvDaily — BC ĐIỂM CĐNT – KTV: bổ sung NV mới 08:00 VN |
CSKH | seed | 08:00 VN hằng ngày | native |
cskhSyncBcCdntKtvStartOfMonth — BC ĐIỂM CĐNT – KTV: seed đầu tháng từ 0.1 (Vị trí làm việc = Kỹ thuật viên) |
CSKH | seed | 08:00 VN hằng ngày | native |
cskhSyncBcCdntStylistDaily — BC ĐIỂM CĐNT – STYLIST: bổ sung NV mới 08:00 VN |
CSKH | seed | 08:00 VN hằng ngày | native |
cskhSyncBcCdntStylistStartOfMonth — BC ĐIỂM CĐNT – STYLIST: seed đầu tháng từ 0.1 (Vị trí làm việc = Stylist) |
CSKH | seed | 08:00 VN hằng ngày | native |
cskhSyncBcKtvDaily — BC Nhức mắt – KTV: bổ sung hằng ngày |
CSKH | seed | 05:00 VN hằng ngày | GAS |
cskhSyncBcKtvStartOfMonth — BC Nhức mắt – KTV: seed đầu tháng |
CSKH | seed | 02:30 VN hằng ngày | GAS |
cskhSyncBcNhucMatMonthly — Đồng bộ 2.1 Nhức mắt → BC mỗi giờ |
CSKH | sync | phút 00 mỗi giờ 08–22h VN | GAS |
cskhSyncBcSlCuocGoiSaiSoStartOfMonth — SL cuộc gọi – Sai số: seed từng ngày × cửa hàng ngày 1 |
CSKH | seed | 03:00 VN hằng ngày | GAS |
cskhTrucPageLateDigest — TRỰC PAGE lượt hai 23:05 |
CSKH | notify | 23:05 VN hằng ngày | native |
reconcileNhucMatNotify — Gửi bù DM KTV 2.1 Nhức mắt bị sót (24h gần nhất) |
CSKH | reconcile | mỗi 20 phút cả ngày | native |
runCskhPageWriteGuard — Ghi bù giải trình TRỰC PAGE bị mất |
CSKH | reconcile | mỗi 20 phút cả ngày | native |
runCskhWriteReconcile — Ghi bù lượt ghi ô lỗi kỹ thuật (từ cskh_write_log) |
CSKH | reconcile | mỗi 20 phút cả ngày | native |
runLichHenKinhNotify — Lịch hẹn kính trong ngày → AM + KTV + Stylist |
CSKH | notify | mỗi 20 phút cả ngày 09:30 VN hằng ngày |
native |
runLichHenKinhRemind — Nhắc trước giờ hẹn 3 tiếng |
CSKH | notify | mỗi 20 phút cả ngày | native |
refreshRsmDataCache_ — Làm nóng cache RSM (target/daily/am/ssp) — GAS, thôi lên lịch 12/10 (vượt bộ nhớ) |
Doanh thu | cache | — | GAS |
refreshRsmDataNative — 05:05/14:05/18:05 VN — làm mới ảnh chụp D1 doanh thu + mốc đồng bộ (thay refreshRsmDataCache_) |
Doanh thu | cache | 05:05 VN hằng ngày 14:05 VN hằng ngày 18:05 VN hằng ngày |
native |
revArchiveScheduled — Sao lưu BC Doanh thu → bảng LT (05/14/20h) |
Doanh thu | archive | 05:00 VN hằng ngày 14:00 VN hằng ngày 20:00 VN hằng ngày |
GAS |
runNopTienVpRemind — 14:00 VN — DM QLCH bản ghi nộp tiền mặt chưa xác nhận (nút Đã nộp tiền → Trạng thái update) |
Doanh thu | notify | 14:00 VN hằng ngày | native |
runRevenueDailySeed — Tạo khung 2.2 Doanh số ngày theo Danh sách cửa hàng (hiện ghi bảng Test) |
Doanh thu | seed | 01:00 VN hằng ngày | native |
runRevenueDailySync — Báo cáo doanh thu theo cửa hàng → 2.2 Doanh số ngày mỗi 5 phút (hiện ghi bảng Test) |
Doanh thu | sync | mỗi 5 phút cả ngày | native |
runDataReconciliationAts — Base ↔ ONE-ANNA: tuyển dụng |
Đối soát | reconcile | phút 08 mỗi giờ | native |
runDataReconciliationCskhBc — Base ↔ ONE-ANNA: BC CSKH (bảng lớn, cron riêng mỗi giờ) |
Đối soát | reconcile | phút 25 mỗi giờ | native |
runDataReconciliationCskhOps — Base ↔ ONE-ANNA: bảng nghiệp vụ CSKH |
Đối soát | reconcile | phút 35 mỗi giờ | native |
runDataReconciliationHrPayroll — Base ↔ ONE-ANNA: HR/lương |
Đối soát | reconcile | phút 08 mỗi giờ | native |
runDataReconciliationRsm — Base ↔ ONE-ANNA: RSM |
Đối soát | reconcile | phút 52 mỗi giờ | native |
runReconciliationSummary — Báo cáo đối soát hằng ngày 09:00 (đọc D1) |
Đối soát | notify | 09:00 VN hằng ngày | native |
createTestBaseCskhOnce — MỘT LẦN: sao chép cấu trúc Base CSKH (không dữ liệu) làm Base thử nghiệm, tắt automation, cấp quyền Tùng; trạng thái KV test_base:cskh, xong thì tự bỏ qua |
Hệ thống | seed | — | native |
pruneWebhookInbox — Hằng ngày 03:00 VN, xoá theo khúc (D1): webhook_inbox cũ hơn 7 ngày (500 dòng × ≤40), lark_event_dedup cũ hơn 3 ngày (5000 × ≤80), trigger_runs cũ hơn 14 ngày |
Hệ thống | cleanup | 03:00 VN hằng ngày | native |
runDailyCatchUp — Ké cron :10/:30/:50 — job 1 lần/ngày (HRIS, cảnh báo HĐ) có lượt gần nhất hôm nay lỗi → chạy bù tuần tự, tối đa 3 lượt/ngày/job (cron ghi catchup) |
Hệ thống | reconcile | 10-59/20 0-16,22-23 * * * | native |
runJobHealthCheck — Kiểm job lịch lỡ lịch (24h) / lần cuối lỗi theo D1 scheduled_job_locks → DM JOB_ALERT_USER_ID, 1 lần/ngày từ 09:30 VN; im khi ổn |
Hệ thống | notify | 10-59/20 0-16,22-23 * * * | native |
runLoadAlertCheck — Cảnh báo tải Worker mỗi 5 phút (event/phút, vòng lặp tự kích, job bị cắt, cron > 10 phút, KV lỗi, Lark rate-limit, exception) → DM JOB_ALERT_USER_ID, 1 lần/giờ/loại; im khi ổn |
Hệ thống | notify | mỗi 5 phút cả ngày | native |
watchBaseSchema — Phát hiện cột Base bị đổi tên/kiểu |
Hệ thống | reconcile | 02:00 VN hằng ngày | native |
runBirthdayNotify — Sinh nhật Leader (tuần + D-1/D0) |
HR | notify | 09:00 VN hằng ngày | native |
runContractExpiryNotify — Cảnh báo hợp đồng sắp hết hạn |
HR | notify | 08:30 VN hằng ngày | native |
runHrisPersonnelSync — HRIS: bảo đảm 2.3/6.1 + hợp đồng theo trạng thái |
HR | sync | 08:30 VN hằng ngày | native |
runKpiMonthlySeed — Seed KPI 1.3 đầu tháng (chỉ ngày 1 VN) |
KPI | seed | 02:00 VN hằng ngày | native |
meetingLarkReconcile — Mỗi 5 phút: người đặt xoá/từ chối trên Lark Calendar hoặc sự kiện bị xoá → huỷ lịch ở D1 + xoá sự kiện lịch bot (trả phòng); không ghi Base |
Lịch họp | reconcile | mỗi 5 phút cả ngày | native |
backfillMonthlyPayrollSheets — Bổ sung dòng tháng (3.0/3.1/4.0.1/5.2) cho NS mới còn hiệu lực — idempotent, sau runHrisPersonnelSync |
Lương | seed | 08:30 VN hằng ngày | GAS |
checkSnapshotDrift — Phát hiện bảng 3.0 bị sửa sau khi đã chốt snapshot |
Lương | reconcile | 02:00 VN hằng ngày | native |
drainPayrollOutbox — Đẩy các lượt xác nhận phiếu công/lương đang chờ lên Base |
Lương | sync | mỗi 15 phút, 07–19h VN phút 00 mỗi giờ |
native |
healDriftedPayroll31 — Snapshot drift → đồng bộ lại 3.1 (hoặc release khi HR xoá XN); tối đa 20 dòng/lượt, tháng hiện tại + tháng trước |
Lương | sync | 02:00 VN hằng ngày | native |
runVisitorMissReportDigest — Cửa hàng chưa báo cáo lượt khách |
Lượt khách | notify | 09:00 VN hằng ngày | native |
runVisitorSeedGuard — Lưới seed lượt khách: dòng ngày hôm qua+hôm nay, tuần hiện tại (từ T2 07:00), backfill theo khoá KV visitor_seed:backfill |
Lượt khách | seed | 10-59/20 0-16,22-23 * * * | native |
seedVisitorDetailDaily — Seed chi tiết lượt khách hôm qua + hôm nay (gọi tay; cron đi qua runVisitorSeedGuard) |
Lượt khách | seed | — | native |
seedVisitorWeek — Seed báo cáo lượt khách tuần (chỉ Thứ Hai) |
Lượt khách | seed | 06:00 VN hằng ngày | native |
cskhKtvAutoGrantCron — Tự cấp Role KTV cho Mã KTV mới |
Phân quyền | grant | 08:30 VN hằng ngày | GAS |
cskhQlchAutoGrantCron — Tự cấp Role QLCH |
Phân quyền | grant | 08:30 VN hằng ngày | GAS |
reconcileHoanTienNotify — Gửi bù thẻ Hoàn tiền bị sót |
Vận hành | reconcile | mỗi 20 phút cả ngày | native |
replayLostVhImgErr — Mỗi 5 phút: xả event P10 kẹt (lỗi waitUntil cũ) — chỉ phiếu trong ngày hôm nay, qua cổng điểm/ngày/khoá once rồi đẩy MEDIA_Q; event ngày cũ → expired, không gửi |
Vận hành | notify | mỗi 5 phút cả ngày | native |
7.2 Event Base (bản ghi thay đổi → Worker xử lý)¶
| Bảng | Handler | Làm gì |
|---|---|---|
| 2.2 MAPS | handleMapsEvent |
Tick Gửi thông báo → DM; Điểm trừ → TOÀ TUYÊN ÁN |
| 4.1 CAMERA | handleCameraEvent |
Tick Gửi thông báo + stamp khi QLCH Xác nhận |
| 3.1 TRỰC PAGE | handlePagesEvent |
Tick Gửi thông báo → DM AM+QLCH; QLCH Xử lý → stamp + DM |
| 1.3 KHÔNG HÀI LÒNG – HAPPY CALL | handleHappyCallUnhappyEvent |
Dòng mới/sửa đủ điều kiện → thông báo |
| 2.1 XỬ LÝ NHỨC MẮT | handleNhucMatEvent |
Dòng mới → DM KTV + stamp Thời gian gửi thông báo KTV; sửa cột CS → trả lời trong thread |
| 1.5 LỊCH HẸN KÍNH | handleLichHenPhkhEvent |
Tick Gửi thông báo → phiếu; AM ghi chú → cập nhật phiếu |
| 1.2 SAI SỐ | handleSaiSoXuLyEvent |
Tick Chuyển thông tin → DM AM+QLCH; ghi chú → stamp thời gian |
| Vận hành – Phiếu chấm 10 tiêu chí | handleVanHanhImgErrEventSplit |
Điểm KSNB ≠ 100 → DM + Group |
| Vận hành – Hoàn tiền | handleHoanTienEvent |
Approved → thẻ; KT điền → DM người yêu cầu |
| BC ĐIỂM CĐNT | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC ĐIỂM PHỤC VỤ P.TNKH | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC ĐIỂM PHỤC VỤ CỤM | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC ĐIỂM PHỤC VỤ HỆ THỐNG | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC SL CUỘC GỌI – SAI SỐ | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC Hoàn thành target cuộc gọi CSKH | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC ĐIỂM CĐNT – KTV | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
| BC ĐIỂM CĐNT – STYLIST | handleBcltLockEventMany |
Khoá dòng BC → BCLT |
7.3 Webhook HTTP¶
| Đường dẫn | Ai gọi | Làm gì |
|---|---|---|
/cron |
Gọi tay / công cụ | Chạy một cron theo biểu thức |
/webhook |
Lark Event Subscription + thẻ tương tác | Cửa chung cho event Base (xem EVENTS) và card action |
/api/webhook/base-attendance |
Lark Automation | Chấm công từ Base |
/api/webhook/payroll-unlock |
Lark Automation | Mở khoá phiếu lương |
/api/webhook/timesheet-detail |
Lark Automation | Chi tiết bảng công |
/api/webhook/cskh-notify |
Lark Automation | Dispatch thông báo CSKH (song song với event — chỉ bật MỘT đường) |
/api/webhook/van-hanh-img-err |
Lark Automation | Lỗi hình ảnh vận hành |
/api/webhook/hoan-tien |
Lark Automation | Hoàn tiền cho khách |
/api/webhook/dao-tao-hr-enrich |
Lark Automation AddRecord ×5 bảng Đào tạo | employer_id → HRIS 2.1 → Khối phòng ban/Vị trí/Leader (chỉ ô trống) |
/api/run |
Gọi tay / công cụ | Chạy một job theo tên |
8. Deploy¶
Chỉ Tùng deploy, chỉ một đường: npm run deploy. Không chạy wrangler deploy trực tiếp (bị [build] preflight chặn). Mọi người làm trên nhánh feat/lich-hop trong ~/code/"ANNA 2".
Trước khi deploy
1. git pull, commit + push hết (cây sạch).
2. Chạy kiểm tra (/deploy-check: test mức full, xem access_log 15 phút gần nhất).
3. Giờ an toàn: 03:15–05:45 hoặc 23:15–00:15 (VN); tránh cao điểm 09h, 14h, 16h và phút cron chạy.
4. Có migration mới → chạy trước: cd apps/api && npm run d1:migrate:<số>.
Lệnh
cd ~/code/"ANNA 2" && git pull
cd apps/api && npm run deploy:dry # chỉ kiểm, không đẩy
npm run deploy # hoặc: npm run deploy -- --note "lý do"
scripts/deploy.mjs từ chối nếu: cây bẩn · sai nhánh · HEAD chưa push · bản live (/api/version) không phải tổ tiên của HEAD · khoá D1 deploy_lock đang bị giữ (tự hết hạn 20 phút). Qua cổng: đóng gói GAS → build lịch họp → chuẩn bị public → test → build-info → sync → wrangler deploy → chờ /api/version = HEAD → ghi deploy_log (D1) → nhả khoá. Ghi thêm một dòng vào .claude/plans/deploy-log.md.
Sau deploy 30 phút: node tools/regression/run.mjs --live (chỉ đọc); xem trigger_runs, cskh_write_log/rpc_write_log; mở thử mọi module bằng tài khoản thử đủ vai trò (NV, QLCH, AM, HR).
Quay lại: npx wrangler rollback (Tùng) rồi git revert; hành vi sau cờ tính năng → tắt cờ; trigger lỗi → tắt bằng trigger_switches.
9. Điểm cần xác nhận (toàn dự án)¶
- Thời hạn phiên đăng nhập.
- Tài khoản thử theo vai trò (NV, QLCH, AM, HR) có sẵn hay chưa — deploy.md nhắc tới nhưng không ghi tên.
- Bảng
lark_api_usage(migration 008) không có trên D1 live. - Bảng HRIS
2.5và0.0.2 Sơ đồ tổ chứckhông thấy code ONE-ANNA dùng. - KSNB đang dùng dữ liệu mẫu; Chứng từ mới ở giai đoạn 1.
- Module
noti-hoso-lan1..3vàconfig/automations/đang làm dở trên máy Tùng, chưa commit — chưa đưa vào tài liệu. - Ghi doanh số ngày đang vào bảng
2.2 - Doanh số ngày Test.