ข้ามไปยังเนื้อหาหลัก
ผลงานทั้งหมด

โปรเจกต์ส่วนตัว·2026·Web App · Knowledge Management

Atlas — พื้นที่ทำงานวิจัยส่วนตัว

เก็บแหล่งข้อมูล เชื่อมหัวข้อ ประเมินข้อกล่าวอ้างด้วยหลักฐาน และเขียนเป็นความรู้ที่กลับมาอ่านได้ — เว็บแอปส่วนตัวที่ผมออกแบบเองตั้งแต่ฐานข้อมูลจนถึงความปลอดภัย

Atlas — พื้นที่ทำงานวิจัยส่วนตัว
บทบาท
นักพัฒนาเดี่ยว — ออกแบบ ฐานข้อมูล Frontend Backend ความปลอดภัย ทดสอบ และDeploy
ทีม
งานเดี่ยว
ระยะเวลา
ต.ค. 2026
ปี
2026

ตัวเลขสำคัญ

35
โมเดลข้อมูลใน Prisma (รวมตารางเชื่อม)
55
unit tests ที่ผ่าน (11 ไฟล์)
14
ชนิดความสัมพันธ์ระหว่างหัวข้อ
50 MB
ขนาดไฟล์แนบสูงสุด
30 วัน
อายุเซสชัน

Atlas เป็นเว็บแอปส่วนตัวสำหรับค้นคว้าเรื่องหนึ่งจากหลายแหล่ง วางลิงก์ลง Inbox พร้อมความเห็น แล้วค่อยจัดเข้าหัวข้อ เชื่อมความสัมพันธ์ จดโน้ต และเขียนรายงานด้วยตัวแก้ไขแบบ rich text ข้อกล่าวอ้างแต่ละข้อแยก “ข้อความ” “หลักฐานที่สนับสนุนหรือขัดแย้ง” และ “ข้อสรุปของตัวเอง” ออกจากกัน มีค้นหาแบบ FULLTEXT, กราฟความรู้, ส่งออก/นำเข้า และติดตั้งเป็น PWA ได้ ระบบมีเจ้าของคนเดียว ไม่มีการสมัครสาธารณะ ไม่มี AI คิวงาน หรือการล็อกอินผ่านบุคคลที่สาม ผมออกแบบทั้งหน้าจอ ฐานข้อมูล (35 โมเดลใน Prisma) และชั้นความปลอดภัยเอง และตอนนี้ใช้งานจริงบนโฮสติ้งที่รัน Phusion Passenger

โจทย์และปัญหา

  1. 01งานค้นคว้ากระจายอยู่หลายที่ ทั้งบุ๊กมาร์ก วิดีโอที่ดูค้างไว้ ไฟล์ PDF และโน้ต พอกลับมาอ่านก็ไม่รู้ว่าแหล่งไหนสนับสนุนข้อสรุปข้อไหน
  2. 02แอปจดโน้ตทั่วไปไม่แยก “ข้อกล่าวอ้าง” ออกจาก “หลักฐาน” และไม่บอกว่าข้อสรุปของเรามั่นใจแค่ไหน
  3. 03การเก็บลิงก์เป็นด่านเสี่ยง: เซิร์ฟเวอร์ต้องไปดึงข้อมูลจาก URL ที่ผู้ใช้ให้มา ซึ่งเปิดช่อง SSRF ได้ และไฟล์แนบก็อาจเป็นไฟล์อันตรายหรือ HTML ที่รันสคริปต์ได้
  4. 04งานเขียนยาวที่เปิดหลายแท็บหรือเซสชันหมดอายุกลางคัน เสี่ยงเขียนทับกันหรือข้อความหายโดยไม่รู้ตัว

วิธีแก้

  1. 01Capture: วาง URL พร้อมความเห็น หัวข้อ แท็ก และความสำคัญ ระบบทำ URL ให้เป็นรูปแบบมาตรฐานและตรวจรายการซ้ำ ดึง metadata ของ YouTube, GitHub และหน้าเว็บทั่วไปผ่าน adapter — ถ้าดึงไม่สำเร็จก็ยังบันทึกได้
  2. 02Inbox → Topics: จัดหลายรายการเข้าหัวข้อ แท็ก และความสำคัญพร้อมกัน ใช้คีย์ลัดได้ หัวข้อมีชื่อเรียกอื่น (alias) ปักหมุด รายการโปรด คอลเลกชัน ความสัมพันธ์ 14 ชนิด และรวมหัวข้อซ้ำกันแบบ transaction
  3. 03Notes และ Reports ด้วย TipTap: หัวข้อ ตัวหนา ลิงก์ รูป โค้ดบล็อก ตาราง รายการตรวจสอบ และ callout บันทึกอัตโนมัติพร้อมสถานะ ใช้ optimistic concurrency กันการเขียนทับจากอีกแท็บ รายงานมีเวอร์ชันที่บันทึกเอง ดูย้อนหลังและกู้คืนเป็นเวอร์ชันใหม่ได้
  4. 04Claims: แยกข้อความ จุดยืนของหลักฐาน (สนับสนุน ขัดแย้ง เป็นกลาง บริบท) และข้อสรุปของตัวเอง พร้อมระดับความมั่นใจ 0–100 ส่วนงานวิจัย (task) ระบุความสำคัญและกำหนดส่งได้ รวมถึงผูกกับหัวข้อ แหล่งข้อมูล หรือข้อกล่าวอ้างได้
  5. 05กราฟความรู้ขาวดำด้วย React Flow และ dagre: กรองตามความสัมพันธ์และแท็ก ค้นหาหัวข้อ ดูหัวข้อที่เชื่อมอยู่ 1–2 ระดับ และจำกัดการวาดที่ 150 หัวข้อ 500 เส้น ค้นหาแบบ FULLTEXT ในขอบเขต workspace และ command palette (Ctrl/⌘+K)
  6. 06ความปลอดภัย: เจ้าของคนเดียวผ่านหน้า first-run setup, รหัสผ่าน Argon2id, เซสชันแบบ opaque อายุ 30 วันที่เก็บเฉพาะ SHA-256 ในฐานข้อมูล, จำกัดการล็อกอินผิดซ้ำ, ทุก query ผูกกับ workspace, ทุก mutation ตรวจที่มาของคำขอ และตั้ง CSP กับ header ป้องกันการฝังเฟรม
  7. 07ไฟล์แนบเก็บใน S3 แบบ private ตรวจขนาด (สูงสุด 50 MB) MIME นามสกุล และ binary signature เก็บ SHA-256 ดาวน์โหลดด้วยsigned URL อายุ 2 นาที มี fallback อัปโหลดผ่านเซิร์ฟเวอร์ และพรีวิว HTML ที่ผ่านการ sanitize ใน sandbox ภายใต้ CSP
  8. 08ส่งออก/นำเข้า: JSON แบบมีเวอร์ชันและ ZIP ของ Markdown ส่วนการนำเข้าเป็น transaction ที่แมป ID ใหม่ รวม URL ต้นทางที่ซ้ำ รักษาเวอร์ชันรายงาน และ sanitize snapshot ติดตั้งเป็น PWA ได้ (manifest, service worker, หน้า offline) พร้อม Dockerfile หลายขั้นและ CI บน GitLab

ผลลัพธ์

  1. 01ได้พื้นที่ทำงานเดียวที่ไล่จากลิงก์ → หัวข้อ → ข้อกล่าวอ้างและหลักฐาน → รายงานที่มีเวอร์ชัน โดยข้อมูลทั้งหมดอยู่ในฐานข้อมูลที่ผมควบคุมเอง และส่งออกได้ทุกเมื่อ
  2. 02ชุดทดสอบหน่วย 55 รายการใน 11 ไฟล์ผ่านทั้งหมด ครอบคลุม URL, SSRF, safe-fetch, รหัสผ่านและเซสชัน, ไฟล์, sanitize HTML, การนำเข้า, origin, PWA และข้อผิดพลาด นอกจากนี้ในรีโปมีชุดทดสอบ integration กับ MySQL จริงและ E2E ด้วย Playwright
  3. 03GitLab CI รัน lint, typecheck, test และ build ในทุกการ push และระบบทำงานจริงบน atlas.phatphum.me (ต้องล็อกอิน)

สิ่งที่ส่งมอบ

  • เว็บแอป Next.js 16 + Prisma/MySQL (35 โมเดล พร้อม migration และ FULLTEXT index)
  • Inbox, Topics, Sources, Notes, Claims, Tasks, Reports, Graph, Collections, Tags, Trash และ Settings
  • ตัวแก้ไข TipTap และรายงานที่มีเวอร์ชัน
  • ชั้นความปลอดภัย: Argon2id, hash ของเซสชัน, safe-fetch, sanitize และ sandbox ของพรีวิว, CSP
  • ส่งออก/นำเข้า JSON และ Markdown ZIP
  • PWA, Dockerfile หลายขั้น, ตัวอย่างนโยบาย S3 และ nginx, และ CI บน GitLab
  • ชุดทดสอบ: unit, integration (MySQL) และ E2E (Playwright)

ทบทวนโปรเจกต์

ความท้าทาย

  • การดึง metadata จาก URL ที่ผู้ใช้ให้มาเป็นจุดที่เสี่ยงต่อการโจมตีแบบ SSRF: ต้องตรวจ DNS ทุก hop ล็อกค่า IP ที่ผ่านการตรวจไว้กับ connection ปฏิเสธ IP ส่วนตัวและ IPv4-mapped IPv6 ตรวจทุก redirect และจำกัดขนาดกับเวลา (2 MB, 5 redirect, 8 วินาที) พร้อมชุดทดสอบเฉพาะ
  • ตัวแก้ไข rich text ต้องไม่ยอมรับ HTML อิสระ จึงใช้ whitelist ของ node และ mark ของ TipTap จำกัดแอตทริบิวต์และโปรโตคอลลิงก์ แล้วแยกพรีวิวไฟล์ HTML ที่ไม่น่าเชื่อถือไว้ใน response ที่มี sandbox และ CSP ของตัวเอง
  • กันเขียนทับระหว่างหลายแท็บและตอนเซสชันหมดอายุ: ใช้ optimistic concurrency เก็บข้อความที่ยังไม่บันทึกไว้ในตัวแก้ไข และเปิดให้ล็อกอินอีกแท็บได้โดยไม่เสียงานที่เขียนอยู่
  • ต้องลดเวอร์ชัน Prisma จาก 7 เป็น 6 ระหว่างDeploy เพื่อให้เข้ากับโฮสติ้ง Plesk/Passenger (ตามประวัติคอมมิต)

สิ่งที่เรียนรู้

  • ออกแบบความปลอดภัยเป็นชั้น ๆ (ตรวจอินพุต, ขอบเขต workspace, ที่มาของคำขอ, CSP, sandbox) แทนการพึ่งจุดเดียว
  • โมเดลที่แยกข้อกล่าวอ้าง–หลักฐาน–ข้อสรุปทำให้บันทึกการค้นคว้าตรงไปตรงมากว่าโน้ตเปล่า ๆ เพราะต้องบอกว่าอะไรเป็นข้อเท็จจริงและอะไรเป็นความเห็น
  • การทดสอบกับฐานข้อมูลจริงเชื่อถือได้กว่า mock แต่ต้องมีรั้วกันไม่ให้เทสต์ไปแตะฐานข้อมูลหลัก ตัวช่วยทดสอบของ Atlas จึงปฏิเสธชื่อฐานข้อมูลที่ไม่มีคำว่า test หรือ shadow

สนใจงานแนวนี้?

เล่าโจทย์ของคุณให้ผมฟัง ตอบกลับภายใน 24 ชั่วโมง

คุยเรื่องงาน