Private Docs

Dev Cluster E2E — Onboarding: เดินถึงไหน / เหลืออะไร / บล็อคอะไร

สถานะการรัน E2E onboarding (NEW_REQUESTOR) บน deployed dev cluster จริง — map ต่อ sequence diagram §3-§5 ของ 07-e2e-real-run-sequences · key: Rework→Resubmit-200 ที่เคย 🔴 ตอน local = ✅ verified บน cluster แล้ว (real Entra OTP via Redis)

อัปเดต: 2026-06-28

อ้างอิง sequence ตัวเต็ม: 07-e2e-real-run-sequences — diagram §3 (happy) / §4.1 (Reject) / §4.2 (Rework→Resubmit) / §4.3 (Cancel) เอกสารนี้ = overlay สถานะ บน deployed dev cluster (gateway gateway-dev.exim.go.th + AKS aks-SupperApp-dev) ทับ diagram เดิมที่เป็นผล local run (mock OTP) driver + แผน + หลักฐานเต็ม: Atlas docs/orchestration-integration/28062026/PLAN_DEV_E2E_AUTOMATED_DRIVER.md + E2E_DRIVER.py


TL;DR

  • ขับ client จริงบน deployed dev cluster ได้ end-to-end ถึง Resubmit-200 — ไม่ใช่ local fleet, ไม่ใช่ mock
  • สิ่งที่ 07 §4.2 ค้าง 🔴 (resubmit 409 → “รอ verify ตอน deploy”) = ผ่านแล้ว: /resubmit คืน HTTP 200 + DocStatus=ReSubmitted (2 runs)
  • 🔑 ปลดล็อก OTP จริง (เดิม local ต้อง mock): deployed US ใช้ Entra Native Auth จริง — fresh-signup OTP email ไม่ delivery บน dev แต่ code ถูก stamp ลง Redis → อ่านผ่าน VPN ได้
  • ยังไม่รันบน cluster: full happy-path ถึง Completed/Finalized · branch Reject · branch Cancel · OC→US return (US Status flips) · maker/approver notification
  • 🔴 บล็อค: cleanup 2 instance ค้างคิว (classifier) · maker/approver notify (role-mapping) · WF endpoint instances/db/by-document พัง (Autofac)

1. dev cluster ต่างจาก local (07 doc) ยังไง

ด้านlocal run (07 doc)dev cluster run (เอกสารนี้)
ที่รัน servicelocal fleet (US
… WF
)
deployed pod ทั้งหมด บน superappdev (ผ่าน gateway)
OTP🔧 mock (LOCAL_E2E_MOCK_OTP)Entra Native Auth จริง — code อ่านจาก Redis (email ไม่ delivery, ดู §4)
RefNostub แล้ว full-7 real (FX-…88)real Centralized→Codex (FX-…99/00, 5-digit zero-padded)
WF instancelocal WF (#43)cluster WF (#50/#53) สร้างโดย OC saga จริง
TS task_idlocalcluster TS (task 46/49) — ดึงผ่าน kubectl port-forward
authbypass localWF AllowAnonymous + bypass non-prod (ไม่ต้อง JWT)

2. Mapping ต่อ 07 sequence — เดินถึงไหนบน dev cluster

สถานะ: ✅ verified บน cluster · ⬜ ยังไม่รันบน cluster (proven local) · 🔴 blocked

07 § / lanesteplocaldev cluster
§3 LANE 1POST /onboarding/instances (NEW_REQUESTOR)
§3 LANE 1OTP SaveDraft → Entra จริง → code🔧 mock✅ real (Redis)
§3 LANE 1RefNo Centralized→Codex✅ FX-…88✅ FX-…99/00
§3 LANE 1OTP Next → BindOwner + cookie🔧 mock✅ real verify
§3 LANE 1Next × Juristic→UserMode→Designate→CompanyInfo→Signatory
§3 LANE 1FxRequestorTcConsentStep/Submitflow-submitted-for-approval✅ (SUBMITTED)
§3 LANE 2OC saga = AwaitingPickup✅ (cluster OC)
§3 LANE 2OC→WF POST /instances (create)✅ #43✅ #50/#53
§3 LANE 2WF→TS POST /tasks (New)✅ task 46/49
§3 LANE 2WF→NS maker notification🟡 NoRecipient🟡 (ไม่เช็ค — role-map เดิม)
§3 LANE 3-4Maker pickup → APPROVE → Approver pickup → APPROVE → Completed(proven local; ไม่รัน cluster)
§3 LANE 3-4OC→US return progress/result → US Status flips → Finalized(ไม่ verify ฝั่ง US)
§4.1 BApprover REJECT → saga Rejected
§4.2 CMaker /reworkIsEditable=true
§4.2 CRequestor /resubmit200 + DocStatus=ReSubmitted🔴 409✅✅ 200
§4.3 D/cancel → saga Cancelled🔴 (classifier block — ดู §5)

หัวใจ: แถว §4.2 resubmit — 07 doc เขียน 🔴 (WF /resubmit 409 IsEditable=false, fix unit-verified แต่ “E2E resubmit→200 รอ verify ตอน deploy”). deploy แล้ว + verify แล้ว = ✅ บน cluster จริง.


3. ✅ Verified บน dev cluster — chain เต็ม (หลักฐาน)

Requestor (driver)
  → US: Start NEW_REQUESTOR ................................ 200  flowInstanceId
  → US: OTP SaveDraft (real Entra) ........................ 200  refNo issued
  → Redis: DEV_Notification:otp:onboarding:{email}:{ref} .. OtpCode
  → US: OTP Next ......................................... 200  → step 2 (cookie set)
  → US: Juristic→UserMode→Designate→CompanyInfo→Signatory . 200 ×5
  → US: FxRequestorTcConsent /Submit ..................... 200  SUBMITTED
  ── flow-submitted-for-approval (ASB) ──
  OC saga → OC creates WF instance ...................... WF #50 (DocStatus=Submitted)
  WF → TS create task .................................. TS task 46
  → WF: maker /rework {taskId,role:AdminMaker} .......... 200  IsEditable=true, DocStatus=Rework
  → WF: /resubmit {} ................................... 200  ← (เคย 409)
  → WF: instances/by-document ......................... DocStatus = ReSubmitted ✅
runrefNoWF instanceTS taskผล
1 (driver.py)FX-202606-00099#5046resubmit 200 · DocStatus=ReSubmitted ✅
2 (E2E_DRIVER.py)FX-202606-00100#5349resubmit 200 · DocStatus=ReSubmitted ✅

gate flip: ตาม Atlas 26062026/ROLLOUT_WF_RESUBMIT_ISEDITABLE_FIX.md §4 — #1 /resubmit=200 ✅ + #2 DocStatus=ReSubmitted ✅ → 07 §4.2 / §5 ของ resubmit ควร flip 🔴→✅

scope ของ 924 ที่ verify: template OnboardingFX บน dev = AssignmentPolicy=ANY (ไม่ใช่ ALL ตามที่ 07 §304 สมมติ) → ที่ verify สด = part-(a) IsEditable false→true (= สาเหตุ 409 จริง) · part-(b) case-mismatch ("REWORK" vs "Rework", เฉพาะ ALL) ไม่ถูก trigger บน flow นี้ แต่ครอบโดย unit 140/140 แล้ว


4. 🔑 OTP บน dev cluster — ทำไมต้อง Redis (ไม่ใช่ mock, ไม่ใช่ email)

deployed US ไม่มี mock (LocalE2EOtpMocks อยู่แค่ worktree, never deployed) → ใช้ Entra Native Auth SignUp จริง:

  1. base email = registered แล้ว → Otp.DuplicateAccount · +alias/dot = fresh signup ได้ (SaveDraft 200)
  2. แต่ OTP email fresh-signup ไม่ delivery บน dev (ทั้ง +alias และ dot-variant: 200 แต่ไม่มีเมลถึง gmail — น่าจะ infra/anti-spam; emails เก่าที่เคยมาน่าจะเป็น login OTP)
  3. ทางที่ใช้ได้: Entra→Notification webhook stamp OTP ลง Redis ก่อน (แม้ email พัง) → อ่านจาก Redis ได้:
    • key: DEV_Notification:otp:onboarding:{email}:{refCode} (email มี {} literal) · JSON field .OtpCode · TTL 300s
    • Redis = sua-redis-mi-dev…:10000 (Enterprise/SSL, private endpoint) → ต้อง VPN + access-key (เครื่องนอก VNet เข้าตรงไม่ได้)
    • +alias = uniqueness ไม่จำกัด (อ่าน code จาก Redis ไม่ต้องรอ email)

gotcha: urllib ต้องใส่ User-Agent: curl/8.0 (cloudflare bot-block) · Next ออก __Host-onboarding cookie สำหรับ step ถัดไป


5. เหลืออะไร / อะไรบล็อค

⬜ ยังไม่รันบน dev cluster (รันต่อได้ — กลไกพร้อม)

  • full happy-path → Completed/Finalized (§3 LANE 3-4): maker APPROVE → approver APPROVE ผ่าน POST /{instanceId}/steps/{stepInstanceId}/action {APPROVE}ต้องส่ง TaskId (APPROVE-เดินต่อ set taskProgress → guard) → ใช้ TS task_id (port-forward) เหมือน /rework · branch นี้ proven local (FULL7 FX-…88) แต่ยังไม่ replay บน cluster
  • branch Reject (§4.1) + OC→US return (US Status flips InReview/Reviewed/Approved) บน cluster — เอกสารนี้ verify ฝั่ง WF; ยังไม่ดึง US FlowInstance.Status มายืนยัน
  • invitation email / NS in-app → requestor หลัง approve (M2b หยุดก่อน Completed จึงยังไม่ทริกเกอร์)

🔴 บล็อค

จุดอาการ / ต้องการ
cleanup #50/#53จบที่ Status=RUNNING, DocStatus=ReSubmitted → ค้างในคิว AdminMaker จริง บน shared dev · /cancel = shared-resource change → classifier block ผม → ต้อง user อนุมัติ/รันเอง (POST /{id}/cancel {instanceId,taskId,userId,reason} + port-forward TS)
maker/approver notificationrole-lookup ไม่เจอ user จริง → NoRecipient (เหมือน local 🟡) · ต้องมี real admin user map กับ role GUID AdminMaker/AdminApprover ใน dev US DB
WF instances/db/by-document🐛 ComponentNotRegisteredException (Autofac, WorkflowController.cs:156) บน deployed image → endpoint พัง · workaround = ใช้ instances/by-document (DocStatus เดียวกัน) · ส่ง WF team
env=Development durabilitydeployed WF (dev-99eaf44) มี ASPNETCORE_ENVIRONMENT=Development แล้ว (ไม่ crash) — แต่ถ้ามาจาก manual patch ไม่ใช่ IaC อาจหายตอน ArgoCD sync → confirm PR 955 merge

side-effect ที่ยอมรับ

ทุก run register Entra account จริง (+alias/dot) ใน dev CIAM + สร้าง draft instances (FX-…95/96/97/98 = SaveDraft-only ไม่มีพิษ) + real WF/TS/OC state ต่อ refNo


6. รันซ้ำยังไง (reproduce)

driver: Atlas docs/orchestration-integration/28062026/E2E_DRIVER.py (Python stdlib + redis)

prereq (ต้องเปิดพร้อมกัน):

  1. VPN เข้า dev (Redis private endpoint)
  2. redis_conn.txt (host/port 10000/username default/access-key) — ห้าม commit (live key)
  3. kubectl -n superappdev port-forward svc/task-service 5601:80 (สำหรับ task_id ใน /rework)
REDIS_CONN_FILE=/path/redis_conn.txt python E2E_DRIVER.py
# → [VERIFY PASS] refNo=FX-... WF#.. task=..: resubmit=200 + DocStatus=ReSubmitted