Delivery log: SDD
Bảng
| Bảng | Migration | Cột chính |
|---|---|---|
email_deliveries | 20260904a_email_deliveries.sql, thêm audit_of ở 20260907a_email_opens.sql | id, kind, recipient, subject, user_id, ref_id, status CHECK IN ('sent','failed'), message_id, error_code, error_message, audit_of, created_at. Chỉ mục theo recipient, kind, user_id, audit_of. Không tiền tố legacy_. |
email_opens | 20260907a_email_opens.sql | id, delivery_id, opened_at, user_agent, ip_country, via_proxy CHECK IN (0,1). Một dòng mỗi lượt tải, cố ý không gộp thành cột opened_at. |
daily_email_runs | 20260909a_daily_email_runs.sql | Sổ của vòng gửi hằng ngày: run_date khoá chính, considered, sent, finished_at. |
Đường ghi và đọc
| Việc | File / route |
|---|---|
| Ghi lượt gửi | sendEmail() trong api.conan.school/src/shared/email/send.ts, sau env.EMAIL.send |
| Ảnh theo dõi | GET /api/system/email/o/:file ở src/domains/system/index.ts: trả GIF no-store, chỉ ghi khi delivery_id có trong email_deliveries |
| Tra lượt mở | GET /api/system/email/opens?email=&kind= và GET /api/system/email/opens/:deliveryId, gác bằng x-email-smoke-token |
| Admin | src/domains/admin/emails.ts mount /api/admin/emails: GET /catalog, GET /stats (lọc audit_of IS NULL, mỗi loại mang cờ operator_opens), GET /, POST /test, GET /:id (cờ operator_opens theo lượt gửi qua operatorOpensForDelivery, kèm audit_copy_mode). Cờ của /stats qua operatorOpensInKindStat (loại có bản sao chung thư VÀ có thư được mở). Mọi phản hồi có lượt mở kèm operator_opens_mixed_in, operator_opens_caveat, audit_rows_written |
| Giao diện | admin.conan.school/legacy/admin-trial/src/pages/EmailsPage.tsx, đường /community/email (khai ở admin.conan.school/src/nav.ts) |
| Báo cáo | src/shared/email/report.ts dùng cùng định nghĩa "đã mở" với /stats, và cùng luật cờ: operatorOpensInKindStat theo loại, operatorOpensForDelivery cho top 10; ccInflated tính từ số liệu của kỳ |
Bản sao kiểm tra và sổ gửi
EMAIL_AUDIT_COPY.mode = 'cc' từ 08.09.2026: người vận hành là người nhận CC, chung thư, chung deliveryId, chung ảnh theo dõi. Hệ quả cho sổ: lượt mở của người vận hành ghi vào lượt gửi của người dùng, và cột audit_of không được ghi nữa (cả sổ chỉ có 10 dòng bản sao, 07-08.09.2026). Bộ lọc audit_of IS NULL giữ lại cho chế độ 'separate', nhưng ở chế độ 'cc' nó không loại gì.
Chưa có
- NOTIF-LOG-06: khi người nhận đã huỷ,
sendEmail()trảE_UNSUBSCRIBEDtrước bước ghi sổ, nên lượt bỏ qua chỉ để lại một dòng logemail_skipped_unsubscribedtrên Workers Logs, không có dòng D1 nào. - Sổ cho kênh khác ngoài email (chưa có kênh khác).