Tracker: เว็บติดตามความคืบหน้างาน
เครื่องมือภายในของทีมสำหรับติดตามความคืบหน้างานในโครงการ TNSU EMS ไม่ได้เป็นส่วนหนึ่งของระบบ TNSU EMS ที่ส่งมอบให้มหาวิทยาลัย และไม่ต้องทำตาม tech stack ของโครงการ
- Server-side rendering: Go render ทุกหน้าด้วย
html/templateเปิดได้แม้ปิด JavaScript - Real-time: server ตรวจไฟล์ใน
data/ทุก 1 วินาที เมื่อมีการเปลี่ยนจะส่ง Server-Sent Events (/events) ให้เบราว์เซอร์ แล้วเบราว์เซอร์ดึงหน้าที่ render ใหม่จาก server มาแทนเนื้อหาเดิมโดยไม่ reload - Dark mode: ตามระบบปฏิบัติการเป็นค่าเริ่มต้น เลือก "สว่าง" หรือ "มืด" ได้ที่ปุ่มด้านล่างเมนู และเบราว์เซอร์จะจำค่าไว้
- Animation: segment ที่เป็น In Progress มีแสงวิ่ง และ Wait for review มีลายเลื่อน ถ้าระบบตั้ง "ลดการเคลื่อนไหว" จะหยุดนิ่ง
- Markdown: ข้อความใน review (สิ่งที่ต้องตรวจ, checklist, ผลการรีวิว) เขียนเป็น markdown ได้ ระบบ escape HTML และรับเฉพาะลิงก์ http/https/relative
- ใช้แค่ Go standard library ไม่มี dependency
เมนู
| เมนู | Path | ข้อมูลมาจาก |
|---|---|---|
| หน้าภาพรวม | / | จำนวน Task / Review / Checkpoint, milestone แบบหลอด segment, Current Task |
| Milestone & Tasks | /milestones → /milestones/{milestone} → /milestones/{milestone}/{epic} → /tasks/{task} | data/milestones.json (หน้าย่อยตามลำดับชั้น มี breadcrumb) |
| Use cases | /use-cases → /use-cases/{W-id} | ตารางค้นหาจาก Use cases ต้นฉบับ และ workflow diagram ที่แก้ไขร่วมกันได้ |
| Timeline | /timeline?scale=hour|day|week | Gantt chart: Milestone › Epic › Task ฝั่งซ้าย แถบเวลาฝั่งขวา จาก started / finished (ทำจริง) และ start / due (แผน) |
| ประวัติ Checkpoint | /checkpoints | data/checkpoints.json บันทึกสรุปที่ Agent เขียนหลังทำงาน |
| ผลตรวจ Test | /tests, /tests?view=ba, /tests?view=tech | data/tests.json จัดกลุ่มตามหัวข้อ แยกมุมมอง BA / Technical |
| Problem solving | /problems | data/problems.json |
| Wait for review | /reviews?state=todo|rejected|hold|done | task ที่มี review แยก tab ตามสถานะการรีวิว |
วิธีรัน
cd tracker
go run . # เปิด http://localhost:8099| Flag | ค่าเริ่มต้น | ความหมาย |
|---|---|---|
-addr | :8099 | address ที่ฟัง |
-data | data | โฟลเดอร์ไฟล์ JSON |
-poll | 1s | ความถี่ตรวจการเปลี่ยนแปลง |
-root | .. | โฟลเดอร์ repo ที่ตัวเปิดไฟล์ /files/ อ่านได้ |
ถ้าวางหลัง reverse proxy ต้องปิด buffering ของ /events server ส่ง header X-Accel-Buffering: no ไว้ให้แล้ว (สำหรับ nginx)
Timeline
- เลือกระดับเวลา ชั่วโมง / วัน / สัปดาห์ ที่ tab ด้านบน ปุ่ม ไปที่ตอนนี้ เลื่อนไปที่เส้นเวลาปัจจุบัน (เส้นสีทอง)
- คอลัมน์ซ้ายย่อ/ขยาย Milestone และ Epic ได้ browser จำไว้ให้ คอลัมน์ซ้ายค้างไว้ตอนเลื่อน chart
- หน้านี้ใช้ความกว้างถึงขอบ browser และ chart ยืดเต็มพื้นที่ (ตำแหน่งแถบเป็น % ของ chart) ถ้าช่วงเวลายาวเกินจอจะเลื่อนแนวนอนได้
- ลากเส้นแบ่งระหว่างรายละเอียดกับ chart (ที่หัวตารางหรือขอบแถวใดก็ได้) เพื่อปรับความกว้าง หรือ focus ที่หัวตารางแล้วกดลูกศรซ้าย/ขวา (Shift = ทีละมาก, Home = ค่าเดิม) browser จำไว้ให้
- แถบของ task: ทึบ = ทำจริง (
started→finishedหรือถึงตอนนี้ถ้ายังทำอยู่/รอรีวิว), กรอบเส้นประ = แผน (start→due) สีตามสถานะ - แถบของ Epic / Milestone ครอบช่วงของงานข้างใน พร้อมสัดส่วนที่เสร็จ ◆ สีทองคือ
targetของ milestone - ค่าที่เป็นวันที่อย่างเดียวนับเป็นทั้งวัน ในมุมมองชั่วโมงจึงเห็นเต็มวัน ใส่วันเวลาแบบ RFC 3339 เพื่อให้แม่นยำ
- มุมมองชั่วโมงแสดงได้สูงสุด 21 วันรอบตอนนี้ (กันหน้าเว็บหนักเกินไป)
Review form (บันทึกผลรีวิวจากหน้าเว็บ)
ทุกงานในหน้า Wait for review และหน้า Task มีฟอร์มให้ผู้รีวิว:
- ติ๊ก Checklist ขั้นที่ทำแล้ว
- เลือก Approve, Reject หรือ Hold
- เขียนรายละเอียดผลรีวิว (Markdown ได้ บังคับเมื่อ Reject หรือ Hold)
- ใส่ชื่อผู้รีวิว (browser จำไว้ให้) แล้วกด บันทึกผลการรีวิว
| ผล | review.state | task.status |
|---|---|---|
| Approve | done | reviewed (ใส่วันที่ finished ถ้ายังว่าง) |
| Reject | rejected | in_progress (ขึ้นใน Current Task) |
| Hold | hold | review |
- ผลบันทึกลง
data/milestones.jsonใต้reviewของ task นั้น (state,decision,decided_at,decided_by,checklist[].done) และต่อท้ายในreview.historyทุกครั้ง Agent อ่านผลจากไฟล์นี้ - Server แก้เฉพาะ field ที่เกี่ยวข้อง คงลำดับ key และ field อื่นไว้ (diff ใน git จะเล็ก) และเขียนแบบ atomic (ไฟล์ชั่วคราวแล้ว rename)
- ระหว่างพิมพ์ในฟอร์ม Live update จะไม่ทับข้อความ (แสดงว่ามีข้อมูลใหม่รออยู่แทน)
- เฉพาะ tab ที่เปิดดูอยู่ที่เชื่อมต่อ Live update (browser ให้ราว 6 การเชื่อมต่อต่อเว็บ) tab ที่ซ่อนอยู่จะต่อใหม่และดึงข้อมูลล่าสุดเมื่อกลับมาดู
- CSS/JS ลิงก์แบบ
?v=<hash>browser จึง cache ได้ และได้ไฟล์ใหม่เองหลัง build ใหม่ (แก้ไฟล์ในstatic/หรือtemplates/ต้อง build และ restart server ส่วนแก้data/*.jsonไม่ต้อง) - Security: รับเฉพาะ POST ที่มาจากหน้าเว็บของ tracker เอง (ตรวจ
Origin/Refererกัน CSRF) จำกัดขนาดฟอร์ม 64 KB ไม่มีระบบ login ทุกคนที่เข้า tracker ได้ (รวมถึงผ่าน Tailscale) บันทึกผลรีวิวได้
เปิดไฟล์แนบ (refs) ในแท็บใหม่
ไฟล์และโฟลเดอร์ใน refs และ path ที่เขียนใน code ในข้อความรีวิว กดเปิดในแท็บใหม่ได้ ที่ /files/<path>:
.mdแสดงเป็นหน้า HTML อ่านง่าย: สารบัญด้านข้าง, ตาราง (หัวตารางค้างไว้), ช่องค้นหาที่กรองแถวในตาราง, diagram mermaid และ anchor ของหัวข้อ- ไฟล์ข้อความและโค้ดแสดงตามต้นฉบับ, ภาพแสดงเป็นภาพ, โฟลเดอร์แสดงรายการไฟล์,
?raw=1เปิดไฟล์ต้นฉบับ - อ่านจากไฟล์ใน repo บนเครื่องโดยตรง จึงเป็นเวอร์ชันล่าสุดเสมอ (
-rootกำหนดโฟลเดอร์ repo ค่าเริ่มต้นคือ..) - เปิดได้เฉพาะไฟล์ใน repo ห้ามออกนอก repo (รวม
../และ symlink) และไม่แสดง.gitไฟล์ซ่อน หรือไฟล์ key
เข้าถึงจาก Tailscale
scripts/tailscale.sh on # เปิดให้เครื่องใน tailnet เข้าได้
scripts/tailscale.sh status # ดูการตั้งค่าและ URL
scripts/tailscale.sh off # ปิด- เข้าได้ที่
http://<Tailscale IP ของเครื่อง>:8099/ตอนนี้คือhttp://100.73.238.43:8099/(เครื่องthanapat-pc-personal) - ใช้
tailscale serve --tcpส่งต่อแบบ TCP ตรง ๆ ไม่ใช้ HTTP serve เพราะ HTTP serve เลือกปลายทางตามชื่อ host และตอบเฉพาะชื่อ MagicDNS ซึ่งปิดอยู่ใน tailnet นี้ ส่วนแบบ TCP ตอบผ่าน IP ได้ และส่งการอัปเดตสด (SSE) ผ่านไปโดยไม่ถูก buffer - สคริปต์ใช้
tailscale.exeฝั่ง Windows อัตโนมัติ (หรือtailscaleถ้าติดตั้งใน WSL) WSL2 แบบ NAT ส่งต่อพอร์ตให้ Windows ทางlocalhostซึ่งบนเครื่องนี้ฟังเฉพาะ IPv6::1เลยต้องตั้งปลายทางเป็นlocalhostไม่ใช่127.0.0.1 - การตั้งค่า serve อยู่บน Tailscale และคงอยู่หลังรีสตาร์ต แต่ tracker ต้องรันอยู่ ถึงจะเข้าได้
- ทุกเครื่องใน tailnet ที่ ACL อนุญาตเข้าได้ และบันทึก review / diagram ผ่านเว็บได้ (ไม่มี login)
การอัปเดตข้อมูล (สำหรับคนและ Agent)
แก้ไฟล์ใน data/ แล้วบันทึก ทุกหน้าที่เปิดอยู่จะอัปเดตเองภายใน 1–2 วินาที ถ้า JSON ผิดรูปแบบ หน้าเว็บจะแสดงข้อความแจ้งพร้อมแสดงข้อมูลชุดก่อนหน้าไว้ให้
milestones.json
โครงสร้างเป็น Milestone → Epic → Task
- Milestone 0 คืองานเตรียมความพร้อมก่อนเริ่มงานจริง (discovery, ออกแบบเบื้องต้น, เครื่องมือของทีม)
- Milestone 1, 2, 3, … คืองานพัฒนาระบบจริง เพิ่มเมื่อจัดหมวดหมู่เสร็จ (ดู epic
prep-real-plan) - รหัส Epic สร้างให้อัตโนมัติจากเลข milestone และลำดับ เช่น
E0.3= epic ลำดับที่ 3 ของ Milestone 0
[
{
"id": "m1-platform-core", // ใช้เป็น anchor: /milestones#m1-platform-core
"no": 1, // เลขลู่ที่แสดง (Milestone 1)
"title": "Platform core",
"goal": "…", // ไม่บังคับ
"target": "2027-01-31", // ไม่บังคับ (YYYY-MM-DD)
"epics": [
{
"id": "m1-iam", // anchor ของ epic และใช้อ้างจาก problems.json
"title": "IAM และสิทธิ์ผู้ใช้",
"goal": "…",
"tasks": [
{
"id": "T-1001", // id ต้องไม่ซ้ำกันทั้งไฟล์ (milestone, epic, task)
"title": "…",
"status": "in_progress", // todo | in_progress | done | review | reviewed
"owner": "Claude",
"started": "2026-11-01T09:30:00+07:00", // วันที่ หรือวันเวลา (RFC 3339) ใส่เวลาด้วยเพื่อให้ Timeline รายชั่วโมงแม่นยำ
"finished": "",
"start": "2026-11-01", // แผน: วันเริ่ม (ไม่บังคับ)
"due": "2026-11-05", // แผน: วันกำหนดเสร็จ (ไม่บังคับ) แสดงเป็นกรอบเส้นประใน Timeline
"summary": "…",
"refs": ["docs/…"],
"steps": [ // แสดงใน Current Task: ส่วนที่คืบหน้าแล้ว / ส่วนที่เหลือก่อนปิด Task
{ "text": "…", "done": true },
{ "text": "…", "done": false }
],
"review": { // ใส่เมื่อส่งรีวิว
"reviewer": "BA",
"requested_at": "2026-11-05",
"state": "todo", // todo | rejected | hold | done
"focus": "สิ่งที่ต้องตรวจ (**markdown** ได้)",
"checklist": [ // ขั้นตอนที่ผู้รีวิวต้องทำ แสดงเป็น 1, 2, 3, … (markdown ได้)
{ "text": "เปิด `docs/agent/13-role-matrix.md` แล้วตรวจ…", "done": false }
],
"decision": "", // ผลการรีวิวหรือเหตุผลที่ตีกลับ / พักไว้ (markdown)
"decided_at": ""
}
}
]
}
]
}
]- ลำดับ milestone ในไฟล์ = ลำดับลู่บนหน้าภาพรวม ลำดับ epic = ลำดับกลุ่มในหลอด และลำดับ task = ลำดับ segment
- task ที่
in_progressขึ้นใน Current Task ควรมีstepsเสมอ เพื่อให้เห็นงานที่เหลือก่อนปิด - ส่ง task ไปรีวิว: เปลี่ยน
statusเป็นreviewและใส่reviewพร้อมchecklistที่บอกผู้รีวิวเป็นขั้นตอน - ผลการรีวิวใช้ Review form บนหน้าเว็บ (ไม่ต้องแก้ไฟล์เอง)
สถานะของ task
| status | ความหมาย | ใครตั้ง |
|---|---|---|
todo | ยังไม่เริ่ม | Agent / คน |
in_progress | กำลังทำ (ขึ้นใน Current Task) | Agent |
done | Agent ทำเสร็จและทดสอบผ่านครบแล้ว ยังไม่มีคนตรวจ | Agent |
review | ส่งให้คนตรวจแล้ว รอผล (Wait for review) | Agent |
reviewed | ผู้รีวิวกด Approve แล้ว สถานะสุดท้าย | Review form เท่านั้น |
ความคืบหน้า (%) นับทั้ง done และ reviewed เป็นงานที่เสร็จ
checkpoints.json
บันทึกสรุปที่ Agent (หรือคน) เขียนหลังทำงานแต่ละช่วง ระบบเรียงจากล่าสุดให้เอง
[{ "id": "C-014", "at": "2026-10-31T10:30:00+07:00", "agent": "Claude Code (Opus 5.5)",
"title": "สรุปสั้น ๆ ว่าทำอะไร",
"summary": "ทำอะไรและทำไม 1–3 ประโยค",
"changes": ["สิ่งที่สร้าง แก้ไข หรืออัปเดต ทีละข้อ"],
"tasks": ["T-403"], "refs": ["tracker/README.md"], "commit": "abc1234" }]commit ไม่บังคับ ใส่ไว้อ้างอิงเท่านั้น
tests.json
เรียงจากล่าสุดไว้บนสุด เขียน summary และ groups ให้คนอ่านเข้าใจ ส่วนตัวเลขดิบและคำสั่งเป็นรายละเอียดสำหรับ Technical
[{ "id": "R-007", "suite": "ชื่อรอบทดสอบ", "date": "2026-10-31",
"summary": "รอบนี้ตรวจอะไรและผลเป็นอย่างไร เป็นภาษาคน",
"groups": [
{ "name": "การนับและสรุปความคืบหน้า", "audience": "ba",
"purpose": "ทำไมหัวข้อนี้สำคัญ",
"cases": [ { "name": "นับจำนวน task แต่ละสถานะถูกต้อง", "status": "pass", "detail": "" } ] }
],
"command": "go test ./...", "passed": 19, "failed": 0, "skipped": 0, "duration": "0.5s",
"notes": "", "failures": [] }]audience:ba(เรื่องที่ BA ตรวจได้),tech(เรื่องเทคนิค),bothstatusของแต่ละข้อ:pass,fail,skipข้อที่failทำให้ทั้งรอบแสดงเป็น "ไม่ผ่าน"- ตั้งชื่อข้อเป็นประโยคว่าตรวจอะไร ไม่ใช่ชื่อฟังก์ชันทดสอบ
problems.json
[{ "id": "P-007", "title": "…", "date": "2026-10-31", "status": "open",
"symptom": "…", "cause": "…", "solution": "…",
"epic": "prep-data-model", "refs": ["…"] }]status เป็น open หรือ solved และ epic คือ id ของ epic ที่ปัญหาเกิด
ทดสอบ
go test ./... # unit + render + SSE
node e2e/live-check.mjs <path-to-chrome> data/milestones.json # อัปเดตสดในเบราว์เซอร์จริง (ต้องรัน tracker ที่ :8099 ก่อน)
node e2e/theme-check.mjs <path-to-chrome> <screenshot-dir> # ธีมสว่าง/มืด/ตามระบบ และการจำค่า
node e2e/timeline-check.mjs <chrome> <base-url> <screenshot-dir> # Timeline เต็มจอ และลากเส้นแบ่งรายละเอียด / chart
node e2e/review-check.mjs <chrome> <base-url> <copy>/milestones.json <task-id> # Review form (ใช้กับข้อมูลชุดสำเนาเท่านั้น เพราะบันทึกผลจริง)สคริปต์ e2e เพิ่ม task ชั่วคราวในไฟล์ข้อมูล ตรวจว่าหน้าที่เปิดอยู่อัปเดตเองโดยไม่ reload แล้วคืนไฟล์เป็นเหมือนเดิม
Use cases และ Workflow diagram
เปิด /use-cases จากเมนู Use cases: ตารางรหัส ชื่อ Module ผู้เกี่ยวข้อง และจำนวนขั้นตอน ค้นหาข้อความหรือกรองตาม Module / ผู้เกี่ยวข้อง แล้วกดชื่อหรือ เปิด diagram เพื่อดูรายละเอียด (/use-cases/W-49 เป็นต้น)
- อ่านข้อมูลจาก
use_cases/UC1-Explorer.dc.htmlโดยตรง ตาม-rootจึงใช้ actors, จุดเริ่มต้น, ผลลัพธ์, ขั้นตอน, ความสัมพันธ์ และหน้าจอจากแหล่งเดิม โดยไม่แก้เอกสาร generated - Diagram เริ่มต้นเป็น workflow ฉบับร่าง: start → ขั้นตอนตามลำดับ → end ไม่ใช่ UML actor/use-case diagram ที่ผ่านการรับรอง และไม่เดาเงื่อนไข decision จากข้อความ
- เพิ่ม shape Start / End / Process / Decision; ลากจัดตำแหน่งตามกริด 20 หน่วย; เลือกเพื่อแก้ Title / Description / Type; ใช้ลูกศรบนแป้นพิมพ์ย้าย shape ได้เมื่อ focus อยู่ที่ shape
- ลากจุดวงกลมด้านขวาของ shape ไปปล่อยบนอีก shape เพื่อสร้างเส้น หรือกด เชื่อม shape แล้วเลือกต้นทางและปลายทาง (ใช้ Enter ได้)
- เส้นเชื่อมเดินเป็นแนวนอน/แนวตั้ง หักมุม 90° และปรับเส้นอัตโนมัติตามตำแหน่ง shape (รวมเส้นขณะกำลังลาก) กริดใน SVG ซูมและเลื่อนไปพร้อมเนื้อหา
- เลือกเส้นเพื่อแก้ข้อความ ต้นทาง ปลายทาง และหัวลูกศรทั้งสองด้าน: ไม่มี / ลูกศรทึบ / ลูกศรโปร่ง / ข้าวหลามตัด รองรับเส้นวนกลับและเชื่อมกลับเข้าตัวเอง
- ลบ shape จะลบเส้นที่เกี่ยวข้องด้วย; ย้อนกลับ / ทำซ้ำ คืนการเปลี่ยนแปลงได้; เปิดหน้าแล้วจัดเนื้อหากึ่งกลางและ Fit ทั้งหมด อัตโนมัติ; เลือกซูม 10–150%, ลากพื้นที่ว่างหรือเลื่อนเพื่อ pan และกด พอดีทั้งหมด เพื่อกลับมาดูภาพรวม
- บันทึกส่วนกลาง เขียน JSON แยกราย Use case ใน
data/diagrams/W-*.json(หรือใต้-dataที่กำหนด) ผ่านPUT /api/use-cases/{id}/diagram; GET URL เดียวกันอ่าน diagram ถ้ายังไม่เคยบันทึกจะได้ร่างจากต้นฉบับ - เขียนไฟล์แบบ atomic และตรวจ revision ภายใต้ mutex: หากอีกคนบันทึกก่อน จะตอบ 409 โดยเก็บงานในหน้าจอไว้ ใช้ ส่งออก JSON สำรองงานก่อน โหลดเวอร์ชันล่าสุด แล้วนำการแก้ไขที่ต้องการมาใช้ใหม่ ขณะนี้ยังไม่มีระบบ merge หรือ import JSON
- Live update จะไม่แทนที่หน้า editor เพื่อรักษาตำแหน่งและการแก้ไข ใช้ โหลดเวอร์ชันล่าสุด เพื่ออ่าน diagram ที่คนอื่นบันทึก มีการเตือนก่อนออกจากหน้าที่ยังไม่บันทึก
- คืนร่างจากขั้นตอน คืน diagram ตามต้นฉบับปัจจุบันในหน้าจอเท่านั้น ต้องกดบันทึกจึงเปลี่ยนส่วนกลาง การแก้ต้นฉบับไม่ทับ diagram ที่บันทึกแล้วอัตโนมัติ
- ใช้ trust model เดียวกับ review form: ไม่มี login ผู้ที่เข้า tracker ได้สามารถแก้ diagram ได้ ตรวจ same-origin, ขนาด JSON ไม่เกิน 2 MB, 500 shapes / 2,000 เส้น, ประเภท พิกัด รหัสซ้ำ และปลายเส้น
ทดสอบ browser ด้วย ข้อมูลสำเนาชั่วคราวเท่านั้น เพราะชุดทดสอบบันทึก diagram จริง (เริ่มด้วยโฟลเดอร์ diagrams/ ว่าง):
node e2e/usecases-check.mjs <chrome-or-headless-shell> http://127.0.0.1:8101 /tmp/screenshots <path-to-existing-playwright/index.mjs> /tmp/tracker-test-dataใช้ Playwright ที่ติดตั้งอยู่แล้ว โดยไม่เพิ่ม dependency ให้ tracker ตัวเลือกท้ายสุดใช้ทดสอบ SSE จริงและรับเฉพาะโฟลเดอร์ใต้ /tmp/
การปรับการอ่านและจัดกลุ่ม Use cases
- ตารางไม่จำกัดความสูง ใช้ scroll หลักของหน้า
- แท็บ ทั้งหมด / Frontend ผู้ใช้ภายนอก / Backoffice ผู้ใช้ภายใน / Integration ระหว่างระบบ ใช้ร่วมกับคำค้น Module และ actor ได้ จำนวนในแท็บนับหลังใช้ตัวกรองเหล่านี้
- เป็นการจัดกลุ่ม เบื้องต้น: actor ภายนอก/ภายในอ้างอิงบทบาทใน
docs/agent/04-roles-and-access.md; เจ้าของข้อมูลอาจเป็นได้ทั้งสองกลุ่ม; Integration ต้องพบชื่อระบบภายนอกที่ระบุในต้นฉบับ เช่น ThaID, ธนาคาร, LINE, LMS หรือ DSL ไม่ได้จัดว่าเป็น Integration เพียงเพราะมีขั้นตอนของ “ระบบ” - Use case เดียวอยู่หลายแท็บได้ ป้ายกลุ่มในตารางมี tooltip แสดงเหตุผล เกณฑ์อยู่ใน
usecase_channels.goการติดป้ายไม่ได้ยืนยันว่าต้องมีหน้าจอหรือ API ใด - Ctrl + scroll ขึ้น/ลง ขณะ hover บน canvas ซูมเข้า/ออกตามตำแหน่งเมาส์ (1–300%); เลื่อนโดยไม่กด Ctrl ยังคง pan และปุ่มพอดีทั้งหมดคืนภาพรวม การซูมไม่ทำให้ diagram มีสถานะยังไม่บันทึก
- Title และ Description แสดงครบ ตัดบรรทัดตามความกว้างด้วยการแบ่งคำและกลุ่มตัวอักษรภาษาไทย พร้อมขยาย shape อัตโนมัติ ไม่ตัดข้อความด้วยจุดไข่ปลา ร่างใหม่และ reset วางขั้นตอนเว้นช่องตามความสูงจริง ส่วน diagram ที่เคยบันทึกจะรักษาตำแหน่งที่ผู้ใช้จัดไว้
- หน้าภาพรวมเรียง Current Task ไว้เหนือ Milestone ทั้งหมด
Horizontal layout, revisions and development approval
- New and reset diagrams flow left to right, with shapes vertically centered and spaced using their actual text height. Existing saved positions remain unchanged until the user chooses Arrange horizontally. This action preserves all shapes/connections, supports Undo, and is committed with Save diagram.
- The English toolbar groups Shapes / Edit / View. More contains Export JSON, Reload saved diagram and Reset to source steps. Reset changes the local draft; Restore in history immediately creates a new saved revision after confirmation.
- The catalog groups rows by Module with full names. Click a module header or use Expand all / Collapse all; the browser remembers collapsed modules through reload and live updates. Tabs/search/module/actor filters still work together.
- Revision history retains each saved diagram snapshot, timestamp and action. View JSON exposes the exact snapshot. Restore copies an older snapshot into a new revision, preserving all later history. Concurrent/stale restores return 409 and retain local edits. Unsaved changes are replaced only after the user confirms Restore.
- Current diagram, revision snapshots and approval events are committed atomically in the same
data/diagrams/W-*.jsonfile. Existing files without history remain readable: the previously saved revision is preserved on the next write, with an honest “Existing save” label when its original timestamp is unknown. Snapshots before history was introduced cannot be reconstructed. - Development approval records reviewer, timestamp, note, source fingerprint and exact diagram revision/content hash. The reviewer must enter their name, check the confirmation and choose Approve use case. An initial draft is saved first so the approved layout has a stored snapshot. Unsaved edits must be saved before approval.
- The table shows Not approved / Approved / Needs reapproval / Unavailable. Saving any new revision, restoring a version, or changing authoritative use-case content invalidates the prior approval. The approval audit trail is retained. Approval is a separate human decision from task completion/review and from preliminary Frontend/Backoffice/Integration tags.
- Agent product implementation must check the live approval status (
approved: true); seeAGENTS.md. The editor has the same internal trust model as task reviews: no login, so reviewer names are recorded declarations rather than authenticated identities. - History covers diagram snapshots; it does not overwrite the read-only explorer source. Source correctness is tracked by approval fingerprints. Restore cannot make an old approval current again.
| API | Purpose |
|---|---|
GET /api/use-cases/{id}/revisions | Snapshot metadata, oldest first |
GET /api/use-cases/{id}/revisions/{revision} | Exact saved diagram and action metadata |
POST /api/use-cases/{id}/restore | { "revision": current, "target_revision": old } → new current revision |
GET /api/use-cases/{id}/approval | Current validity, source hash, reviewer details and approval history |
POST /api/use-cases/{id}/approval | { "revision": current, "source_hash": pageSourceHash, "reviewer": "…", "note": "…", "confirmed": true } |
POST actions require the same Origin/Referer as the tracker. The approval source hash must match the version the reviewer actually loaded; source changes return 409 rather than approving unseen changes. GET endpoints never create approvals or snapshots.
PNG export และ review panels
เลือก More → Export PNG… แล้วเลือก White หรือ Transparent ก่อนกด Download PNG ภาพรวมทุก shape/ข้อความ/เส้นเชื่อมตามขอบเขต diagram จริง ไม่ขึ้นกับ zoom/pan ไม่รวมกริด จุดลาก หรือกรอบเลือก ใช้สีของธีมปัจจุบัน พื้นหลัง Transparent โปร่งใสเฉพาะพื้นที่ว่างและคงสีภายใน shape ไว้ ปกติส่งออกที่ 2× และลดขนาดอัตโนมัติเมื่อเกิน 16,384 pixels ต่อด้านหรือ 16 ล้าน pixels รวม ขนาดไฟล์แสดงหลังส่งออก
Development approval และ Revision history เป็นการ์ดแยก วันเวลาแสดงตาม Asia/Bangkok / พ.ศ. หลัง Approve จะแสดงข้อมูลผู้ตรวจและหมายเหตุแทนฟอร์มว่าง ประวัติมี Current revision, loading/empty/error state และไม่ทิ้งข้อมูลเดิมเมื่อ Refresh ล้มเหลว
Task brief และคำถามที่ต้องการข้อมูล
หน้า /tasks/{id} แสดงข้อมูลเพิ่มเติมที่เลือกใส่ได้:
description: Markdown อธิบายเป้าหมาย วิธีดำเนินการ และขอบเขตdeliverables: รายการผลลัพธ์ที่ต้องส่งมอบdependencies: task IDs ที่ใช้เป็นข้อมูลประกอบ (กดเปิดได้)suggested_owner: บทบาทผู้รับผิดชอบที่เสนอ โดยไม่ถือว่าได้รับมอบหมายแล้วquestions:{ "id": "T303-Q1", "asked_of": "ผู้ที่ควรตอบ", "question": "คำถาม", "why": "คำตอบมีผลอย่างไร", "state": "open" }- เมื่อได้คำตอบ เพิ่ม
answer,answered_by,answered_at(RFC 3339) และsourceแล้วตั้งstate: "answered"โดยคงรหัสคำถามเดิม
ตอบคำถามในแชตโดยระบุ ID หรือให้ทีมอัปเดตไฟล์ข้อมูลตามหลักฐาน ปัจจุบันส่วนนี้แสดงผลคำถาม/คำตอบ ยังไม่มีฟอร์มตอบคำถามผ่านเว็บ การเติม brief ไม่เปลี่ยน todo เป็น done และไม่อนุมัติข้อเสนอให้เอง ดู docs/agent/15-preparation-task-briefs.md
Canonical workflow review (2026-10-31)
The explorer JSON may include review (date/state/note) and wf metadata. wf.decisions inserts a gate before a 1-based source step, with labelled branches to a step or distinct outcome. A branch targeting its own step enters that process directly; other targets enter any gate before that step. wf.next overrides a step successor (including resubmission loops), and wf.stop terminates a non-success route separately. See workflow.go and the full BA review.
The renderer and Reset to source share the same canonical draft. Source metadata participates in approval fingerprints. Existing saved diagrams are preserved and must be reconciled deliberately after source changes. Initial branch drafts use separate rows with fit-to-view; routes try an outer orthogonal lane when the direct route crosses another shape. This is an internal editor, not a workflow execution engine.
Branch regression: node e2e/workflow-review-check.mjs <chrome> <temporary-server-url> <shots-dir> <playwright-module-path> (writes to temporary server data only).
Mockup workspace
เมนู /mockup มี Sitemap (ภาพหน้าจอเรียงบนลงล่าง), Page flow (/mockup/page-flow/{W-ID} ตาม canonical steps/decisions เรียงซ้ายไปขวา) และ Screen Listing/detail ข้อมูลตั้งต้นเป็น 164 รหัสหน้าจอ + 6 ภาพ reference; wireframes/mappings เป็นร่างตาม คู่มือ artifacts
หน้าจอ/variants/components เก็บใต้ mockups/ ที่ repo root ส่วน graph ที่แก้ร่วมกันเก็บใน <-data>/mockups/graphs/ แบบ atomic พร้อม revision history/restore และ conflict check ตัวกรอง Sitemap เปลี่ยนเฉพาะมุมมอง ไม่ลบ hidden screens ตอนบันทึก Source เปลี่ยนจะแจ้ง stale notice โดยยังเก็บ graph เดิมไว้ การแก้ Mockup ไม่ให้ Development Approval โดยอัตโนมัติ
ตรวจ artifacts: python3 mockups/tools/build_catalog.py --check จาก repo root ทดสอบ browser: node e2e/mockups-check.mjs <chrome> <temporary-server-url> <shots-dir> <playwright-module-path> <temporary-data-dir> ใช้ข้อมูลชั่วคราวเท่านั้น
Mockup/UI แสดงชื่อ Module เต็มจาก catalog mapping; Page flow index มี module folding พร้อมจำสถานะแยกจาก Use cases ทดสอบ e2e/module-groups-check.mjs (ชื่อ Module/การหุบ/ค้นหา) และ e2e/mockup-contrast-check.mjs (คู่สี explicit/OS light/dark) ใช้ arguments <chrome> <base-url> <shots-dir> <playwright-module-path> ทั้งสองชุดไม่กดบันทึก graph ส่วนกลาง