groups: หน้ากลุ่มแสดง bookmark+annotation ทั้งกลุ่มในการ์ดไฟล์ — หุบ/กาง <details> "Annotations & Bookmarks (N)" รวมรายการเดียวเรียงตามหน้า (หน้าเดียวกัน bookmark ก่อน) + deep link ?ann=/?page= เหมือนหน้าสรุป + วันเวลา (formatThaiDate) ต่อรายการ + meta การ์ดเป็น en + ย่อ banner เป็น "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้" — ปิด gap 5.3.10 ครึ่งหลัง (bookmark รวมทั้งกลุ่ม) + docs sync ครบ (คำขอผู้ใช้ 2026-09-23)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
329ae8e956
commit
e254b935ce
5 changed files with 223 additions and 57 deletions
|
|
@ -1,6 +1,7 @@
|
|||
# แผน N9 — กลุ่มเอกสารตาม `typeId` จาก e-Court + หน้ารายการเอกสารในกลุ่ม
|
||||
|
||||
> สถานะ: **implement แล้ว (2026-09-23)** — `tsc` + vitest 142/142 + Playwright ผ่านทุกข้อ verify ของ task 3–4 + plan-reviewer/code-reviewer ไม่พบ violation (คงเหลือ e2e ลิงก์ e-Court จริงตามแผน ตอนปิดงาน N8) — เขียนใหม่ 2026-09-22 แทนร่างเดิม "Document Set จัดชุดมือใน UI" (2026-09-17, commit 6940b38) ตามคำขอผู้ใช้: ให้ e-Court บอกกลุ่มผ่านลิงก์แทนการจัดชุดด้วยมือ
|
||||
> เพิ่มเติม (2026-09-23 ตามคำขอผู้ใช้): การ์ดไฟล์หน้า `/groups/[typeId]` หุบ/กางดู bookmark+annotation ทั้งไฟล์ (ปิด gap 5.3.10 ครึ่งหลังที่เคยเป็น out of scope) + ย่อข้อความหมายเหตุเหลือ "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้"
|
||||
> เลขฟีเจอร์: ร่างเดิม (2026-09-17) เคยใช้เลข N8 — ยกให้แผนลิงก์ e-Court (`docs/PLAN-ECOURT.md`) ซึ่งเป็น dependency ต้นทาง แผนนี้จึงเป็น **N9**
|
||||
> Dependency: **N8** — การรับ/refresh `typeId` เกิดที่ `registerExternalFile` ของ N8 ทั้งหมด (แผนนี้ไม่มี code path ที่เขียน `type_id` เอง) — **N8 implement ครบแล้ว (2026-09-22 รวม D5)**: schema `type_id` + index มากับ migration `drizzle/0002` ด้วย
|
||||
> ตาม governance ของโปรเจกต์: implement ต้องเขียนสเปกลง `docs/PLAN-FEAT.md` §7 (**N9**) + ขยาย whitelist ใน `CLAUDE.md` + อัปเดต `docs/PLAN.md` §3 (schema) ก่อน — เป็น task แรกของแผน แล้วรันผ่าน `/implement-feat N9`
|
||||
|
|
@ -9,13 +10,13 @@
|
|||
|
||||
- กรณีจริงของศาล: คดีหนึ่งงวด = หลายเอกสาร (คำฟ้อง / คำพิพากษา / คำสั่งศาล) — ผู้ใช้อยากเห็นเอกสารที่เกี่ยวเนื่องกันจัดกลุ่มมาแสดง และมีหน้ารวมทุกเอกสารของกลุ่ม
|
||||
- ร่างเดิม (2026-09-17) ออกแบบเป็นตาราง `document_sets` + ย้ายไฟล์เข้า/ออกด้วยมือใน UI — ผู้ใช้ตัดสินใจใหม่ (2026-09-22): ให้ e-Court ส่งรหัสกลุ่มมากับลิงก์ (`?typeId=` — เปลี่ยนชื่อจาก caseId ตามคำขอ) จึง**ไม่ต้องมีตารางแยก / Server Actions / UI จัดการกลุ่มเลย** เหลือแค่ column + การแสดงผล
|
||||
- ข้อจำกัดที่ยอมรับ (ผู้ใช้ยืนยัน 2026-09-22): ระบบเรารู้จักเฉพาะเอกสารที่เคยเปิดผ่านลิงก์ e-Court (row เกิดตอน `registerExternalFile`) — หน้ากลุ่มจึงแสดง**เฉพาะเอกสารที่รู้จักแล้ว** พร้อมหมายเหตุให้ผู้ใช้ทราบว่าอาจไม่ครบทุกฉบับของคดี (รายการครบทั้งคดีอยู่ใน e-Court ไม่ใช่ระบบเรา)
|
||||
- ข้อจำกัดที่ยอมรับ (ผู้ใช้ยืนยัน 2026-09-22): ระบบเรารู้จักเฉพาะเอกสารที่เคยเปิดผ่านลิงก์ e-Court (row เกิดตอน `registerExternalFile`) — หน้ากลุ่มจึงแสดง**เฉพาะเอกสารที่รู้จักแล้ว** พร้อมหมายเหตุกำกับว่า "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้" (รายการครบทั้งคดีอยู่ใน e-Court ไม่ใช่ระบบเรา — ข้อความเดิมยาวกว่า ย่อตามคำขอผู้ใช้ 2026-09-23)
|
||||
|
||||
## การตัดสินใจ (ยืนยันกับผู้ใช้แล้ว 2026-09-22)
|
||||
|
||||
1. **กลุ่มระดับเดียว กำหนดด้วย `typeId` จากลิงก์ e-Court** — เพิ่ม column บนตาราง `files` ค่าเดียว (`type_id` — ถอด `type_name` ตามคำขอผู้ใช้ 2026-09-22, แสดงผลด้วยรหัสกลุ่มโดยตรง) — ไม่มีตารางกลุ่มแยก ไม่มี many-to-many ไม่มีหลายระดับ (เอกสารหนึ่งอยู่กลุ่มเดียวตามธรรมชาติของงาน) — ความหมายของ id เป็นของ e-Court ฝั่งเราถือว่า "ส่งมาเหมือนกัน = กลุ่มเดียวกัน"
|
||||
2. **เข้ามาอัตโนมัติทั้งหมด ไม่มี UI จัดการกลุ่ม** — ไฟล์ได้กลุ่มเมื่อเปิดผ่านลิงก์ที่มี `typeId` (เขียนที่ N8) — กลุ่มเกิด/หายตามข้อมูลจริงใน `files` ไม่มีสถานะกลุ่มค้างในตารางอื่น
|
||||
3. **หน้ารายการ `/` จัดกลุ่มตาม `typeId`** (section ต่อกลุ่ม + ส่วน "ไม่มีกลุ่ม" ท้ายสุด) + **หน้าใหม่ `/groups/[typeId]`** แสดงเอกสารทั้งกลุ่มที่รู้จัก พร้อมหมายเหตุ "อาจไม่ครบทุกฉบับ"
|
||||
3. **หน้ารายการ `/` จัดกลุ่มตาม `typeId`** (section ต่อกลุ่ม + ส่วน "ไม่มีกลุ่ม" ท้ายสุด) + **หน้าใหม่ `/groups/[typeId]`** แสดงเอกสารทั้งกลุ่มที่รู้จัก พร้อมหมายเหตุ "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้" และการ์ดแต่ละไฟล์หุบ/กางดู bookmark+annotation ของไฟล์นั้นได้ (2026-09-23)
|
||||
|
||||
## Design
|
||||
|
||||
|
|
@ -45,8 +46,9 @@ Server component `force-dynamic` (login ถูกบังคับโดย `mi
|
|||
|
||||
- โหลด: `files where type_id = params.typeId` `orderBy createdAt` (Next decode dynamic param ให้อัตโนมัติ — **อย่าเรียก `decodeURIComponent` ซ้ำ** ตาม edge case #5) — **ไม่มี = 404** (กลุ่มที่ระบบไม่รู้จัก/ย้ายไฟล์ออกหมดแล้ว)
|
||||
- แสดง: หัวกลุ่ม (`type_id` + "N เอกสาร") + ลิงก์กลับ `/`
|
||||
- **หมายเหตุกำกับทุกครั้ง** (ผู้ใช้ยืนยัน): "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้ — อาจไม่ครบทุกฉบับของกลุ่ม" (กล่อง info ใต้หัวกลุ่ม)
|
||||
- รายการเอกสาร: ชื่อไฟล์ + วันที่นำเข้า (`formatThaiDate`) + จำนวน annotation/bookmark (query นับแยกด้วย `groupBy fileId` — 2 query เสริม ไม่ join หนัก) + ปุ่ม/ลิงก์ **Annotate → `/annotate/{fileId}`** (ไม่ต้อง deep link หน้า — เข้าไปเหมือนปกติ)
|
||||
- **หมายเหตุกำกับทุกครั้ง** (ผู้ใช้ยืนยัน): "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้" (กล่อง info ใต้หัวกลุ่ม — ย่อจากข้อความเดิม "… — อาจไม่ครบทุกฉบับของกลุ่ม" ตามคำขอผู้ใช้ 2026-09-23)
|
||||
- รายการเอกสาร: ชื่อไฟล์ + วันที่นำเข้า (`formatThaiDate`) + จำนวน annotation/bookmark + ปุ่ม/ลิงก์ **Annotate → `/annotate/{fileId}`** (ไม่ต้อง deep link หน้า — เข้าไปเหมือนปกติ)
|
||||
- **การ์ดแต่ละไฟล์หุบ/กางดู bookmark+annotation ทั้งไฟล์** (คำขอผู้ใช้ 2026-09-23 — แถบ summary เป็น en: "Annotations & Bookmarks (N)"): select รายการเต็ม 2 query (`inArray fileId` + `orderBy` หน้า — เดิมนับอย่างเดียวด้วย `groupBy`) แล้วจัดตามไฟล์ใน JS; รวมเป็นรายการเดียวเรียงตามหน้า (หน้าเดียวกันให้ที่คั่นหน้าก่อนหมายเหตุ — ไล่ตามตำแหน่งในเอกสาร); แต่ละแถว deep link เดียวกับหน้าสรุป F12 (`?ann=<id>` / `?page=N`) + รูปแบบแถว/ไอคอน/โน้ต/ป้าย "จัดการแล้ว"/"ใน: …" ของ sub bookmark ตามหน้าสรุป F15 + วันเวลาที่สร้าง (`formatThaiDate` withTime — คำขอผู้ใช้ 2026-09-23) ในบรรทัด meta ก่อน "โดย"; ใช้ `<details>` ล้วน ไม่มี client component; ไฟล์ที่ไม่มีรายการเลยไม่มีแถบหุบ/กาง
|
||||
- ไม่มี SSE (snapshot ณ ตอนโหลด เหมือนหน้าสรุป F15) ไม่มีปุ่มแก้ไข/ย้ายไฟล์ (จัดการที่ e-Court ฝั่งเดียว)
|
||||
- `generateMetadata` ตั้งชื่อแท็บ browser ตามชื่อกลุ่ม (pattern เดียวกับหน้าสรุป F15)
|
||||
|
||||
|
|
@ -64,7 +66,7 @@ Server component `force-dynamic` (login ถูกบังคับโดย `mi
|
|||
| `CLAUDE.md` | whitelist ฟีเจอร์เสริมหลังแผน เพิ่ม N9 + โครงสร้างไฟล์เพิ่ม `app/groups/[typeId]/page.tsx` |
|
||||
| `.claude/rules/data-layer.md` | เพิ่ม: `files.type_id` เขียนที่ N8 `registerExternalFile` เท่านั้น (ลิงก์ไม่ส่ง = คงเดิม) — ไม่มี action/SSE ใหม่ของ N9 |
|
||||
|
||||
- `docs/requirement/gap-analysis.md` 5.3.10 ครึ่งหลัง ("หรือชุดของเอกสาร") — **ยังไม่ปิด** ด้วยแผนนี้ (แผนนี้แสดง *เอกสาร* รวมกลุ่ม ไม่ใช่ *bookmark* รวมกลุ่มตาม requirement) — อย่าเปลี่ยนสถานะ
|
||||
- `docs/requirement/gap-analysis.md` 5.3.10 ครึ่งหลัง ("หรือชุดของเอกสาร") — เดิมแผนนี้ไม่ปิด (แสดงเฉพาะ *เอกสาร* รวมกลุ่ม) แต่**ปิดแล้ว 2026-09-23** ด้วยการหุบ/กางดู bookmark+annotation ต่อไฟล์บนหน้ากลุ่ม (D3)
|
||||
- `.claude/rules/realtime.md`, `pdf-viewer.md`, `coordinates.md` **ไม่แตะ**
|
||||
|
||||
## ลำดับ task + verify (ทุก task: `npx tsc --noEmit` ผ่าน)
|
||||
|
|
@ -93,7 +95,7 @@ Server component `force-dynamic` (login ถูกบังคับโดย `mi
|
|||
|
||||
- จัดกลุ่ม/แก้ชื่อ/ลบกลุ่มด้วยมือใน UI ของเรา (ทิ้งจากร่างเดิม — กลุ่มมาจาก e-Court อย่างเดียว)
|
||||
- ไฟล์อยู่หลายกลุ่ม (many-to-many) / กลุ่มซ้อนหลายระดับ
|
||||
- **bookmark รวมทั้งกลุ่ม** (ครึ่งหลังของ requirement 5.3.10 แบบร่างเดิม — น่าดึงกลับมาภายหลังได้เมื่อผู้ใช้ขอ)
|
||||
- ~~bookmark รวมทั้งกลุ่ม~~ — **ทำแล้ว (2026-09-23)**: การ์ดไฟล์หน้ากลุ่มหุบ/กางดู bookmark+annotation ต่อไฟล์ (D3)
|
||||
- export JSON ตามกลุ่ม (N7 ยังรับ `fileId` เดียว)
|
||||
- API ดึงข้อมูลให้ระบบภายนอก = **N10** `docs/PLAN-API.md` (แผนแยก)
|
||||
- รายการเอกสารครบทุกฉบับของคดีรวมฉบับที่ยังไม่เคยเปิด (ข้อมูลอยู่ที่ e-Court)
|
||||
|
|
@ -101,7 +103,8 @@ Server component `force-dynamic` (login ถูกบังคับโดย `mi
|
|||
## Verification (ภาพรวม end-to-end — หลัง N8 เสร็จ)
|
||||
|
||||
1. `npm run dev` → login → เปิดลิงก์ e-Court 2 ไฟล์ที่ `typeId` เดียวกัน + 1 ไฟล์ `typeId` ต่างกลุ่ม → หน้า `/` จัด 2 section ตามกลุ่ม + section "ไม่มีกลุ่ม" (ไฟล์ seed/อัปโหลด)
|
||||
2. หัวกลุ่ม → "เอกสารในกลุ่ม" → `/groups/[typeId]`: เห็นไฟล์ครบตามลำดับ + หมายเหตุ "อาจไม่ครบทุกฉบับ" + จำนวน annotation/bookmark ต่อไฟล์
|
||||
3. กด Annotate → เข้า viewer ของไฟล์นั้นได้ตามปกติ
|
||||
4. เปิดลิงก์รอบใหม่ของไฟล์เดิมด้วย `typeId` คนละค่า → ไฟล์ย้ายกลุ่ม กลุ่มเดิมลดจำนวน/หายไปเมื่อว่าง
|
||||
5. Regression: อัปโหลด N4 / annotate / ค้นหา N6 / export JSON N7 ยังทำงานเหมือนเดิม
|
||||
2. หัวกลุ่ม → "เอกสารในกลุ่ม" → `/groups/[typeId]`: เห็นไฟล์ครบตามลำดับ + หมายเหตุ "แสดงเฉพาะเอกสารที่เคยเปิดในระบบนี้" + จำนวน annotation/bookmark ต่อไฟล์
|
||||
3. กาง "Annotations & Bookmarks (N)" ในการ์ดไฟล์ → เห็น bookmark+annotation ทั้งไฟล์เรียงตามหน้า + กดแถวแต่ละรายการเด้งไปตำแหน่งนั้นใน viewer (`?ann=` / `?page=`)
|
||||
4. กด Annotate → เข้า viewer ของไฟล์นั้นได้ตามปกติ
|
||||
5. เปิดลิงก์รอบใหม่ของไฟล์เดิมด้วย `typeId` คนละค่า → ไฟล์ย้ายกลุ่ม กลุ่มเดิมลดจำนวน/หายไปเมื่อว่าง
|
||||
6. Regression: อัปโหลด N4 / annotate / ค้นหา N6 / export JSON N7 ยังทำงานเหมือนเดิม
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue