eCourt-Doc-Edit/CLAUDE.md
Suphonchai Phoonsawat b976cf3124 implement Phase 1-2
2026-08-19 10:54:55 +07:00

76 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## โปรเจกต์นี้คืออะไร
ระบบ **Word Versioning**: จัดการ version history ของไฟล์ .docx — สร้างเอกสารจาก template ผ่านเว็บ, ตรวจจับ tracked document ใน Word, บันทึก version ผ่านปุ่ม Save & Version และ sync ค่า fields กลับ DB ประกอบด้วย 3 ส่วน:
| ส่วน | Stack | หน้าที่ |
|---|---|---|
| `/addin` | Office.js + TypeScript + React + Fluent UI (`yo office`) | Task pane ใน Word Desktop/Online — detect, Save & Version, history, field extraction |
| `/backend` | ASP.NET Core 8 + EF Core + PostgreSQL + MinIO (AWSSDK.S3) + OpenXML | Version API, template system, docx generation, JWT validation |
| `/web` | Nuxt.js + TailwindCSS (light/dark theme) | จัดการ template + กรอก form สร้างเอกสารเป็น version 1 อัตโนมัติ |
Infra ทั้งหมดรันผ่าน `docker-compose.yml`: PostgreSQL + MinIO + Keycloak (OIDC, 3 public clients พร้อม PKCE: `word-addin-officejs`, `word-versioning-web`, `word-addin-vsto`)
**สถานะปัจจุบัน: Phase 0–2 เสร็จ** (scaffold + infra + backend core FR-5–8) — งานต่อคือ implement phase 3–8 ในแผน
## เอกสารหลัก (อ่านก่อนเริ่มงานใดๆ)
- `specs/spec-officejs.md` — **source of truth ของ requirements** (FR-1–11, acceptance criteria 1–14, data models, platform constraints)
- `docs/plans/officejs-implementation-plan.md` — implementation plan แบ่ง 9 phases พร้อม checklist, DoD, dependency ระหว่าง phase และตารา mapping Phase↔FR↔AC
เมื่อ requirement เปลี่ยน: แก้ spec ก่อน แล้ว sync ไปยัง plan
## กฎที่ห้ามละเมิด (ข้อจำกัดแพลตฟอร์มจริง — สรุปจาก spec ส่วน 2 และ 9)
1. **ห้ามออกแบบ flow ที่ดัก native save** (Ctrl+S / File>Save) — Office.js ไม่มี before-save event ที่ cancel ได้ ใช้ปุ่มใน task pane เท่านั้น
2. **Custom Document Properties = primary flag** ตรวจจับ tracked document; **Custom XML Part = secondary เท่านั้น** (ต้อง delete แล้ว add ใหม่ทุกครั้ง, มี known bug บน Mac บาง build — ต้อง catch แบบไม่ throw)
3. **ห้าม redirect iframe ของ task pane ไป Keycloak ตรงๆ** — ต้องใช้ Office Dialog API (`displayDialogAsync` + `messageParent`); ส่วน `/web` เป็น top-level page ใช้ OIDC redirect ปกติ
4. **Token เก็บใน memory เท่านั้น** — ห้าม localStorage (theme preference ของ `/web` ยกเว้นได้)
5. **Backend คือ source of truth** ของ version history และ field values
6. **Field key = content control (SDT) tag** ใช้ค่าเดียวกันทั้ง generate (backend) / extract (add-in) / sync (DB)
7. **Docx generation + metadata stamping ทำฝั่ง backend เท่านั้น** (OpenXML, แก้ที่ run level ใน SDT เพื่อรักษา formatting)
8. **Ports:** add-in = `https://localhost:3000`, web = `http://localhost:5173` (ห้ามชนกัน), backend CORS ต้องอนุญาตทั้งคู่
9. **Config (DB/MinIO/Keycloak) แยกเป็น env/appsettings เท่านั้น** — ห้าม hardcode; `userId` เอาจาก JWT claims เท่านั้น ห้ามรับจาก client
10. **ทุก Office.js call ต้อง catch** — ห้ามปล่อย unhandled promise rejection
## สถาปัตยกรรม — flow หลักที่ต้องเข้าใจ
**Create → v1 (FR-10):** web form → `POST /api/documents/generate` → OpenXML แทนที่ค่าใน SDT + stamp `SavedByAddIn`/`DocumentTrackingId` ลงไฟล์ → สร้าง `Document` + `DocumentFieldValue` + upload v1 → ผู้ใช้โหลดไฟล์ไปเปิดใน Word → add-in ตรวจพบ tracked doc ทันทีเห็น v1
**Save & Version (FR-2):** ปุ่มใน task pane → stamp properties → อัปเดต XML part (delete-then-add, fail ได้แบบ silent) → `document.save()` → `getFileAsync` → POST version **พร้อม `fields` map จาก content controls (FR-11)** → backend update `DocumentFieldValue` (latest) + `FieldsSnapshotJson` (ต่อ version)
**Field sync policy (FR-11):** field ขาด (ผู้ใช้ลบ control) → เก็บค่าเดิม + mark missing **ไม่ fail request**; ส่งมาเกินนิยาม → ignore
**MinIO:** bucket `docx-versions` (snapshot ต่อ version, key `{documentId}/v{N:D4}_{clientVersionId}.docx`) + `docx-templates` (ไฟล์ template) — private ทั้งคู่, เข้าถึงผ่าน backend proxy stream เท่านั้น
**Template:** template.docx author ด้วย Word (ใส่ content controls) → upload → backend parse SDT tags → admin ตั้ง label/type/required → delete = deactivate (soft) เพราะ document เก่ายังอ้างอยู่
## คำสั่ง (ใช้ได้หลัง scaffold ใน Phase 0)
```bash
docker compose up -d # infra: PostgreSQL + MinIO + Keycloak
# backend
cd backend/WordVersioning.Api
dotnet run # API + swagger
dotnet ef migrations add <Name>
dotnet test
dotnet test --filter "FullyQualifiedName~GenerateTests" # รัน test เดี่ยว
# add-in (https://localhost:3000)
cd addin
npm run build # webpack build
npm start # dev server — sideload ผ่าน manifest
npm test
npx jest src/services/metadataService.test.ts # รัน test เดี่ยว
npx office-addin-dev-certs install # ครั้งแรกครั้งเดียว
# web portal (http://localhost:5173 — ห้ามใช้ 3000)
cd web
npm run dev
npm test
npx vitest run composables/useTheme.spec.ts # รัน test เดี่ยว
```