UC 8.2.3
Flow 10.1B - AI Plan Dispatch + Calendar Compliance: email Trading Plan + phân tích AI cho Pod Leader; cron hằng ngày kiểm tra lịch họp của leader để ghi strike và đóng Induction_Due
| Field | Value |
|---|---|
| BA in Charge | Anh Hoang |
| Date Created | 2026-10-12 |
| Version | v1.11 |
| Document References | Zapier Integration V7.pdf (§Flow 10.1B) · RFQ_ Stack Trading Prop Tech V7.pdf (§Log Calendar Strike, §Background Mechanisms — Calendar Compliance Auditor, §4.4 #11) · QnA from clients — STAGE 6: Pod System Flow 10 → 11 (POD-DISP-01/02/06/07/08/09/13, POD-SLA-07, POD-PLAN-11, POD-XF-14) · QnA_init_docs.md (A-01…A-18) · Common Rules CR-08, CR-15.2, CR-18 |
UC_8.2.3 — Flow 10.1B: AI Plan Dispatch + Calendar Compliance
🇻🇳 Section này viết bằng tiếng Việt để BA review. Mọi ID, anchor, tên field/API và text hiển thị cho user giữ nguyên tiếng Anh.
1. Overview
| Field | Content |
|---|---|
| ID | UC_8.2.3 |
| Use Case | Flow 10.1B: AI Plan Dispatch + Calendar Compliance |
| Description | UC này giúp Pod Leader làm đúng vai trò mentor, gồm 3 việc: gửi cho leader Trading Plan của mentee mới kèm nhận xét của AI; mỗi ngày kiểm tra lịch họp của leader để phát hiện cuộc họp không mời bot ghi chép, và ghi nhận leader đã hẹn họp với mentee mới; mỗi tuần gửi báo cáo vi phạm cho ban quản lý. |
| Phạm vi | Không gồm bảng SLA_Deadlines và cron nhắc hạn SLA (UC_8.2.4), phần tạo PDF và AI phân tích (UC_8.2.2). |
| Zapier Flow | Flow 10.1B (Trading Plan AI Dispatch) |
| Zapier Table | — |
| API | API Log Calendar Strike (POST /api/community/calendar-strike) |
| Cron Job task | Calendar Compliance Auditor, chạy hằng ngày lúc 01:00 UTC · Tác vụ gửi báo cáo tuần, chạy Thứ Sáu lúc 5:00 PM giờ US/Central |
| 3rd Party | AWS SES, Google Workspace Calendar API, Fireflies (notetaker), Discord, Slack |
2. Trigger
- Zapier nhận webhook
TRADING_PLAN_ANALYZEDtừ Middleware. Zapier gửi email cho Pod Leader (§5.1). - Cron Job task
Calendar Compliance Auditorchạy hằng ngày lúc 01:00 UTC trên Middleware (§5.2). - Tác vụ gửi báo cáo tuần chạy Thứ Sáu lúc 5:00 PM giờ US/Central trên Middleware (§5.5).
3. Pre-conditions
- Pod Leader có tài khoản Google Workspace
@stacktrading.com(BR_8.2.3.1). - Stack Trading đã cấp cho Sotatek một Service Account có quyền Domain-Wide Delegation. Service Account là tài khoản dành cho phần mềm, không phải cho người. Domain-Wide Delegation là quyền cho phép tài khoản này đọc lịch của mọi tài khoản trong Google Workspace của Stack Trading mà không cần từng người đăng nhập.
4. Post-conditions
- Pod Leader đã nhận email Trading Plan của mentee.
- Sau mỗi lần cron chạy, mọi cuộc họp nhiều người không mời notetaker và diễn ra trong 24 giờ trước lần chạy đó đều đã bị ghi strike.
- Leader nào đã liên kết Discord thì nhận 1 tin nhắn riêng (DM) cho mỗi strike.
- Mọi hạn
Induction_Dueđã có cuộc họp hợp lệ trên lịch leader đều đã được đóng. - Thứ Sáu hằng tuần, kênh Slack
#ops-riskđã nhận báo cáo strike của tuần.
5. Basic Flow
5.1 Email cho Pod Leader (Flow 10.1B)
Stage 1 — Nhận webhook (Trigger, Action 1)
-
Sau khi AI phân tích xong Trading Plan,
API Analyze Trading Plan(UC_8.2.2) gửi webhookTRADING_PLAN_ANALYZEDvào Catch URL của Zap Flow 10.1B. Catch URL là địa chỉ Zapier cấp để nhận webhook. Thời điểm gửi và payload đầy đủ xem UC_8.2.2 BR_8.2.2.6.Input field Value mentor_emailEmail @stacktrading.comcủa leader (BR_8.2.3.1)pdf_urlLink PDF Trading Plan. Mở không cần đăng nhập, link không hết hạn (Ref: UC_8.2.2 BR_8.2.2.2) ai_analysisNhận xét của AI, dạng văn bản thường -
Mỗi webhook nhận được làm Zap chạy 1 lần và gửi 1 email. Webhook trùng xem E_8.2.3.1.
-
Zapier đọc 3 field
mentor_email,pdf_urlvàai_analysistừ payload. Nếuai_analysisrỗng hoặc lạc đề thì xem E_8.2.3.2.
Stage 2 — Gửi email (Action 2)
- Zapier tải file PDF từ
pdf_url. PDF luôn nhỏ hơn 25MB nên luôn đính kèm được vào email. - Zapier gửi email qua AWS SES tới
mentor_email, chỉ gửi vào địa chỉ@stacktrading.com(BR_8.2.3.1). Nội dung email xem BR_8.2.3.4. Email gồm:- File PDF Trading Plan được đính kèm. Thân email cũng ghi link
pdf_url. - Nhận xét của AI. Chỉ leader nhận phần này (BR_8.2.3.3).
- Lời nhắc leader có 5 ngày để đặt lịch Induction Sync. Induction Sync là buổi họp 1-1 đầu tiên giữa leader và mentee mới. Hạn này gọi là
Induction_Due, tính từ lúc mentee nộp Trading Plan. VD: mentee nộp plan lúc 10:00 ngày 1 thì leader phải đặt lịch trước 10:00 ngày 6. - Master Calendar link của leader. Đây là link đặt lịch cố định của từng leader, giống Google Appointment Schedule.
- File PDF Trading Plan được đính kèm. Thân email cũng ghi link
- Mẫu email có 3 biến, giá trị lấy từ payload webhook do Middleware gửi kèm:
[Leader_Name]: tên Pod Leader, dùng trong lời chào.[Mentee_Name]: tên mentee, dùng ở tiêu đề và thân email.[calendar_link]: Master Calendar link của leader. BE gọi API để tạo hoặc lấy link này ngay lúc gửi webhook, hệ thống không lưu sẵn link.
- Nếu một bước của Zap vẫn lỗi sau khi Zapier đã tự chạy lại thì xem E_8.2.3.3.
Stage 3 — Leader đặt lịch Induction Sync
- Leader bấm Master Calendar link, tự chọn ngày giờ và xác nhận. Hệ thống không tự tạo cuộc họp. Google tạo cuộc họp trên lịch
@stacktrading.comcủa leader và mời 2 khách:- Email đăng ký của mentee.
notetaker@stacktrading.com. Đây là bot Fireflies, tự ghi âm và ghi chép cuộc họp để phục vụ tuân thủ. Master Calendar link điền sẵn notetaker vào danh sách khách mời.
- Leader được tự chọn giờ và đổi giờ, miễn là đặt lịch trong hạn
Induction_Due. Không bắt buộc số mentee mỗi buổi, thường là họp 1-1. - Buổi họp không cần diễn ra trong 5 ngày, chỉ cần được đặt lịch trong 5 ngày. VD: hạn
Induction_Duelà ngày 6. Leader đặt lịch vào ngày 5 cho buổi họp ngày 10 thì vẫn đạt.
5.2 Calendar Compliance Auditor — đọc lịch leader
Stage 4 — Lấy danh sách leader
- Cron Job task
Calendar Compliance Auditorchạy trên Middleware mỗi ngày 1 lần lúc 01:00 UTC. Mỗi lần chạy, cron đọc lịch leader rồi làm 2 việc: Task 1 ghi strike (§5.3) và Task 2 đóngInduction_Due(§5.4). Hai task chạy độc lập, lỗi ở task này không chặn task kia. - Cron đăng nhập bằng Service Account, dùng JSON key (file khoá) do Stack Trading cấp, rồi lấy danh sách tài khoản trong OU "Pod Leaders". OU (Organizational Unit) là một nhóm tài khoản trên Google Workspace; nhóm "Pod Leaders" gồm các tài khoản
@stacktrading.comcủa Pod Leader, do Stack Trading Ops quản lý. Nếu lỗi đăng nhập hoặc không đọc được danh sách thì xem E_8.2.3.4. - Cron đối chiếu từng tài khoản với
Leader_IDtrongPod_Leader_Registry, bằng email công việc@stacktrading.comcủa leader. Cron chỉ kiểm tra leader cóStatuslàActive. Tài khoản không khớp leader nào, hoặc leader đang nghỉ phép, xem E_8.2.3.5, E_8.2.3.6. Leader không có mentee thì không có cuộc họp nhiều người, nên tự nhiên không bị strike; cron không có bộ lọc riêng cho trường hợp này.
Stage 5 — Đọc sự kiện trên lịch
- Với từng leader, cron đọc mọi sự kiện trên lịch chính của leader, không chỉ cuộc họp tạo từ Master Calendar link. VD: buổi họp thứ 2, thứ 3 hoặc họp đột xuất đều được đọc. Cron chỉ đọc lịch của leader, không đọc lịch của mentee. Với mỗi sự kiện, Google trả về ID sự kiện, trạng thái, thời điểm bắt đầu, tên sự kiện và danh sách khách mời.
- Cron chọn sự kiện theo thời điểm bắt đầu, mỗi task xem một khoảng khác nhau:
- Task 1 chỉ xem các cuộc họp đã diễn ra hôm qua. VD: cron chạy lúc 01:00 ngày 15 thì xem các cuộc họp từ 01:00 ngày 14 đến 01:00 ngày 15.
- Task 2 xem các cuộc họp từ hôm qua đến 7 ngày tới. VD: cron chạy lúc 01:00 ngày 15 thì xem các cuộc họp từ 01:00 ngày 14 đến 01:00 ngày 22. Cuộc họp xa hơn 7 ngày thì chờ tới khi nằm trong khoảng này. VD: ngày 15 leader đặt lịch họp lúc 10:00 ngày 30; lần chạy 01:00 ngày 24 là lần đầu cron thấy cuộc họp này.
- Cron luôn bỏ qua sự kiện đã huỷ (
status = cancelled). Sự kiện lặp lại, VD họp mỗi thứ Hai, thì mỗi lần diễn ra là 1 sự kiện riêng có ID riêng. Khi so khớp email, cron không phân biệt chữ hoa và chữ thường; VDNotetaker@StackTrading.comvẫn khớp vớinotetaker@stacktrading.com. - Nếu Google báo lỗi, hoặc không đọc được lịch của một leader, thì xem E_8.2.3.7, E_8.2.3.8.
5.3 Task 1 — Ghi strike khi thiếu notetaker
Strike là một lần vi phạm được ghi lại khi leader tổ chức cuộc họp nhiều người mà không mời notetaker. Mục đích là chặn trường hợp leader xoá notetaker khỏi danh sách khách mời, hoặc tự tạo cuộc họp khác để tránh bị ghi âm.
Stage 6 — Tìm cuộc họp vi phạm
- Cron xác định sự kiện có phải cuộc họp nhiều người không. Cuộc họp nhiều người là sự kiện có từ 2 người thật trở lên. Người thật gồm người tổ chức (leader) và các khách mời, kể cả khách đã từ chối lời mời. Cron không tính
notetaker@stacktrading.comvà các tài nguyên như phòng họp, thiết bị. VD: leader mời 1 mentee và notetaker thì có 2 người thật là leader và mentee, nên đây là cuộc họp nhiều người. Sự kiện dưới 2 người thật xem E_8.2.3.9. - Nếu cuộc họp nhiều người chưa có trong nhật ký cuộc họp thì cron ghi 1 dòng gồm ID sự kiện,
Leader_ID, thời điểm bắt đầu và thời điểm cron ghi nhận. Báo cáo tuần dùng nhật ký này để đếm tổng số cuộc họp. - Cron kiểm tra danh sách khách mời:
- Có
notetaker@stacktrading.com: cuộc họp đạt yêu cầu, bất kể khách mời khác là ai. Cron không gọi API. - Không có notetaker và sự kiện chưa bị strike: cuộc họp vi phạm. Cron gọi
API Log Calendar Strikeở bước 22. - Cuộc họp vẫn vi phạm khi người còn lại là email cá nhân của chính leader. VD: leader dùng lịch
@stacktrading.commời Gmail cá nhân của mình và không mời notetaker thì vẫn bị strike.
- Có
- Mỗi cuộc họp chỉ được xét strike 1 lần, kể cả khi cron chạy 2 lần trong ngày hoặc chạy lại sau sự cố (BR_8.2.3.5). VD: cuộc họp vi phạm lúc 10:00 ngày 14 chỉ được xét ở lần chạy 01:00 ngày 15.
Stage 7 — Ghi strike qua API
-
Cron gọi
API Log Calendar Strike(POST /api/community/calendar-strike). Đây là endpoint nội bộ của Middleware, chỉ cron được gọi, không mở cho Zapier hay hệ thống bên ngoài.Input field Value pod_idTheo RFQ_ Stack Trading Prop Tech V7.pdf. Chưa chốt pod_idcó phải chính làLeader_IDkhông (§8 #2)leader_idLeader_IDtrongPod_Leader_RegistryID sự kiện của Google Dùng để chống ghi strike trùng (BR_8.2.3.5) Thời điểm bắt đầu sự kiện ( Event Timestamp)ISO 8601 theo giờ UTC (CR-08). VD 2026-10-14T15:00:00.000ZTên sự kiện ( Event Title)Không bắt buộc. Sự kiện không có tên thì để trống Email người tham dự Email của mọi người tham dự đọc được trên sự kiện, gồm người tổ chức và các khách mời RFQ V7 chỉ ghi
pod_idvàleader_id. Endpoint nhận thêm 4 thông tin còn lại vì strike phải lưu các giá trị này và DM gửi leader phải hiển thị chúng. Tên trường và định dạng chi tiết do BE chốt trong OpenAPI spec. -
Middleware kiểm tra lời gọi. Input sai, leader không tồn tại, strike đã có hoặc lỗi hệ thống thì xem E_8.2.3.10 đến E_8.2.3.13.
-
Middleware ghi 1 dòng vào nhật ký strike (BR_8.2.3.2).
-
Middleware trả
200 OKcho cron, kèm kết quả xử lý (đã ghi strike, hoặc đã bỏ qua) và mã bản ghi strike (UUID; để trống khi bỏ qua).
Stage 8 — Báo cho leader qua Discord
-
Khi Middleware đã ghi strike, bot Discord nhắn riêng (DM) cho leader dựa trên
discord_user_idcủa leader. Nội dung tin xem BR_8.2.3.4. Cách điền biến:[Attendee_Emails]: email người tham dự, cách nhau bằng dấu phẩy. VDa@gmail.com, b@stacktrading.com.[Event_Timestamp]: thời điểm bắt đầu sự kiện, ISO 8601 theo giờ UTC (CR-08).
Leader chưa liên kết Discord hoặc gửi DM lỗi thì xem E_8.2.3.14.
5.4 Task 2 — Đóng Induction_Due
Task 2 không có trong RFQ V7, khách bổ sung qua QnA.
Stage 9 — Tìm cuộc họp induction
- Cron chỉ xét những mentee còn hạn
Induction_Dueđang mở trongSLA_Deadlines. Cron xét mọi sự kiện trong khoảng xét của Task 2 (bước 15), không cần là cuộc họp nhiều người. - Nếu sự kiện mời cả
notetaker@stacktrading.comvà email đăng ký của mentee (lấy trongUsers) thì cron đóngInduction_Duecủa mentee đó. Cách lưu trạng thái đóng xem UC_8.2.4 BR_8.2.4.1. Hạn đã đóng thì các lần chạy sau không quét lại cho mentee đó. - Một sự kiện có thể đóng hạn của nhiều mentee. VD: leader mời 2 mentee mới và notetaker vào cùng 1 buổi họp thì hạn của cả 2 mentee đều được đóng. Cron không lọc theo pod, tức là không kiểm tra người sở hữu lịch có phải leader của mentee hay không.
- Sự kiện được tạo trước khi mở
Induction_Duevẫn được tính, miễn là tạo từ ngày mentee vào pod (pod_join_date) trở đi. VD: mentee vào pod ngày 1, leader đặt lịch ngày 2, mentee nộp plan ngày 3. Sự kiện tạo ngày 2 vẫn đóng đượcInduction_Due. - Cron chạy mỗi ngày 1 lần, nên leader đặt lịch sau lần chạy 01:00 UTC chỉ được ghi nhận ở lần chạy hôm sau, xem E_8.2.3.17. Lỗi database và sự kiện bị huỷ xem E_8.2.3.15, E_8.2.3.16.
5.5 Báo cáo tuần trên Slack
Báo cáo do một tác vụ hằng tuần riêng trên Middleware gửi, không do API Log Calendar Strike gửi. API Log Calendar Strike chỉ ghi strike; báo cáo đếm trực tiếp từ nhật ký strike.
Stage 10 — Gửi báo cáo
- Tác vụ chạy Thứ Sáu lúc 5:00 PM theo giờ US/Central.
- Middleware kiểm tra nhật ký gửi báo cáo. Nếu tuần này đã gửi thì không gửi lại (BR_8.2.3.5).
- Middleware tính cửa sổ tuần: từ Thứ Sáu 5:00 PM tuần trước đến Thứ Sáu 5:00 PM tuần này, theo giờ US/Central. Middleware không tính cứng 168 giờ, vì tuần có đổi giờ mùa hè hoặc mùa đông sẽ dài 167 hoặc 169 giờ. VD: tuần chuyển sang giờ mùa hè (tháng 3) mất 1 giờ, nên cửa sổ tuần đó dài 167 giờ. Dữ liệu vẫn lưu theo giờ UTC (CR-08).
- Middleware đọc nhật ký cuộc họp nhiều người, nhật ký strike và
Pod_Leader_Registry(để lấyLeader_Name):- Cuộc họp và strike được tính theo thời điểm diễn ra cuộc họp, không theo thời điểm cron phát hiện. VD: leader đặt lịch ở Tuần 1 cho cuộc họp Thứ Tư Tuần 2 thì cuộc họp được tính vào báo cáo Tuần 2.
- Cuộc họp sát cuối cửa sổ có thể chưa được cron xét lúc gửi báo cáo, nên được tính vào tuần sau. VD: cuộc họp lúc 3:00 PM Thứ Sáu giờ US/Central; cron chạy lúc 01:00 UTC thứ Bảy, sau 5:00 PM Thứ Sáu giờ US/Central, nên cuộc họp này vào báo cáo tuần sau.
- Mỗi cuộc họp và mỗi strike chỉ thuộc 1 báo cáo.
- Lỗi database khi đếm xem E_8.2.3.18.
- Báo cáo gồm 3 nội dung: tổng số cuộc họp nhiều người toàn firm, tổng số vi phạm thiếu notetaker, và danh sách Pod Leader bị strike (mỗi leader 1 dòng gồm
Leader_NamevàLeader_ID). - Middleware gửi 1 tin vào kênh
#ops-riskcho ban quản lý. Nội dung tin xem BR_8.2.3.4. Prod dùng kênh#ops-risk(C0BREC78LGH), Test dùng kênh#test-ops-risk(C0BRAMTDYMQ) (Ref: CR-15.2). Leader không nhận báo cáo này. Tuần không có strike vẫn gửi, ghi 0 vi phạm. - Gửi thành công thì Middleware ghi vào nhật ký gửi báo cáo: mốc đầu cửa sổ, mốc cuối cửa sổ và thời điểm gửi. Slack lỗi xem E_8.2.3.19, E_8.2.3.20.
6. Exceptional Flows
| Exception ID | Exception | Condition | System Handling / Fallback |
|---|---|---|---|
| E_8.2.3.1 | Zapier nhận webhook trùng | Zapier nhận 2 webhook giống nhau cho cùng 1 mentee. | Zap không tự lọc trùng, nên leader nhận 2 email. Bình thường mỗi leader chỉ nhận 1 email cho mỗi mentee, vì mentee chỉ nộp Trading Plan 1 lần (Ref: UC_8.2.2 BR_8.2.2.4). Khi mentee đổi sang pod mới, leader mới cũng nhận email này kèm PDF mentee đã nộp trước đó (Ref: UC_8.2.1 §5.4). Không có mẫu email riêng cho "Updated Trading Plan". |
| E_8.2.3.2 | ai_analysis rỗng hoặc lạc đề | AI trả về nội dung rỗng hoặc không liên quan tới plan. | Zapier đưa câu thay thế AI analysis unavailable. Please review the attached plan directly. vào email (Ref: UC_8.2.2 BR_8.2.2.3). |
| E_8.2.3.3 | Zap lỗi | Một bước của Zap vẫn lỗi sau khi Zapier đã tự chạy lại. VD: AWS SES từ chối email, hoặc Zapier không tải được PDF. | Zapier gửi thông báo lỗi mặc định "Zap Error" (ghi tên Zap và tên bước lỗi) vào kênh Slack Operations. Tính năng tự chạy lại có sẵn trong gói Zapier Company; Sotatek chỉ cấu hình nơi nhận thông báo, không dựng cơ chế xử lý lỗi riêng. Hạn Induction_Due vẫn tính bình thường. |
| E_8.2.3.4 | Không đăng nhập được hoặc không đọc được OU | Service Account hoặc JSON key sai, hết hạn hoặc bị thu hồi quyền Domain-Wide Delegation; hoặc không đọc được danh sách OU. | Cron dừng cả lần chạy: không ghi strike và không đóng Induction_Due cho leader nào, ghi log lỗi. Có báo Slack không và báo vào kênh nào hiện chưa chốt (§8 #1). |
| E_8.2.3.5 | Tài khoản không khớp leader đang hoạt động | Tài khoản trong OU không khớp leader nào, hoặc leader có Status khác Active, VD đã nghỉ việc hoặc bị terminate. | Cron bỏ qua tài khoản đó và ghi log. |
| E_8.2.3.6 | Leader đang nghỉ DTO hoặc Hiatus | Tài khoản leader đang ở trạng thái Locked (Flow 13). | Cron bỏ qua leader đó trong lần chạy: không xét strike, không gửi DM, vì leader đang nghỉ thì không tổ chức buổi mentorship. Cột nào trong database cho biết tài khoản đang Locked do BE xác định. |
| E_8.2.3.7 | Google báo lỗi khi đọc lịch | Google báo vượt giới hạn số lần gọi hoặc lỗi máy chủ (429 hoặc 5xx). | Cron thử gọi lại nhiều lần ngay trong lần chạy, lần sau chờ lâu hơn lần trước. Vẫn lỗi thì bỏ qua leader đó và ghi log. Lần chạy sau không đọc bù. VD: lần chạy 01:00 ngày 15 không đọc được lịch của leader A, thì các cuộc họp của A từ 01:00 ngày 14 đến 01:00 ngày 15 không bao giờ được xét strike. Cron lỡ cả một lần chạy thì cũng vậy cho mọi leader. |
| E_8.2.3.8 | Không đọc được lịch của 1 leader | Tài khoản leader bị khoá, bị xoá hoặc không có lịch. | Cron bỏ qua leader đó, ghi log và tiếp tục với leader khác. |
| E_8.2.3.9 | Sự kiện dưới 2 người thật | VD leader tự tạo sự kiện để khoá giờ làm việc. | Cron bỏ qua sự kiện ở Task 1. |
| E_8.2.3.10 | Input API không hợp lệ | Gọi API Log Calendar Strike thiếu pod_id, leader_id, ID sự kiện, thời điểm sự kiện hoặc email người tham dự; hoặc thời điểm sự kiện sai định dạng. | Middleware trả 400 và không ghi gì vào database. |
| E_8.2.3.11 | Leader không tồn tại (Ref: CR-18) | leader_id không có trong Pod_Leader_Registry. | Middleware trả 200 OK và bỏ qua, không ghi gì. Cron không bị báo lỗi. |
| E_8.2.3.12 | Strike đã có cho sự kiện này (Ref: BR_8.2.3.5) | Cron gọi lại với cùng ID sự kiện, hoặc 2 lời gọi cùng ID sự kiện đến cùng lúc. | Middleware trả 200 OK và bỏ qua: không ghi strike thứ hai, không gửi DM thứ hai. Cron không bị báo lỗi. |
| E_8.2.3.13 | Lỗi hệ thống khi ghi strike | Lỗi database hoặc hết thời gian chờ; hoặc cron không nhận được phản hồi. | Middleware trả 500, không ghi strike, không gửi DM. Cron ghi log và chưa coi sự kiện là đã bị strike. Lần chạy sau không xét lại, vì sự kiện đã nằm ngoài khoảng của Task 1. VD: lần chạy 01:00 ngày 15 gọi API lỗi cho cuộc họp lúc 10:00 ngày 14; lần chạy 01:00 ngày 16 chỉ xét từ 01:00 ngày 15, nên cuộc họp này không bị strike. |
| E_8.2.3.14 | Không gửi được DM | Leader chưa liên kết Discord (discord_user_id rỗng), hoặc gửi DM lỗi: Discord lỗi, leader chặn DM, không tìm thấy người nhận. | Middleware ghi log cảnh báo, không thử gửi lại và không gửi email thay thế. Strike vẫn giữ nguyên và vẫn được tính vào báo cáo tuần (BR_8.2.3.2). |
| E_8.2.3.15 | Lỗi database khi đóng Induction_Due | Cron không ghi được trạng thái đóng. | Cron bỏ qua và ghi log. Lần chạy sau, nếu sự kiện vẫn nằm trong khoảng xét của Task 2 thì được xét lại. |
| E_8.2.3.16 | Cuộc họp bị huỷ sau khi đã đóng hạn | Sự kiện bị huỷ sau khi Induction_Due đã được đóng. | Cron không mở lại Induction_Due. |
| E_8.2.3.17 | Leader đặt lịch sau giờ cron chạy | Leader đặt lịch sau lần chạy 01:00 UTC. | Hạn chỉ được đóng ở lần chạy hôm sau. VD: leader đặt lịch lúc 09:00 UTC ngày 15 thì lần chạy 01:00 UTC ngày 16 mới đóng Induction_Due. Trong lúc chờ, leader có thể vẫn nhận email nhắc hạn hoặc email trễ hạn của UC_8.2.4. Day 1 chấp nhận độ trễ này, không thêm cron và không dùng webhook lịch thời gian thực. |
| E_8.2.3.18 | Lỗi database khi đếm báo cáo | Middleware không đếm được số liệu. | Middleware không gửi báo cáo thiếu số liệu và ghi log. Khi chạy lại, kể cả chạy trễ sau sự cố, Middleware vẫn dùng đúng cửa sổ của tuần bị lỡ, không gộp sang tuần sau. |
| E_8.2.3.19 | Slack báo lỗi khi gửi báo cáo | Slack báo vượt giới hạn số lần gọi hoặc lỗi máy chủ (429 hoặc 5xx). | Middleware thử gửi lại nhiều lần, lần sau chờ lâu hơn lần trước. Vẫn lỗi thì ghi log và chưa ghi nhật ký gửi báo cáo, để lần chạy lại biết tuần này chưa gửi. |
| E_8.2.3.20 | Kênh Slack không dùng được | Kênh không tồn tại hoặc bot không có quyền gửi vào kênh. | Middleware không thử lại và ghi log lỗi. |
7. Business Rules
| BR_ID | Rule Description |
|---|---|
| BR_8.2.3.1 | Email gửi Pod Leader: Mọi Pod Leader đang Active đều được cấp tài khoản Google Workspace @stacktrading.com khi lên làm leader, không riêng Founding Mentor.Mọi email gửi leader trong Pod System chỉ gửi vào địa chỉ @stacktrading.com, không bao giờ gửi vào email cá nhân. Áp dụng cho email Trading Plan (UC này), email SLA (UC_8.2.4, kể cả email leader chỉ được CC) và Wednesday Brief (UC_8.2.5).Tài khoản Discord của leader vẫn gắn với email cá nhân. |
| BR_8.2.3.2 | Ghi strike: Mỗi strike là 1 dòng trong nhật ký strike (PostgreSQL), gồm mã bản ghi strike, leader_id, pod_id, ID sự kiện, thời điểm sự kiện, tên sự kiện, email người tham dự và thời điểm ghi. 4 thông tin bắt buộc phải lưu là Leader ID, Event Timestamp, Event Title và email người tham dự.Strike được ghi im lặng, tức là hệ thống không báo cho ai ngoài leader.Strike được tính vào báo cáo tuần, kể cả khi DM không gửi được.Strike không gây hậu quả tự động: hệ thống không tự xử lý gì dựa trên số strike, số strike không reset theo kỳ, và không có kênh để leader kháng nghị strike. |
| BR_8.2.3.3 | Người nhận nhận xét AI: Phần nhận xét AI là tài liệu coaching riêng cho leader. Mentee không bao giờ nhận phần này. |
| BR_8.2.3.4 | Nội dung tin nhắn: xem chi tiết tại §7.1. |
| BR_8.2.3.5 | Chống ghi trùng: - Phía cron: cron chạy 2 lần trong ngày hoặc chạy lại sau sự cố thì không tạo strike thứ hai, không gửi DM thứ hai và không đếm cuộc họp hai lần. Trước khi ghi, cron kiểm tra ID sự kiện của Google trong nhật ký strike và nhật ký cuộc họp. Task 1 chỉ xét cuộc họp đã diễn ra trong 24 giờ trước lần chạy, nên sự kiện vi phạm còn trên lịch cũng không bị strike lại ở các ngày sau.- Phía API: nhật ký strike có ràng buộc mỗi ID sự kiện chỉ có tối đa 1 dòng. Nhờ vậy 2 lời gọi cùng ID sự kiện đến cùng lúc chỉ tạo 1 strike (E_8.2.3.12).- Báo cáo tuần: mỗi cửa sổ tuần chỉ gửi 1 lần, kiểm tra bằng nhật ký gửi báo cáo (bước 33). |
7.1 BR_8.2.3.4 — Nội dung tin nhắn
Giữ nguyên văn tiếng Anh do khách cung cấp.
Email gửi Pod Leader (Zapier gửi qua AWS SES, bước 5)
Subject: Action Required: New Mentee Trading Plan & Induction - [Mentee_Name] Hello [Leader_Name], A new mentee, [Mentee_Name], has been assigned to your Pod and has successfully submitted their mandatory Trading Plan. Please find their original Trading Plan attached as a PDF (Link: [pdf_url]). Our AI coach has performed an initial structural review of their plan to assist your evaluation: [ai_analysis] Action Required: You have 5 days to complete the initial 1-on-1 induction sync with [Mentee_Name]. Please use your Master Scheduling Link below to book this meeting. The compliance notetaker bot will be automatically invited. Schedule Induction Sync: [calendar_link] Regards, Stack Trading Operations
Chỉ dùng 1 mẫu email này. Không có mẫu "Updated Trading Plan" riêng.
Discord DM khi bị strike (bước 26)
Compliance Notice: Calendar Strike Logged Our system detected a multi-party calendar event that did not include the mandatory compliance notetaker bot. This incident has been logged as a strike on your leader profile. Leader ID: [Leader_ID] Event Title: [Event_Title] Event Timestamp: [Event_Timestamp] Attendees Present: [Attendee_Emails] As a reminder, notetaker@stacktrading.com must be included on the guest list for all mentorship syncs.
Báo cáo tuần trên Slack #ops-risk (bước 37)
Weekly Risk Ops Metrics Report 📊
- Meeting & Violation Metrics: • Total Multi-Party Meetings: [Insert Total Meetings] • Total Missing Notetaker Violations: [Insert Total Violations]
- Strike List (Pod Leaders): (Note: Pod Leaders listed below have received a strike for missing notetakers) • [Leader_Name_1] | ID: [Leader_ID_1] • [Leader_Name_2] | ID: [Leader_ID_2] • [Leader_Name_3] | ID: [Leader_ID_3]
Strike List có 1 dòng cho mỗi Pod Leader bị strike trong tuần, chỉ gồm Leader_Name và Leader_ID, không có email hay Discord ID. VD: tuần này có 2 leader bị strike thì Strike List có 2 dòng.
8. Open Items
Chi tiết: QnA_init_docs.md.
| # | Câu hỏi | ID |
|---|---|---|
| 1 | Cron Auditor lỗi toàn bộ (key Google sai hoặc bị thu hồi) có báo Slack không, kênh nào? | A-17 |
| 2 | pod_id có phải chính là Leader_ID không? | UC_8.2.1 A-11 |
| 3 | Cron xác định đúng mentee thế nào để đóng Induction_Due: link đặt lịch có điền sẵn email mentee không, khớp bằng email nào, leader có nhiều hạn mở mà chỉ tạo 1 cuộc họp thì đóng hạn nào? | A-20 |
9. Phân chia trách nhiệm
| Hạng mục | Sotatek build | Stack Trading Ops | Bên thứ 3 tự chạy |
|---|---|---|---|
| Zap Flow 10.1B và template email leader | ✅ Map biến | ✅ Copy (đã gửi) | AWS SES |
| Master Calendar link của từng leader | ✅ BE gọi API tạo hoặc lấy link | — | Google Calendar |
Tài khoản notetaker@stacktrading.com (Fireflies) | — | ✅ Adam Culver tạo và cấu hình | Fireflies |
| Service Account Domain-Wide Delegation và JSON key | — | ✅ Adam Culver cấp | Google Workspace |
Cron Job task Calendar Compliance Auditor, API Log Calendar Strike, DM Discord, báo cáo tuần | ✅ | ✅ Copy DM, báo cáo tuần (đã gửi) | — |
| Ghi âm, ghi chép cuộc họp; lưu transcript trong workspace Fireflies của Stack Trading | — | — | Fireflies |
Changelog
| Date | Version | Updated item | Before | After | Notes |
|---|---|---|---|---|---|
| 2026-10-12 | v1 | Initial document | — | — | Bản tiếng Việt để BA re-check trước khi chuyển tiếng Anh. Nguồn chính: QnA POD-DISP-01…13, POD-SLA-05/07, POD-PLAN-04. Spec V7 bị QnA thay thế: calendar link là link đặt lịch tĩnh, leader tự đặt (POD-DISP-02); Auditor có thêm nhiệm vụ đóng Induction_Due (POD-DISP-13). Kênh #risk-ops khách ghi → #ops-risk theo CR-15.2. |
| 2026-10-12 | v1.1 | Thêm mục API & Cron | Zap, cron và endpoint chỉ được nhắc 1 dòng trong BR_8.2.3.5 | Mục API & Cron: spec Zap Flow 10.1B, cron Calendar Compliance Auditor, POST /api/community/calendar-strike, cron báo cáo tuần (input, output, xử lý, lỗi, chạy lại / gọi trùng). Basic Flow trỏ tới từng API; BR_8.2.3.5 rút các dòng API. Thêm Hạng mục mở #14–#21 | BA định nghĩa theo RFQ_ Stack Trading Prop Tech V7.pdf §4.4 #11, #19: mã lỗi 400/401/500; status Logged / Skipped, strike_id; input event_id, event_timestamp, event_title, attendee_emails thêm vào calendar-strike (V7 chỉ có pod_id, leader_id) để đủ trường log POD-DISP-06 và DM T-13; chống trùng theo ID sự kiện Google; nhật ký cuộc họp nhiều người và nhật ký gửi báo cáo; báo cáo tuần là cron riêng; thử lại khi Google / Slack lỗi 429 / 5xx. DM Discord lỗi 429 / 5xx theo FR-42 |
| 2026-10-12 | v1.2 | Basic Flow — mô tả lời gọi API | Bước gọi API chỉ gắn "(Ref: API_x)", không rõ bên gọi / bên nhận / kết quả; cron báo cáo tuần chưa có tên | Mỗi bước gọi giữa các hệ thống ghi dạng [Bên gọi → Bên nhận] tên API + input chính → kết quả: Middleware → Zapier (TRADING_PLAN_ANALYZED), Zapier → AWS SES, Cron → Google Calendar API, Cron → Middleware (calendar-strike), Middleware → Bot Discord, Cron → Slack. Mở mỗi stage cron bằng tên + lịch chạy; rẽ nhánh theo kết quả calendar-strike (Logged / Skipped / 500), lỗi đọc lịch Google, lỗi gửi Slack. Đặt tên cron báo cáo tuần Weekly Strike Report, dùng thống nhất ở Trigger, BR_8.2.3.5 và mục API & Cron | — |
| 2026-10-13 | v1.3 | Tên báo cáo tuần | Weekly Calendar Strike Report (tên tự đặt) | Weekly Strike Report — tên theo QnA POD-DISP-09 | — |
| 2026-10-13 | v1.4 | Dùng tên API gốc; bỏ tên tự đặt | Input event_id, event_timestamp, event_title, attendee_emails; output status, strike_id; giá trị Logged / Skipped; cron Weekly Strike Report (báo cáo tuần là cron riêng); tiêu đề API dạng đường dẫn / tên ngắn | Mô tả nội dung bằng lời; tên do BE chốt trong OpenAPI spec. Tiêu đề và Basic Flow dùng tên gốc: Zap Flow 10.1B (Trading Plan AI Dispatch) Action 1 (Parse) / Action 2 (Notification), API Analyze Trading Plan, Task Calendar Compliance Auditor, API Log Calendar Strike (POST /api/community/calendar-strike). API_8.2.3.4 thành "Báo cáo tuần trên Slack (thuộc API Log Calendar Strike)"; tác vụ gửi lúc Thứ Sáu 5PM trỏ Hạng mục mở #12 (A-13) | Chỉ giữ tên có trong nguồn. QnA_init_docs A-07: bỏ tên bảng tự đặt calendar_strikes |
| 2026-10-14 | v1.5 | Toàn UC — viết lại theo khuôn UC_8.1.x | Có bảng "Giải thích thuật ngữ"; Basic Flow chia "Phần A / Phần B / Phần B — Báo cáo tuần", mỗi bước trỏ sang mục API; BR_8.2.3.5 "Thông tin kỹ thuật cho dev"; mục "API & Cron" liệt kê 4 mục API: API_8.2.3.1 Zap Flow 10.1B, API_8.2.3.2 Task Calendar Compliance Auditor (cron), API_8.2.3.3 API Log Calendar Strike (POST /api/community/calendar-strike), API_8.2.3.4 Báo cáo tuần trên Slack; "Hạng mục mở" | Bỏ bảng thuật ngữ (giải thích ngay câu dùng lần đầu). Thêm Scope. Basic Flow chia 5 Stage (1 Email Trading Plan · 2 Đọc lịch leader · 3 Kiểm tra notetaker và ghi strike · 4 Đóng Induction_Due · 5 Báo cáo tuần), bước đánh số, lỗi / chạy trùng đưa vào nhánh [If …] ngay tại bước. Input, xử lý, mã phản hồi của endpoint ghi ngay trong Stage 3; cron ghi ở Trigger và đầu Stage 2. Bỏ mục "API & Cron": chỉ còn 1 API Middleware đúng nguồn — API Log Calendar Strike (POST /api/community/calendar-strike); cùng với webhook TRADING_PLAN_ANALYZED nhận từ UC_8.2.2 và Google Workspace Calendar API (bên thứ 3) ghi tại bước gọi. Zap Flow 10.1B, cron Calendar Compliance Auditor, gửi email AWS SES, DM Discord, báo cáo Slack là hành động trong bước, không đánh số API. BR_8.2.3.5 đổi thành "Chống ghi trùng và chạy lại" (nội dung "Chạy lại / chạy trùng" của API_8.2.3.2–4). "Hạng mục mở" → "Open Items" | Theo yêu cầu BA: mô tả và thứ tự như UC_8.1.1 / UC_8.1.2. Nội dung nghiệp vụ và BR ID giữ nguyên. Số API sửa cho khớp nguồn: Zapier Integration V7.pdf §Flow 10.1B (Trigger webhook TRADING_PLAN_ANALYZED, Action 1 Parse, Action 2 Notification — không có API riêng); RFQ_ Stack Trading Prop Tech V7.pdf §Log Calendar Strike (POST, pod_id, leader_id, "writes the weekly Slack report metrics") và §Background Mechanisms — Calendar Compliance Auditor (Task, Daily @ 01:00 UTC, Target API: Google Workspace Calendar API); QnA POD-DISP-13. |
| 2026-10-14 | v1.6 | Cron Job task tách khỏi API | Cron gọi là "Task Calendar Compliance Auditor" | Ghi rõ Cron Job task Calendar Compliance Auditor; Overview thêm dòng API (API Log Calendar Strike) và Cron Job task | Theo yêu cầu BA: Cron Job task là tác vụ nền chạy theo lịch, khác API; phải ghi rõ "Cron Job task" như API ghi rõ "API". Nguồn: RFQ_ Stack Trading Prop Tech V7.pdf §3.3 Background Workers (Cron Jobs). |
| 2026-10-15 | v1.7 | Basic Flow — biến email gửi leader · Open Items | [Leader_Name], [Mentee_Name], [calendar_link] lấy từ đâu: Open Item #14 (↪ UC_8.2.2 A-05) | Lấy từ payload webhook TRADING_PLAN_ANALYZED — Middleware gửi kèm tên Pod Leader, tên mentee, Master Calendar link; bỏ Open Item #14, đánh số lại #15–#21 → #14–#20 | Theo UC_8.2.2 v1.7 (BA chốt A-05 ngày 2026-10-15) |
| 2026-10-16 | v1.8 | BR_8.2.3.4 · Stage 5 bước 4 · Open Items · RACI | Nội dung tin báo cáo tuần: Open Item #20 (A-19) | Thêm template Slack #ops-risk "Weekly Risk Ops Metrics Report" (tổng cuộc họp nhiều người, tổng vi phạm thiếu notetaker, Strike List Leader_Name | Leader_ID); Stage 5 bước 4 trỏ BR_8.2.3.4; bỏ Open Item #20; RACI ghi copy báo cáo tuần đã gửi | Theo bảng template Stage 6 — POD system khách gửi (A-19 đã chốt trong QnA_init_docs) |
| 2026-10-22 | v1.9 | Overview · Trigger · Stage 1 bước 1, 3 · Stage 2 bước 2–5 · Stage 3 bước 3–5 · Stage 4 · Stage 5 · BR_8.2.3.2, BR_8.2.3.4, BR_8.2.3.5 · Open Items · Phân chia trách nhiệm | 19 Open Items; khoảng đọc lịch chưa rõ, có thể strike lại mỗi ngày; DM lỗi 429/5xx giữ hàng đợi, thử lại theo FR-42; báo cáo tuần 168 giờ, thuộc API Log Calendar Strike; email cập nhật khi nộp lại chưa rõ | Strike chỉ xét cuộc họp chưa huỷ diễn ra trong 24 giờ trước lượt chạy (không đọc bù khi lỡ); đóng Induction_Due xét sự kiện từ lúc chạy − 24 giờ tới + 7 ngày, chỉ mentee còn hạn mở, không lọc theo pod; DM lỗi / chưa liên kết Discord → log cảnh báo, không thử lại, không email thay thế; chấp nhận độ trễ đóng Induction_Due 1 lần/ngày; báo cáo tuần do tác vụ riêng gửi, cửa sổ theo giờ US/Central (167/169 giờ tuần đổi giờ), đếm theo thời điểm diễn ra, tuần 0 strike vẫn gửi; 1 mẫu email leader duy nhất; ghi rõ người thật, strike không hậu quả, leader Active, Master Calendar link do BE gọi API · Open Items còn 3 | Khách trả lời 2026-10-22: A-03, A-04, A-05, A-08, A-09, A-18. Áp các mục BA đã chốt trước: A-01, A-02, A-06, A-07, A-10 → A-16 |
| 2026-10-22 | v1.9 | Basic Flow · Business Rules · Document References — kiểm tra chữ ký webhook | Bước kiểm tra chữ ký (HMAC/JWS), sai → 401 (RFQ V7 §4.4 #19) | Bỏ toàn bộ bước kiểm tra chữ ký và các dòng 401 | BA chốt 2026-10-22: yêu cầu bảo mật chung, khách không nói riêng cho flow này |
| 2026-10-22 | v1.9 | Stage 1 bước 1 | Mỗi lần gán pod mentee nộp 1 lần | Mentee nộp 1 lần duy nhất; đổi pod thì leader mới nhận email với PDF cũ | Theo UC_8.2.2 A-03 |
| 2026-10-22 | v1.9 | Stage 1 bước 1, 3, 4 · Stage 2 bước 1–5 · Stage 3 bước 2, 3 · Stage 4 bước 1, 3 · Stage 5 (mở đầu, bước 2–4) · BR_8.2.3.5 | Một số câu gộp nhiều ý trong 1 dòng | Tách thành các ý riêng (sub-bullet) | Viết lại cho dễ hiểu, không đổi nghiệp vụ |
| 2026-10-22 | v1.9 | Stage 1 bước 1, 3 · Stage 2 bước 1–3, 5 · Stage 3 bước 1, 4, 5 · Stage 4 bước 1, 3 · Stage 5 (mở đầu, bước 3, 4) · BR_8.2.3.1 | Một số câu viết tắt / mơ hồ | Diễn giải rõ nghĩa | Viết lại cho dễ hiểu, không đổi nghiệp vụ |
| 2026-10-22 | v1.9 | Stage 5 — phần mở đầu | Câu "Nội dung, thời điểm gửi và kênh Slack của báo cáo theo QnA POD-DISP-09" | Bỏ câu này (nội dung, thời điểm, kênh đã ghi cụ thể ở Stage 5 bước 3–4 và BR_8.2.3.4); POD-DISP-09 ghi cạnh thời điểm gửi, danh sách tổng hợp và ý leader không nhận báo cáo | Không đổi nghiệp vụ |
| 2026-10-22 | v1.9 | Stage 2 bước 2, 3, 6 · Stage 4 bước 1 · Open Items | Leader DTO / Hiatus: không có bộ lọc riêng, có bị strike không chờ Open Item #3 · khoảng đọc ghi "từ lúc chạy − 24 giờ tới lúc chạy (+ 7 ngày)" | Leader DTO / Hiatus bị bỏ qua, không xét strike; chỉ xử lý leader Active và không Locked · khoảng đọc viết thành lời kèm VD lượt chạy 01:00 UTC ngày 15 · Open Items còn 2 | BA chốt 2026-10-22: leader đang nghỉ không họp nên không strike (khớp ý "naturally exempt" của POD-DISP-08) |
| 2026-10-22 | v1.9 | Toàn UC — Basic Flow, Business Rules | Văn phong ký hiệu, rút gọn, khó đọc | Viết lại bằng câu đầy đủ, kèm VD | Theo mẫu BA duyệt 2026-10-22, không đổi nghiệp vụ |
| 2026-10-22 | v1.9 | Basic Flow · Business Rules — cấu trúc lại theo flow gốc | Basic Flow tự sắp xếp, tách rời Business Rules | Mỗi bước trích nguyên văn flow khách + bổ sung, edge case; BR ngắn gộp vào flow (giữ anchor), BR dài được trỏ từ flow | Theo mẫu UC_8.2.2, không đổi nghiệp vụ |
| 2026-10-27 | v1.10 | Open Items | 2 Open Items | Thêm Open Item #3: cách xác định đúng mentee khi đóng Induction_Due (A-20) | BA mở câu hỏi gửi khách 2026-10-27 |
| 2026-10-29 | v1.11 | Toàn UC — cấu trúc lại theo khuôn UC_1.8.7 (giống UC_8.2.1 v1.12) | Mỗi bước trích nguyên văn flow gốc của khách; đoạn "3 điểm khác nguồn"; edge case và BR_8.2.3.1, BR_8.2.3.2, BR_8.2.3.3, BR_8.2.3.5 nằm rải trong flow; bước đánh số lại từ 1 ở mỗi phần; mã QnA trong thân doc | Bỏ dòng trích nguyên văn và đoạn "điểm khác nguồn" (nội dung ghi thành câu khẳng định ở §5.1 bước 8, §5.4, §5.5). Mục đánh số 1 đến 9; §5 chia 5.1 email leader, 5.2 đọc lịch, 5.3 Task 1 strike, 5.4 Task 2 đóng Induction_Due, 5.5 báo cáo tuần; bước đánh số liên tục 1 đến 38. Edge case gom vào bảng §6 (E_8.2.3.1 đến E_8.2.3.20). BR gom vào bảng §7, nội dung tin nhắn ở §7.1. Mọi BR đều được refer từ bước hoặc exception liên quan. Mã QnA chỉ giữ ở Document References, Open Items và Changelog. Giữ nguyên anchor BR_8.2.3.1 đến BR_8.2.3.5, open-items; 3 Open Items giữ nguyên | BA yêu cầu viết dễ hiểu như UC_1.8.7, không đổi nghiệp vụ |
| 2026-10-29 | v1.11 | §1 Overview — Description | Mô tả chi tiết các bước, tên API, field và nhánh xử lý | Chỉ ghi tổng quan: UC dùng để làm gì và nội dung chính, bằng câu thường; chi tiết xem §5 | BA yêu cầu Description chỉ ghi tổng quan, không đổi nghiệp vụ |