ความคืบหน้างาน ไฟล์ต้นฉบับ

tracker/data/problems.json

[
  {
    "id": "P-014",
    "title": "Sitemap จำนวนมากกว้างเป็นแถบเดียวเมื่อ navigation มีวงจร",
    "date": "2026-10-31T11:21:44+07:00",
    "status": "solved",
    "symptom": "ภาพ overview ของ 170 หน้ากว้างมากและ fit เหลือประมาณ 2% แม้ source direction เป็น TB",
    "cause": "การ collapse strongly connected components ทำให้หน้าจอจำนวนมากอยู่ rank เดียว แล้ว layout วางทุก node ในแถวเดียว",
    "solution": "แบ่งแถว TB ไม่เกิน 6 cards ต่อแถวและคงความสูงตามข้อความจริง เพิ่ม Module/Channel scope กับ Focus โดยซ่อนเฉพาะมุมมองและไม่ลบ hidden nodes ตอน Save; browser ตรวจ bounded width/แนวตั้งและการคง 170 nodes หลังบันทึก",
    "refs": [
      "tracker/static/mockups.js",
      "tracker/e2e/mockups-check.mjs"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-013",
    "title": "ข้อทดสอบลาก diagram ส่งเมาส์นอก viewport หลังเพิ่มกล่องข้อสังเกต",
    "date": "2026-10-31T02:59:35+07:00",
    "status": "solved",
    "symptom": "grid drag assertion ไม่ผ่าน แต่ shape และเส้นแสดงปกติ",
    "cause": "พิกัดกึ่งกลาง start shape อยู่ y≈1019 เมื่อ viewport สูง 1000 และ elementFromPoint ไม่พบ node; กล่อง review เพิ่มความสูงก่อน canvas แต่ test ใช้ mouse coordinates โดยไม่เลื่อนหน้า",
    "solution": "ให้ Playwright scroll canvas เข้ามาใน viewport ก่อนทดสอบ wheel/drag แล้วตรวจพิกัดและ grid จริง ชุดเดิมผ่านครบ 70 ข้ออีกครั้ง ไม่แก้ product drag โดยเดาสาเหตุ",
    "refs": [
      "tracker/e2e/usecases-check.mjs"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-012",
    "title": "Tracker ช้าเมื่อเปิดหลาย tab",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "กดเมนูแล้วหน้าโหลดช้า ทั้งที่ server ตอบเร็ว",
    "cause": "ทุก tab เปิดการเชื่อมต่อ live update (SSE) ค้างไว้ 1 ช่อง browser ให้ประมาณ 6 ช่องต่อเว็บบน HTTP/1.1 เปิดหลาย tab แล้ว request ใหม่ต้องรอ และ CSS/JS ถูกโหลดใหม่ทุกหน้า",
    "solution": "tab ที่ซ่อนอยู่ปิดการเชื่อมต่อแล้วต่อใหม่เมื่อกลับมา, CSS/JS ใส่ ?v=<hash> และให้ browser cache ได้",
    "refs": [
      "tracker/static/live.js",
      "tracker/main.go",
      "tracker/templates/layout.html"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-011",
    "title": "ย่อ/ขยายใน Timeline กดแล้วแถวไม่หาย",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "กดปุ่ม ▾ ที่ Milestone / Epic หรือย่อทั้งหมด แล้วแถวข้างในยังแสดงอยู่",
    "cause": "JS ใส่ attribute hidden ให้แถวถูกแล้ว แต่ CSS .tl-row { display: flex } มีผลเหนือ [hidden] ของ browser แถวจึงไม่หาย E2E เดิมเช็กแค่ attribute ไม่ได้เช็กว่าหายจากจอจริง",
    "solution": "เพิ่ม .tl-row[hidden] { display: none } และ E2E เช็กจากความสูงของแถวที่เห็นจริง",
    "refs": [
      "tracker/static/style.css",
      "tracker/e2e/timeline-check.mjs"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-010",
    "title": "ช่องรายละเอียดของ Timeline มีสีซ้อนตอนชี้เมาส์ (theme มืด)",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "เลื่อน chart ไปทางขวาแล้วชี้เมาส์ที่แถว ส่วนที่ช่องรายละเอียดทับ chart เห็นสีแถบทะลุขึ้นมา",
    "cause": "สี hover ของ theme มืดเป็นสีโปร่งแสง (rgba) และไปแทนพื้นทึบของช่องรายละเอียดที่ลอยทับ chart",
    "solution": "วางสี hover เป็นชั้นบนพื้นทึบ (linear-gradient + --surface / --thead) ช่องรายละเอียดจึงทึบเสมอ",
    "refs": [
      "tracker/static/style.css"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-009",
    "title": "ผลตรวจจาก curl ผิดเพราะ rtk ตัด output",
    "date": "2026-10-30",
    "status": "solved",
    "epic": "prep-team-tools",
    "symptom": "ตรวจหน้า Wait for review ด้วย curl | grep แล้วได้ 0 ฟอร์ม ทั้งที่หน้าเว็บมีฟอร์มครบ",
    "cause": "เครื่องนี้ใช้ rtk ซึ่ง rewrite คำสั่ง curl ให้ย่อ output (เหลือ ~600 ตัวอักษรจาก 34 KB) grep จึงไม่เจอสิ่งที่อยู่ท้ายหน้า",
    "solution": "ใช้ rtk proxy curl เมื่อต้องการ output เต็มสำหรับ grep หรือนับผล ตรวจซ้ำแล้วเจอฟอร์มครบ 6 อัน",
    "refs": [
      "tracker/e2e/review-check.mjs"
    ]
  },
  {
    "id": "P-008",
    "title": "เปิด tracker ผ่าน Tailscale แล้วได้ 404 และ 500",
    "date": "2026-10-30",
    "status": "solved",
    "epic": "prep-team-tools",
    "symptom": "tailscale serve --http ตอบ 404 page not found เมื่อเข้าด้วย IP และตอบ 500 เมื่อเข้าด้วยชื่อเครื่อง",
    "cause": "(1) HTTP serve เลือกปลายทางตามชื่อ host และ MagicDNS ปิดอยู่ เครื่องอื่นจึงต้องใช้ IP ซึ่งไม่ตรงกับชื่อที่ลงทะเบียน (2) WSL ส่งต่อพอร์ตให้ Windows ทาง ::1 เท่านั้น ปลายทาง 127.0.0.1 จึงต่อไม่ได้ และ http://[::1]:8099 ถูกบันทึกเป็น http://::1:8099 ซึ่งไม่ใช่ URL ที่ถูกต้อง",
    "solution": "ใช้ tailscale serve --tcp=8099 tcp://localhost:8099 ซึ่งส่งต่อแบบ TCP ไม่สนชื่อ host และให้ localhost เลือก ::1 เอง ทดสอบทุกหน้าและ SSE ผ่าน IP Tailscale แล้วผ่าน รวมไว้ใน scripts/tailscale.sh",
    "refs": [
      "tracker/scripts/tailscale.sh"
    ]
  },
  {
    "id": "P-007",
    "title": "Watcher อ่านไฟล์ข้อมูลระหว่างที่กำลังบันทึก",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "TestWatchBroadcastsOnDataChange ผ่านบ้างไม่ผ่านบ้าง และหน้าเว็บอาจขึ้นข้อความ JSON ผิดแวบหนึ่งตอนบันทึกไฟล์",
    "cause": "การบันทึกไฟล์จะล้างไฟล์ก่อนแล้วค่อยเขียน watcher ที่ตรวจทุก 1 วินาทีบางครั้งอ่านไฟล์ตอนที่ยังเขียนไม่เสร็จ",
    "solution": "เมื่อเห็นไฟล์เปลี่ยน ให้รอจนขนาดและเวลาแก้ไขของไฟล์คงที่ (ตรวจห่างกัน 100 ms) ก่อนโหลดใหม่ แล้วรันทดสอบซ้ำ 30 รอบผ่านครบ",
    "refs": [
      "tracker/live.go"
    ],
    "epic": "prep-team-tools"
  },
  {
    "id": "P-001",
    "title": "Proposal มีเนื้อหาจากเอกสารโครงการอื่นค้างอยู่",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "§5 (Architecture, การเชื่อมต่อ, NFR) และ §7 (งบประมาณ) พูดถึงระบบที่ไม่เกี่ยวกับ TNSU",
    "cause": "ทีมใช้เอกสารของโครงการอื่นขึ้นโครง แล้วลืมลบเนื้อหาเดิมออก",
    "solution": "เอาเนื้อหานั้นออกจากฐานความรู้ทั้งหมด และระบุว่า §5 กับ §7 ยังไม่ได้เขียนสำหรับ TNSU ให้ Agent ข้ามไป",
    "refs": [
      "docs/agent/11-open-questions-and-known-issues.md"
    ],
    "epic": "prep-discovery"
  },
  {
    "id": "P-002",
    "title": "รหัส SCH ซ้ำกันระหว่าง BA กับ use case",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "เอกสารใช้ SCH-xx เป็นโรงเรียนกีฬา แต่ use case ของทีมใช้ SCH เป็น module ทุนและ กยศ.",
    "cause": "ตั้งรหัสฝั่ง BA เองก่อนได้ use case",
    "solution": "เปลี่ยนรหัสฝั่ง BA เป็น SS-xx ทุกไฟล์ และเขียนคำเตือนไว้ใน AGENTS.md",
    "refs": [
      "docs/agent/03-modules.md",
      "AGENTS.md"
    ],
    "epic": "prep-discovery"
  },
  {
    "id": "P-003",
    "title": "ภาพโครงสร้าง module ของ BA ความละเอียดต่ำ",
    "date": "2026-10-29",
    "status": "solved",
    "symptom": "ภาพขนาด 2000×486 ตัวอักษรเล็กจนอ่านตรง ๆ ไม่ได้ และมีเลขข้อซ้ำ (8.3, 14.3, 15.3)",
    "cause": "ได้มาเป็นภาพ export ไม่ใช่ไฟล์ต้นฉบับ",
    "solution": "ตอนแรกตัดภาพเป็นส่วนแล้วขยาย 4–5 เท่าเพื่อถอดข้อความ ต่อมา BA ส่งไฟล์ต้นฉบับ TNSU_EDU 191069.drawio มา (30 ต.ค. 2569) จึงอ่านจากไฟล์โดยตรงด้วย gen_ba_drawio.py ข้อความตรงกับที่ถอดจากภาพทุกข้อ เลขข้อซ้ำมีอยู่จริงในต้นฉบับ",
    "refs": [
      "TNSU_EDU 191069.drawio",
      "docs/agent/ba-drawio.md",
      "docs/agent/tools/gen_ba_drawio.py"
    ],
    "epic": "prep-discovery"
  },
  {
    "id": "P-004",
    "title": "ข้อมูล use case ฝังอยู่ในไฟล์ HTML ที่ export มา",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "Agent อ่านไฟล์ UC1-Explorer.dc.html ขนาด 300 KB ได้ยาก และค้นหา use case รายตัวไม่ได้",
    "cause": "ข้อมูลทั้งหมดอยู่ในตัวแปร JavaScript บรรทัดเดียว",
    "solution": "เขียนสคริปต์ gen_use_cases.py ดึง object ออกมาแล้วสร้าง Markdown ทีละ module รันใหม่ได้ทุกครั้งที่ทีม export",
    "refs": [
      "docs/agent/tools/gen_use_cases.py"
    ],
    "epic": "prep-discovery"
  },
  {
    "id": "P-005",
    "title": "หาผู้อนุมัติด้วยการค้นคำให้ผลผิด",
    "date": "2026-10-30",
    "status": "solved",
    "symptom": "การค้นคำว่า อนุมัติ หรือ รับรอง ทำให้นักศึกษาถูกนับเป็นผู้อนุมัติในหลาย module",
    "cause": "คำเหล่านี้ปรากฏในขั้นตอนของผู้ยื่นคำขอด้วย เช่น ยื่นใบลาที่ไม่ต้องอนุมัติ",
    "solution": "ใช้ตารางนับแค่การมีส่วนร่วม แล้วอ่านขั้นตอนอนุมัติ 158 รายการเพื่อทำตารางอำนาจอนุมัติด้วยมือ",
    "refs": [
      "docs/agent/13-role-matrix.md",
      "docs/agent/use-cases/role-module-matrix.md"
    ],
    "epic": "prep-access"
  },
  {
    "id": "P-006",
    "title": "เครื่องไม่มีโปรแกรมแปลง .docx",
    "date": "2026-10-29",
    "status": "solved",
    "symptom": "ไม่มี pandoc และ libreoffice ให้แปลง Proposal เป็นข้อความ",
    "cause": "เครื่อง WSL ไม่ได้ติดตั้งไว้",
    "solution": "แตกไฟล์ .docx แล้วอ่าน word/document.xml ด้วย Python ตรง ๆ รวมตารางและตำแหน่งภาพ",
    "refs": [
      "docs/agent/source/proposal-extracted.md"
    ],
    "epic": "prep-discovery"
  },
  {
    "id": "P-007",
    "title": "Browser test ผ่าน CDP โดยตรงค้างตอน navigation",
    "date": "2026-10-30T20:00:07+07:00",
    "status": "solved",
    "symptom": "ชุด browser test แรกค้างที่ Page.navigate แม้ HTTP server ตอบ 200",
    "cause": "การเรียก Chromium ด้วยชุด flag และ CDP แบบง่ายในสภาพแวดล้อมนี้ไม่สามารถเปิดหน้าได้ สาเหตุระดับ Chromium ยังไม่ได้ยืนยัน ไม่พบปัญหา HTTP server",
    "solution": "ใช้ Playwright ที่ติดตั้งอยู่แล้วเปิด headless shell ด้วย launch configuration มาตรฐาน ทดสอบจริงผ่าน 23 ข้อ รวมการเขียนและสองผู้ใช้ ไม่มีการติดตั้ง dependency เพิ่ม",
    "epic": "prep-team-tools",
    "refs": [
      "tracker/e2e/usecases-check.mjs"
    ]
  }
]