2026-08-18 12:52:40 +07:00
# Word Versioning Add-in
ระบบจัดการ version history ของเอกสาร Word — สร้างเอกสารจาก template ผ่านเว็บ ติดตามทุกการแก้ไขผ่าน add-in ใน Word และ sync ข้อมูลสำคัญกลับฐานข้อมูลอัตโนมัติ
## คุณสมบัติหลัก
- 📝 **สร้างเอกสารจาก template** — กรอก form บนเว็บ → ระบบ generate .docx จาก template (แทนที่ค่าใน content controls) พร้อม stamp metadata และขึ้นเป็น **version 1 อัตโนมัติ**
- 🗂️ **Template management** — upload ไฟล์ .docx ที่มี content controls แล้วระบบ **detect fields อัตโนมัติ** ตั้งชื่อ/ชนิด/required ต่อ field ผ่านหน้าเว็บ
- 📌 **ตรวจจับ tracked document** — เปิดไฟล์ใน Word (Desktop Win/Mac หรือ Online) แล้ว add-in รู้ทันทีว่าไฟล์นี้อยู่ในระบบ พร้อมแสดง version history
- 💾 **Save & Version** — ปุ่มใน task pane สร้าง version ใหม่ (stamp metadata + อัปโหลด snapshot ไป backend)
- 🔄 **Field sync** — ทุกครั้งที่สร้าง version ระบบ extract ค่าจาก content controls ของเอกสารไป update fields ใน DB ให้ sync กับเนื้อหาจริงเสมอ
- ⬇️ **ดาวน์โหลด version ย้อนหลัง** — ทุก version เก็บครบพร้อม SHA256 hash ตรวจสอบความถูกต้องได้
## สถาปัตยกรรม
| ส่วน | Stack | หน้าที่ |
|---|---|---|
| **Add-in** (`/addin` ) | Office.js, TypeScript, React, Fluent UI | Task pane ใน Word — ตรวจจับ document, Save & Version, version history, field extraction |
| **Backend** (`/backend` ) | ASP.NET Core 8, EF Core, PostgreSQL, MinIO, OpenXML | Version API, template system, docx generation, JWT validation |
| **Web Portal** (`/web` ) | Nuxt.js, TailwindCSS | จัดการ template + สร้างเอกสารจาก form (light/dark theme) |
| **Auth** | Keycloak (OIDC + PKCE) | Public clients ทั้ง add-in และเว็บ, backend validate ผ่าน JWKS |
| **Storage** | MinIO (S3-compatible) | bucket `docx-versions` (snapshot ต่อ version) + `docx-templates` (ไฟล์ template) — private ทั้งคู่ |
**Flow หลัก:**
1. Admin upload template (.docx ที่มี content controls) → ระบบ detect fields อัตโนมัติ
2. ผู้ใช้กรอก form บนเว็บ → ได้ไฟล์ .docx ที่เป็น version 1 แล้ว → เปิดใน Word
3. Add-in รู้จักเอกสารทันที → แก้ไขเนื้อหา → กด **Save & Version** → เกิด version ใหม่ + fields ใน DB sync ตามเนื้อหาล่าสุด
## สถานะโปรเจกต์
2026-08-19 10:58:37 +07:00
| Phase | เนื้อหา | สถานะ |
|---|---|---|
| 0 | Scaffold 3 โปรเจกต์ (addin / backend / web) | ✅ เสร็จ |
| 1 | Local dev infra — docker-compose + Keycloak (realm, 3 clients + PKCE) + MinIO (buckets) | ✅ เสร็จ |
| 2 | Backend core — version API (FR-5– 7) + JWT auth (FR-8) | ✅ เสร็จ |
| 3 | Template system + docx generation + field sync (FR-9– 11) | ⏳ รอ implement |
| 4– 5 | Add-in services + task pane UI (FR-1– 4) | ⏳ รอ implement |
| 6 | Web Portal UI (FR-9– 10) | ⏳ รอ implement |
| 7– 8 | Tests + เอกสารฉบับเต็ม | ⏳ รอ implement |
**ใช้ได้แล้วตอนนี้:** infra ทั้งชุด + backend API สำหรับ upload / ดู history / ดาวน์โหลด version (พร้อม JWT auth จาก Keycloak) — ลองเล่นได้ผ่าน Swagger
2026-08-18 12:52:40 +07:00
## เอกสาร
- [specs/spec-officejs.md ](specs/spec-officejs.md ) — spec เต็มรูปแบบ: functional requirements (FR-1– 11), data models, acceptance criteria (1– 14)
- [docs/plans/officejs-implementation-plan.md ](docs/plans/officejs-implementation-plan.md ) — implementation plan แบ่ง 9 phases พร้อม definition of done
สำหรับผู้เริ่มพัฒนา: อ่าน spec ก่อน แล้วตามด้วย plan (เริ่มจาก Phase 0)
2026-08-19 10:58:37 +07:00
## การพัฒนา (local)
### Prerequisites
- Docker Desktop
- .NET 8 SDK + `dotnet-ef` tool (สำหรับ migration):
```bash
dotnet tool install --global dotnet-ef --version 8.0.11
```
- Node.js LTS (add-in และ web — ยังเป็น scaffold)
### 1) รัน infrastructure (PostgreSQL + MinIO + Keycloak)
2026-08-18 12:52:40 +07:00
```bash
2026-08-19 10:58:37 +07:00
cp .env.example .env # ครั้งแรกครั้งเดียว — แก้ password ได้ตามต้องการ
2026-08-18 12:52:40 +07:00
docker compose up -d
2026-08-19 10:58:37 +07:00
```
เมื่อขึ้นครบแล้ว:
| บริการ | URL | เข้าด้วย |
|---|---|---|
| Keycloak admin console | http://localhost:8080/admin/ | `KC_BOOTSTRAP_ADMIN_USERNAME` / `KC_BOOTSTRAP_ADMIN_PASSWORD` จาก `.env` |
| MinIO console | http://localhost:9001 | `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` จาก `.env` |
| PostgreSQL | `localhost:5432` | `POSTGRES_USER` / `POSTGRES_PASSWORD` จาก `.env` , ฐานข้อมูล `wordversioning` |
Keycloak จะ import realm `word-versioning` อัตโนมัติ (clients 3 ตัว + test user) จาก [keycloak/realm-export.json ](keycloak/realm-export.json ) — ไฟล์นี้คือ source of truth ของ realm ฝั่ง dev: แก้ realm ให้แก้ที่ไฟล์นี้แล้วรัน `docker compose rm -sf keycloak && docker compose up -d` เพื่อ import ใหม่ (การแก้ผ่าน admin console จะหายเมื่อ recreate container)
**Test user สำหรับล็อกอิน:** `testuser` / `Test1234!` (เปลี่ยนได้ใน realm-export.json)
MinIO จะมี bucket `docx-versions` และ `docx-templates` (private ทั้งคู่) สร้างให้อัตโนมัติ
2026-08-18 12:52:40 +07:00
2026-08-19 10:58:37 +07:00
### 2) Backend API
```bash
2026-08-18 12:52:40 +07:00
cd backend/WordVersioning.Api
2026-08-19 10:58:37 +07:00
dotnet ef database update # ครั้งแรก / เมื่อมี migration ใหม่
dotnet run # Swagger ที่ http://localhost:5075/swagger
```
ค่าเชื่อมต่อ (DB/MinIO/Keycloak) อยู่ใน `appsettings.json` + `appsettings.Development.json` — override ผ่าน env ได้ทั้งหมด เช่น `ConnectionStrings__Default` , `MinIO__Endpoint` , `Authentication__Authority`
2026-08-18 12:52:40 +07:00
2026-08-19 10:58:37 +07:00
**API ที่มีตอนนี้** (ทุก endpoint ต้องแนบ `Authorization: Bearer <token>` ):
2026-08-18 12:52:40 +07:00
```
2026-08-19 10:58:37 +07:00
POST /api/documents/{documentId}/versions # อัปโหลด version ใหม่ (FR-5)
GET /api/documents/{documentId}/versions # version history ใหม่ → เก่า (FR-6)
GET /api/documents/{documentId}/versions/{versionId}/download # ดาวน์โหลด version (FR-7)
```
- Upload เป็น multipart/form-data: `file` (.docx เท่านั้น, จำกัด 100MB) + `clientVersionId` (GUID) + `fields` (optional, JSON map tag→text สำหรับ field sync)
- `documentId` ยังไม่มีในระบบ = สร้างใหม่อัตโนมัติ · `versionNumber` เพิ่มอัตโนมัติต่อเอกสาร · เก็บ SHA256 ของทุก version
### ขอ token ทดสอบ (dev)
ทุก client บังคับ PKCE (ปิด direct grants ตาม spec) — วิธีเร็วสุดตอนทดสอบคือขอผ่าน client `admin-cli` ของ realm:
```bash
curl -s -X POST http://localhost:8080/realms/word-versioning/protocol/openid-connect/token \
-d "client_id=admin-cli& grant_type=password& username=testuser& password=Test1234!" \
| jq -r .access_token
```
แล้วลอง upload:
```bash
DOC_ID=$(uuidgen | tr 'A-Z' 'a-z')
curl -X POST http://localhost:5075/api/documents/$DOC_ID/versions \
-H "Authorization: Bearer $TOKEN" \
-F "file=@เอกสาร .docx;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
-F "clientVersionId=$(uuidgen)"
# → { "versionId": "...", "versionNumber": 1 }
```
### 3) Add-in และ Web Portal (ยังเป็น scaffold)
```bash
cd addin & & npm start # https://localhost:3000 — ครั้งแรก: npx office-addin-dev-certs install
cd web & & npm run dev # http://localhost:5173
```
สองส่วนนี้ยังเป็นโครงจาก Phase 0 — logic จริง (login, Save & Version, template UI) มาตาม Phase 4– 6
2026-08-18 12:52:40 +07:00
2026-08-19 10:58:37 +07:00
> คำแนะนำฉบับเต็ม (sideload บน Word Desktop/Online, สร้าง template แรก, สร้างเอกสารจากเว็บ) จะเติมเมื่อ implement ครบตาม Phase 8 ของแผน
2026-08-18 12:52:40 +07:00
## เทคโนโลยี
- **Add-in**: Office.js (WordApi 1.5+), TypeScript, React, Fluent UI, webpack — scaffold ด้วย `yo office`
- **Backend**: .NET 8, EF Core + Npgsql (PostgreSQL), AWSSDK.S3 → MinIO (`ForcePathStyle = true` ), DocumentFormat.OpenXml, JwtBearer
- **Web**: Nuxt.js (Vue 3), TailwindCSS (`darkMode: 'class'` )
- **Auth**: Keycloak — realm `word-versioning` , clients: `word-addin-officejs` , `word-versioning-web` , `word-addin-vsto` (public + PKCE S256 ทุกตัว)