Hotfix: auto-download fallback when Word cold-start drops the open URL

ผู้ใช้จริง (Mac): กด "เปิดใน Word" ตอน Word ยังไม่เปิดค้างอยู่ — Word
cold-start แล้ว URL event หลุด แสดงหน้า Recent แทนเอกสาร (ข้อจำกัด
ms-word:ofe บน macOS; กลไกนี้ผ่าน manual test ตอน Word เปิดอยู่ก่อนแล้ว)

- useVersionOpen.openDocxUrl: หน้าต่างรอ 1.5s → 3s และเมื่อไม่เห็นการ
  สลับแอป → ดาวน์โหลดไฟล์ให้อัตโนมัติ (anchor → presigned attachment)
  + ข้อความแนะนำเปิดจาก Downloads หรือกดซ้ำเมื่อ Word เปิดอยู่แล้ว
  — ใช้ร่วมทุกจุดเปิด docx (version rows, v0, ไฟล์ร่าง) PDF ไม่เกี่ยว
- Tests: timing edge 2999/3000 + href + notice, ไม่ download เมื่อสลับ
  แอปจริง, re-click ยกเลิก timer เก่า (web 59/59 + build)
- Spec FR-15/16 (~3s + auto-download + หมายเหตุ cold-start) +
  acceptance-review เพิ่ม manual check item
- QA reviewer PASS (1 round; minors 3 — แก้ 1 ยอมรับ 2 พร้อมเหตุผล)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Suphonchai Phoonsawat 2026-09-10 12:22:19 +07:00
parent b9b227926d
commit e0558e3cf4
6 changed files with 82 additions and 10 deletions

View file

@ -291,7 +291,7 @@ POST /api/documents/generate { templateId, values: { <fieldKey>: <value> } }
- เก็บ PDF ใน bucket docx-versions, sibling key `{documentId}/v{N:D4}_{clientVersionId}.pdf`; `PdfObjectKey` nullable
- docx upload ล้มใช้ error เดิม; PDF upload ล้มเป็น best-effort → version สำเร็จ `hasPdf:false`; task pane เตือน “บันทึกแล้ว แต่สร้าง PDF ไม่สำเร็จ” และแนะนำ Save & Version ใหม่
- upload/history response มี `hasPdf`; ปุ่ม PDF แสดงเฉพาะเมื่อมี PDF; add-in เปิด presigned URL ผ่าน `openBrowserWindow`
- เว็บ history ทั้ง desktop/mobile เปิด docx ผ่าน `ms-word:ofe|u|<presigned-url>` (ไม่ encode URL ทั้งก้อนซ้ำตาม Microsoft Office URI Schemes); PDF แท็บใหม่; มีลิงก์ดาวน์โหลดสำรองและ heuristic blur/visibilitychange ~1.5s ซึ่งไม่ใช่หลักฐานว่า Word เปิดสำเร็จ
- เว็บ history ทั้ง desktop/mobile เปิด docx ผ่าน `ms-word:ofe|u|<presigned-url>` (ไม่ encode URL ทั้งก้อนซ้ำตาม Microsoft Office URI Schemes); PDF แท็บใหม่; มีลิงก์ดาวน์โหลดสำรองและ heuristic blur/visibilitychange ~3s ซึ่งไม่ใช่หลักฐานว่า Word เปิดสำเร็จ — ถ้าไม่เห็นการสลับแอปภายในหน้าต่างรอ ให้**ดาวน์โหลดไฟล์ให้อัตโนมัติ** + แนะนำเปิดจาก Downloads หรือกดซ้ำ (v9.1: `ms-word:ofe` บน macOS ตอน Word cold-start มักทำ URL event หลุด → เห็นหน้า Recent แทนเอกสาร — กดครั้งที่สองขณะ Word เปิดอยู่แล้วจะสำเร็จ)
- หน้า generate success เปิด v0 ใน Word พร้อมลิงก์ดาวน์โหลดสำรอง; PDF fidelity และ tracked changes ต้องยืนยันบน Word จริง
### FR-16: ไฟล์ร่าง (draft) — สร้าง .docx จาก template โดยไม่สร้าง Document (เพิ่มเติม v8 · ปรับ v9)
@ -301,7 +301,7 @@ POST /api/documents/generate { templateId, values: { <fieldKey>: <value> } }
- **ค่าที่แทนที่เขียนที่ run ของ "ข้อความ placeholder จริง"** (v9 — ใช้ร่วมทั้ง generate และ generate-draft): template ไทยมักแตก placeholder เป็น `[` / ข้อความ / `]` หลาย run โดย run ข้อความถือ `w:hint="cs"` + `w:cs` (complex script) ที่ Word ใช้ตัดคำ/กระจายภาษาไทย — เขียนค่าที่ run ที่มีข้อความยาวสุด (ไม่ใช่ run แรกที่เป็นปีกกา) · SDT เปล่าให้ run ใหม่สืบทอด `rPr` จาก `sdtPr` (เหมือนพฤติกรรม Word ตอนพิมพ์ลง control)
- **ผูก template ตอน Start Versioning:** `POST /api/documents/{documentId}/versions` รับ `templateId` (multipart form field ทางเลือก) — ใช้เฉพาะตอน auto-create `Document` (field sync ทำงานเต็มระบบที่ v1); document มีอยู่แล้ว → เฉย (แต่ validate ทุกครั้งที่ส่งมา) · ไม่ใช่ GUID / ไม่พบใน DB → 400 · template ที่ deactivate → **ผูกได้** (ไฟล์ร่างถูกสร้างตอน template ยัง active — นโยบายเดียวกับ FR-9/FR-12) · upload แรกของ Document ใหม่ = **version 1** (max+1 — ไม่มี v0)
- Add-in: อ่าน property `TemplateId` ตอน untracked แล้วแนบ `templateId` **เฉพาะตอน Start Versioning** (Save & Version ไม่ส่ง) + แสดง hint ว่าไฟล์นี้เป็นไฟล์ร่างจาก template
- Web Portal: ปุ่ม "สร้างไฟล์ร่าง" ที่สองบนฟอร์มสร้างเอกสารเดิม → **เปิดใน Word ทันที** ผ่าน `ms-word:ofe|u|<presigned-url>` พร้อมลิงก์ดาวน์โหลดสำรองอายุสั้น + heuristic เตือนเมื่อไม่เห็นการสลับแอป (กลไกเดียวกับ flow เปิด v0 — `useVersionOpen`); ฟอร์มอยู่ต่อ ไม่มี documentId/หน้าผลลัพธ์ · ช่องคำอธิบาย version ใช้กับ flow สร้างเอกสาร v0 เท่านั้น · flow v0 (FR-10) และ re-generate (FR-12) คงเดิม
- Web Portal: ปุ่ม "สร้างไฟล์ร่าง" ที่สองบนฟอร์มสร้างเอกสารเดิม → **เปิดใน Word ทันที** ผ่าน `ms-word:ofe|u|<presigned-url>` พร้อมลิงก์ดาวน์โหลดสำรองอายุสั้น + heuristic 3 วิ (สลับแอปไม่ได้ = ดาวน์โหลดให้อัตโนมัติ — กลไกเดียวกับ flow เปิด v0 `useVersionOpen`); ฟอร์มอยู่ต่อ ไม่มี documentId/หน้าผลลัพธ์ · ช่องคำอธิบาย version ใช้กับ flow สร้างเอกสาร v0 เท่านั้น · flow v0 (FR-10) และ re-generate (FR-12) คงเดิม
## 7. Data Model (Backend)