Phase 12 v9: draft opens in Word + Thai word-breaking fix (FR-16)
แก้ตามผลใช้งานจริง 2 ประเด็น: 1. เปิดใน Word ทันที — generate-draft เปลี่ยนจากคืนไฟล์ตรงๆ เป็นเก็บ ชั่วคราวใต้ drafts/ (lifecycle ลบรายวัน, config Minio__DraftRetentionDays) + คืน presigned URL ให้เว็บเปิดผ่าน ms-word:ofe พร้อมลิงก์สำรอง (useVersionOpen.openDocxUrl แยกแกนเปิด docx URL ใช้ร่วมกับ flow v0) 2. ตัดคำไทย — T14 แตก placeholder เป็น [ / ข้อความ / ] โดย run ข้อความ ถือ w:hint="cs" + w:cs เท่านั้น; เดิมเขียนค่าลง run ปีกกาทำให้ Word จัดหน้าไทยผิด — แก้เป็นเขียนที่ run ข้อความยาวสุด + SDT เปล่าสืบทอด rPr จาก sdtPr (ใช้ร่วมทั้ง generate และ generate-draft) - ถอดของที่เลิกใช้: CORS expose Content-Disposition, downloadFile init, useApi.spec · Spec v9 + ADR 0002 Amendment + acceptance-review AC-19 - Tests: backend 84 / web 56 + build; QA reviewer PASS (2 rounds, 10 findings แก้ครบ — รวม bug จริงที่ test ใหม่จับได้: lifecycle Rules null ทำ startup ตั้ง rule ล้มแบบเงียบ) · ค้าง manual บน Word จริง Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
b3c1c667f7
commit
70f71f4c5c
23 changed files with 408 additions and 241 deletions
|
|
@ -1,14 +1,18 @@
|
|||
# ADR 0002: ไฟล์ร่าง stateless — stamp TemplateId ตัวเดียว ผูก template ทีหลังตอน Start Versioning
|
||||
# ADR 0002: ไฟล์ร่าง — stamp TemplateId ตัวเดียว ผูก template ทีหลังตอน Start Versioning
|
||||
|
||||
วันที่: 2026-09-10 · สถานะ: Accepted
|
||||
วันที่: 2026-09-10 · สถานะ: Accepted (แก้ไข v9 วันเดียวกัน — ด้วย Amendment ด้านล่าง)
|
||||
|
||||
## Decision
|
||||
ไฟล์ร่าง (FR-16) สร้างแบบ stateless: `POST /api/templates/{id}/generate-draft` คืนไฟล์ทันที ไม่สร้าง Document/version ไม่เขียน MinIO. ไฟล์ถูก stamp custom property `TemplateId` ตัวเดียว (ไม่มี SavedByAddIn/DocumentTrackingId) จึงเป็น untracked ในสายตา add-in. การผูกกลับเข้า template เกิดทีหลังผ่าน form field `templateId` ทางเลือกของ upload ซึ่งใช้เฉพาะตอน auto-create Document — เอกสารเกิดเป็น version 1 โดยไม่มี v0.
|
||||
ไฟล์ร่าง (FR-16) สร้างโดยไม่มี record ใน DB: `POST /api/templates/{id}/generate-draft` ไม่สร้าง Document/version/field values. ไฟล์ถูก stamp custom property `TemplateId` ตัวเดียว (ไม่มี SavedByAddIn/DocumentTrackingId) จึงเป็น untracked ในสายตา add-in. การผูกกลับเข้า template เกิดทีหลังผ่าน form field `templateId` ทางเลือกของ upload ซึ่งใช้เฉพาะตอน auto-create Document — เอกสารเกิดเป็น version 1 โดยไม่มี v0.
|
||||
|
||||
## Amendment (v9, 2026-09-10 — หลังใช้งานจริง)
|
||||
เดิม endpoint คืนไฟล์เป็น stream ตรงๆ (stateless เต็มที่) ทำให้ผู้ใช้ต้องเปิด Word เองจาก Downloads. ผู้ใช้ต้องการเปิดใน Word ทันทีแบบ flow v0 จึงแก้เป็น: generate แล้วเก็บ object ชั่วคราวใต้ prefix `drafts/` ของ bucket docx-versions พร้อม **lifecycle rule ลบรายวัน** (config ได้) แล้วคืน presigned URL อายุสั้นให้เว็บเปิดผ่าน `ms-word:ofe`. สาระสำคัญของ decision เดิมยังอยู่: ไม่มี Document สถานะร่างใน DB ไม่ต้องจัดการ row ที่ไม่ถูกเปิด — ขยะจำกัดอยู่แค่ object ใต้ prefix เดียวที่ลบตัวเอง
|
||||
|
||||
นอกจากนี้พบจาก template จริง (T14): ค่าที่แทนที่ต้องเขียนที่ run ของข้อความ placeholder จริง (run ที่ถือ `w:hint="cs"` + `w:cs`) ไม่ใช่ run แรก (ปีกกา) ไม่งั้น Word ตัดคำ/กระจายภาษาไทยผิดทั้งบรรทัด และ SDT เปล่าต้องสืบทอด rPr จาก sdtPr
|
||||
|
||||
## Alternatives rejected
|
||||
- สร้าง Document สถานะ "ร่าง" ค้างไว้ใน DB + ไฟล์ใน MinIO รอผู้ใช้เปิด: ต้องมี lifecycle/cleanup ของเอกสารที่ไม่ถูกเปิด และเอกสารขยะในหน้ารายการ
|
||||
- สร้าง Document สถานะ "ร่าง" ค้างไว้ใน DB รอผู้ใช้เปิด: ต้องมี lifecycle/cleanup ของ row ที่ไม่ถูกเปิด และเอกสารขยะในหน้ารายการ
|
||||
- stamp SavedByAddIn + DocumentTrackingId ตั้งแต่ตอนสร้างไฟล์ร่าง: add-in จะมองเป็น tracked document แต่ backend ไม่มี record → history ติด 404 ถาวร (ไม่มี 404-handling ในปัจจุบัน)
|
||||
- ปุ่ม "เปิดใน Word" สำหรับไฟล์ร่างแบบ flow v0 (`ms-word:ofe|u|<url>`): ไม่มี URL เพราะไม่มี object ใน storage — ต้องเสีย statelessness ไปเก็บไฟล์ชั่วคราวพร้อม TTL
|
||||
|
||||
## Consequences
|
||||
ไฟล์ร่างหาย/ไม่ถูกเปิด = ไม่มีอะไรค้างในระบบ (ต้องกรอกฟอร์มใหม่). เอกสารจากไฟล์ร่างเริ่มที่ v1 ไม่มี v0 — เลข version ยังกำหนดเป็น "รอบบันทึกผ่าน Word หลังฉบับตั้งต้น" โดย v0 เป็นทางเลือกของ flow เดิม. Field sync เริ่มทำงานที่ v1 จากค่าที่ extract ใน Word. CORS ต้อง expose `Content-Disposition` เพื่อให้เว็บอ่านชื่อไฟล์ไทยได้.
|
||||
เอกสารจากไฟล์ร่างเริ่มที่ v1 ไม่มี v0 — เลข version ยังกำหนดเป็น "รอบบันทึกผ่าน Word หลังฉบับตั้งต้น" โดย v0 เป็นทางเลือกของ flow เดิม. Field sync เริ่มทำงานที่ v1 จากค่าที่ extract ใน Word. Object ไฟล์ร่างที่ไม่ถูกเปิดถูก lifecycle ลบในรอบวัน (ลิงก์ presigned อายุสั้นอยู่แล้ว การเปิดซ้ำหลังผ่านไปนานต้องสร้างไฟล์ร่างใหม่)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue