Skip to content

Email: SDD ​

PRD · Tests · trạng thái: đã xây · chi tiết vận hành ở platform/emails

Luồng ​

domain (user, membership-activation, events, admin, ...)
  -> sendEmail() / fireEmail()                 api.conan.school/src/shared/email/send.ts
       1. kiểm email_preferences nếu là thư gắn kết  (bỏ qua: trả E_UNSUBSCRIBED, KHÔNG ghi sổ)
       2. EMAIL_CATALOG[kind].render(data)       templates.ts, khung layout()
       3. chèn ảnh theo dõi + withUtm()
       4. thư gắn kết: link huỷ + List-Unsubscribe / List-Unsubscribe-Post
       5. env.EMAIL.send(...)                    binding [[send_email]] name="EMAIL" (wrangler.toml)
       6. INSERT email_deliveries                mỗi lượt một dòng, kể cả hỏng
       7. E_RECIPIENT_SUPPRESSED -> ghi email_preferences source='suppressed'
       8. bản sao kiểm tra nếu wantsAuditCopy()

Thành phần ​

Thành phầnFileGhi chú
Cổng gửisrc/shared/email/send.ts: sendEmail, fireEmail, lookupRecipient, unsubscribeToken, withUtm, auditCopyAppliesTosendEmail không ném lỗi, trả SendEmailResult. env.EMAIL.send chỉ được gọi ở file này. fireEmail dùng qua waitUntil.
Người gửiEMAIL_FROM trong templates.tsConan School, [email protected].
Bản sao kiểm traEMAIL_AUDIT_COPY trong templates.tsHiện mode: 'cc', exclude: ['login_code']. auditCopyAppliesTo() loại thêm cả nhóm gắn kết. Hai đường sinh bản sao cùng hỏi wantsAuditCopy(). Chế độ 'cc' không ghi dòng audit_of và chung ảnh theo dõi; chỗ hiện lượt mở ghi nhãn theo số liệu qua operatorOpensInKindStat() / operatorOpensForDelivery() (send.ts); modeSince ghi lúc chế độ hiện tại bắt đầu, thư trước mốc đó sạch.
Khunglayout() trong templates.ts, bảng màu EMAIL_PALETTEHex chép từ theme.css, được scripts/check-token-sync.mjs so từng cặp.
Tra người nhậnlookupRecipient(env, userId)Hỏi cả users lẫn legacy_users.
Biên nhận MasteractivateToMaster() ở src/domains/membership-activation/repository.tsGửi membership_activated cho mọi đường kích hoạt; admin duyệt tay gửi ở src/domains/admin/membership_claims.ts.
Nhắc sự kiệnsrc/shared/email/reminders.ts, cron 7 * * * * trong src/index.tsclaimScheduledRun(env, 'event-reminders:<giờ>') rồi NOT EXISTS trên email_deliveries với audit_of IS NULL.
Thư hằng ngàysrc/shared/email/daily.ts, cron 0 1 * * *Khoá INSERT INTO daily_email_runs(run_date); công tắc platform_settings.daily_email_enabled; trần MAX_PER_RUN = 500; nguồn users status='active'.
Báo cáo vận hànhsrc/shared/email/report.ts, cùng cronclaimScheduledRun theo ngày (ops-daily-report:) và thứ Hai (ops-weekly-report:).
Mã đăng nhậpPOST /api/user/auth/request-code ở src/domains/user/index.ts
Gửi thửPOST /api/system/email/smoke ở src/domains/system/index.tsXem catalog.

Bảng D1 ​

email_deliveries (20260904a, thêm audit_of ở 20260907a), email_opens (20260907a), email_preferences (20260907b, bù suppressed ở 20260909c), daily_email_runs (20260909a). Chi tiết sổ ở delivery-log, tuỳ chọn ở preferences.

Tài liệu nội bộ nền tảng Conan School.