feat(addin): unmock versioning — real upload/download against docver API
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 5s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m27s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 5s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m27s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s
Replace the in-memory versioningService with real calls to the docver group (/api/documents/*) via apiClient with the ticket-issued Bearer; keep the mock only for ?addindemo (authService.isDemoMode). - uploadVersion: multipart POST /api/documents/versions (file, optional pdf when non-empty, clientVersionId, fields JSON, trimmed message, fileName) — identity fields are never sent (userId/userName/templateId in the form = 400 per the 2026-10-22 contract; docId comes from the fid claim) - getVersions: GET → DocumentVersionDTO mapped to VersionRecord (adds optional createdByUserName; history panel shows it with userId fallback) - getDownloadLink: GET presigned URL (+ ?format=pdf) - apiClient.toUrl: empty NEXT_PUBLIC_ADDIN_API_BASE_URL = same-origin through withBasePath (/docedit/api/...); the env is now only for a split deployment (must include basePath, HTTPS) - documentId/templateId params stay in signatures but are not sent - tests: versioningService.test.ts covers both modes (real sign-in via signInWithTicket, FormData contract assertions, DTO mapping, format query, 401 -> AuthRequiredError, demo mock without network) - docs sync: WORDADDIN-DEV (new "การรันกับ backend จริง" section), addin-ui-flow status note, PLAN-DOCVER §8, PLAN-ADDIN-AUTH §12, CLAUDE.md Verified: tsc clean, 286/286 tests, full E2E against MinIO (ticket -> token -> upload docx / docx+pdf -> history -> presigned download of both formats). Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
4200176239
commit
37b18c58c2
11 changed files with 373 additions and 68 deletions
|
|
@ -4,7 +4,7 @@ Taskpane ของ Word add-in "e-Court Documents Versioning" พอร์ตม
|
|||
|
||||
**ทางเข้า:** เปิด `/docedit` เปล่า ๆ จะ redirect มาที่ taskpane ทันที (ไม่ผ่าน login — คำขอผู้ใช้ 2026-10-14) ยกเว้นลิงก์ e-Court `/docedit/?fileUrl=&fileId=&typeId=` ที่ยังส่งต่อให้ `/note` ตามสัญญา N8 · manifest ชี้ `/docedit/wordaddin` ตรง ๆ (ไม่ว่าผ่าน root เพื่อลด hop ใน webview)
|
||||
|
||||
สถานะช่วงนี้: **ไม่มี login แล้ว** (ยกเลิก Keycloak 2026-10-27 — auth เข้าทางเดียวคือ **ticket ของ e-Court** (`ticket_data` + `HmacSha256` ในไฟล์): add-in ตรวจ HMAC เอง → ขอ token ที่ `/api/documents/token` → เก็บใน localStorage ตาม fid ดูหัว "ทดสอบ e-Court ticket" และแผน `docs/PLAN-ADDIN-AUTH.md`) ส่วน **API ยังเป็น mock** (version store เก็บ metadata ค้างข้าม session ใน localStorage ของ taskpane เพื่อทดสอบวงปิดเอกสาร→เปิดใหม่ — สลับกลับของจริงด้วยการลบ `wordaddin-mock-versions` หรือเคลียร์ storage ของ origin) รอ backend จริง — ดูหัว "การสลับกลับของจริง" ด้านล่าง
|
||||
สถานะช่วงนี้: **ไม่มี login แล้ว** (ยกเลิก Keycloak 2026-10-27 — auth เข้าทางเดียวคือ **ticket ของ e-Court** (`ticket_data` + `HmacSha256` ในไฟล์): add-in ตรวจ HMAC เอง → ขอ token ที่ `/api/documents/token` → เก็บใน localStorage ตาม fid ดูหัว "ทดสอบ e-Court ticket" และแผน `docs/PLAN-ADDIN-AUTH.md`) และ **upload/download เป็นของจริงแล้ว** (ปลด mock 2026-10-27 — `versioningService` ยิงกลุ่ม `/api/documents/*` ผ่าน Bearer จาก ticket: Save & Version ขึ้น MinIO จริง ดาวน์โหลดเปิด presigned URL ในเบราว์เซอร์; เหลือ mock เฉพาะโหมด `?addindemo` เพื่อดู UI ใน browser โดยไม่ต้องมี backend — ดูหัว "การรันกับ backend จริง")
|
||||
|
||||
## ไฟล์หลัก
|
||||
|
||||
|
|
@ -76,11 +76,14 @@ node scripts/make-ticket-docx.mjs path/to/file.docx --tracked --in-place
|
|||
|
||||
หมายเหตุ: การขอ token ยิง same-origin `/docedit/api/documents/token` จริง (ไม่ผูก `NEXT_PUBLIC_ADDIN_API_BASE_URL`) — dev server ต้องรันอยู่และ secret ฝั่ง server (`ADDIN_TICKET_SECRET` → `SECRET` → default `super_secret`) ตรงกับ `--secret` ของสคริปต์
|
||||
|
||||
## การสลับกลับของจริง (วันหน้า)
|
||||
## การรันกับ backend จริง (ปลด mock แล้ว 2026-10-27)
|
||||
|
||||
- **Auth:** ไม่มี login ให้สลับแล้ว — **ยกเลิก Keycloak ถาวร 2026-10-27** · auth ของ add-in คือ ticket ของ e-Court ผ่าน `signInWithTicket` (ticket_data + HmacSha256 ในไฟล์ — แผนเต็ม `docs/PLAN-ADDIN-AUTH.md`): add-in ตรวจ HMAC ฝั่ง client (UX gate) แล้วขอ access_token ที่ `/api/documents/token` ซึ่ง server ตรวจ HMAC+exp อีกชั้นด้วย secret ฝั่ง server · โดน 401 กลาง flow = ลอง renew จาก ticket 1 ครั้ง ยังไม่ผ่าน = `AuthRequiredError` → หน้า `no-access` (ticket ต่ออายุไม่ได้ — ต้องได้ไฟล์ใหม่จาก e-Court)
|
||||
- **API:** `wordaddin/services/versioningService.ts` เก็บชื่อ/ลายเซ็นเหมือนต้นฉบับเป๊ะ — ก้อบ body เดิม (multipart POST ผ่าน `apiClient` ซึ่งพอร์ตไว้แล้ว) กลับมา + ตั้ง `NEXT_PUBLIC_ADDIN_API_BASE_URL` (contract ปัจจุบันของกลุ่ม docver สรุปไว้ใน docblock ของไฟล์นั้น + docs/PLAN-DOCVER.md — identity/docId แกะจาก Bearer token ทั้งหมด)
|
||||
- ชุด unit test ของ services (jest → vitest) ยังไม่พอร์ต — ต้นฉบับอยู่ที่ `D:\word-addin-poc\addin\src\services\*.test.ts` + mock ที่ `src/test/`
|
||||
- **Auth:** ไม่มี login — **ยกเลิก Keycloak ถาวร 2026-10-27** · auth ของ add-in คือ ticket ของ e-Court ผ่าน `signInWithTicket` (ticket_data + HmacSha256 ในไฟล์ — แผนเต็ม `docs/PLAN-ADDIN-AUTH.md`): add-in ตรวจ HMAC ฝั่ง client (UX gate) แล้วขอ access_token ที่ `/api/documents/token` ซึ่ง server ตรวจ HMAC+exp อีกชั้นด้วย secret ฝั่ง server · โดน 401 กลาง flow = ลอง renew จาก ticket 1 ครั้ง ยังไม่ผ่าน = `AuthRequiredError` → หน้า `no-access` (ticket ต่ออายุไม่ได้ — ต้องได้ไฟล์ใหม่จาก e-Court)
|
||||
- **Upload/download ของจริงเป็น default แล้ว:** `wordaddin/services/versioningService.ts` ยิงกลุ่ม `/api/documents/*` ผ่าน `apiClient` (Bearer จาก ticket) — **ไม่ต้องตั้ง env อะไรเพิ่ม** เพราะ `apiClient.toUrl` ใช้ same-origin `withBasePath("/api/documents/…")` เมื่อ `NEXT_PUBLIC_ADDIN_API_BASE_URL` ว่าง (API ของกลุ่ม docver อยู่แอปนี้เอง) · ตั้งค่า env นั้นเฉพาะวันที่ deploy add-in กับ API คนละ origin (ต้องรวม basePath เช่น `https://host/docedit` และเป็น HTTPS)
|
||||
- **เอกสารถูกระบุด้วย fid ใน token** — พารามิเตอร์ `documentId` (GUID ที่ stamp ในไฟล์) ของ uploadVersion/getVersions/getDownloadLink เหลือไว้ตาม signature เดิม ไม่ถูกส่งถึง server · templateId ก็เช่นกัน (มาจาก claims ของ token — ส่งใน form = 400)
|
||||
- **สิ่งที่ต้องรันฝั่ง server ก่อนใช้จริง:** MinIO (`docker compose up -d minio` — bucket `docver` app สร้างเอง) + env `DOCVER_API_KEY`/`DOCVER_TOKEN_SECRET`/`MINIO_*` ตาม `.env.example` ของกลุ่ม docver (docs/PLAN-DOCVER.md §6) · ทดสอบวงเต็ม: สร้างไฟล์ด้วย `make-ticket-docx.mjs` → เปิดใน Word → Save & Version → version ขึ้น MinIO จริง → กดดาวน์โหลด/PDF เปิด presigned URL ในเบราว์เซอร์ (โฮสต์ MinIO ต้องเข้าถึงได้จากเครื่องผู้ใช้)
|
||||
- **mock เหลือเฉพาะโหมด `?addindemo`** (dev-only — ดู UI ใน browser ไม่ต้องมี backend: version เก็บในเครื่อง metadata ใน localStorage `wordaddin-mock-versions`, download-link คืน about:blank — เคลียร์ด้วยการลบ key นี้หรือ clear storage ของ origin)
|
||||
- ชุด unit test ของ services: ต้นฉบับ jest อยู่ที่ `D:\word-addin-poc\addin\src\services\*.test.ts` — ฝั่งนี้เขียนใหม่เป็น vitest เฉพาะส่วนที่เป็นโค้ดใหม่ (ticket auth + versioningService สองโหมด ที่ `tests/wordaddin/`)
|
||||
|
||||
## Docker
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue