สัปดาห์ที่ 13

โครงงานเว็บแอปพลิเคชันทางธุรกิจ: วิเคราะห์ ออกแบบ และพัฒนา (ทีม)

CLO1 CLO2 CLO6
📖 ทฤษฎี

1. การวิเคราะห์ความต้องการ (Requirements Analysis) — User Stories

ก่อนเขียนโค้ดแม้แต่บรรทัดเดียว ทีมต้องเข้าใจ ปัญหา ที่ต้องการแก้ และ ผู้ใช้งาน ที่เกี่ยวข้องอย่างชัดเจน วิธีที่เป็นมาตรฐานในการบันทึก Requirement คือ User Stories — ประโยคสั้นๆ ที่อธิบาย Feature จากมุมมองของผู้ใช้

โครงสร้างของ User Story มีสามส่วน:

  • As a [ประเภทผู้ใช้] — ระบุว่าใครคือผู้ใช้ที่ต้องการ Feature นี้
  • I want to [สิ่งที่ต้องการทำ] — ระบุ Action ที่ผู้ใช้ต้องการทำ
  • So that [ประโยชน์ที่ได้รับ] — ระบุเหตุผลหรือคุณค่าที่ได้รับ

แต่ละ User Story ควรมี Acceptance Criteria — เกณฑ์ที่วัดได้ว่า Feature นั้น "เสร็จ" จริงๆ Acceptance Criteria เขียนเป็น Checklist ที่ทุกคนในทีมเห็นตรงกัน ทำให้การ Test และ Review ง่ายขึ้นมาก

  User Story Template
  ─────────────────────────────────────────────────
  As a     [ประเภทผู้ใช้]
  I want   [สิ่งที่ต้องการทำ]
  So that  [ประโยชน์ที่ได้รับ]

  Acceptance Criteria:
  - [ ] เงื่อนไขที่วัดได้ข้อ 1
  - [ ] เงื่อนไขที่วัดได้ข้อ 2
  - [ ] เงื่อนไขที่วัดได้ข้อ 3
  ─────────────────────────────────────────────────
หมายเหตุ — Must Have vs Nice to Have

แบ่ง User Stories ออกเป็นสองกลุ่ม: Must Have (ต้องมีเพื่อให้ระบบทำงานได้จริง) และ Nice to Have (เพิ่มคุณค่าแต่ไม่จำเป็น) เริ่มสร้าง Must Have ก่อนเสมอ ป้องกัน Scope Creep ที่ทำให้โปรเจกต์ไม่เสร็จทันกำหนด

2. การออกแบบ Database สำหรับระบบจริง

Database ที่ดีคือรากฐานของระบบที่ดี การออกแบบตาราง (Schema Design) ที่ถูกต้องตั้งแต่ต้น ทำให้เขียน Query ง่าย ระบบเร็ว และแก้ Bug น้อยกว่า การออกแบบผิดกลางคันทำให้ต้อง Migrate ข้อมูล ซึ่งเสียเวลามากกว่าการวางแผนตั้งแต่แรก

หลักการสำคัญในการออกแบบ Database สำหรับโครงงาน:

  • Normalization (1NF–3NF) — แยก Data ที่ซ้ำกันออกเป็นตารางใหม่ เช่น แทนที่จะเก็บชื่อหมวดหมู่ซ้ำทุก Record ให้สร้างตาราง categories แยก และใช้ Foreign Key อ้างอิง
  • Foreign Keys & Relationships — กำหนด Relationship ระหว่างตาราง (One-to-Many, Many-to-Many) ให้ชัดเจนก่อนสร้างตาราง วาด ER Diagram เป็นขั้นตอนแรกเสมอ
  • Appropriate Data Types — ใช้ VARCHAR สำหรับข้อความสั้น, TEXT สำหรับข้อความยาว, DECIMAL สำหรับราคาเงิน (ไม่ใช่ FLOAT), TIMESTAMP สำหรับวันเวลา
  • Indexes — เพิ่ม Index บน Column ที่ใช้ค้นหาบ่อย เช่น email, status เพื่อให้ Query เร็วขึ้น
  ตัวอย่าง ER Diagram (ระบบจัดการสต็อกสินค้า)
  ─────────────────────────────────────────────────
  [categories]          [products]
  ────────────          ─────────
  id (PK)               id (PK)
  name                  name
  description           price
                        stock
                        image
                        category_id (FK)────► [categories.id]
                        created_at

  [users]               [stock_transactions]
  ───────               ───────────────────
  id (PK)               id (PK)
  email                 product_id (FK)─────► [products.id]
  password              user_id (FK)─────────► [users.id]
  role                  type (IN/OUT)
  created_at            quantity
                        note
                        created_at
  ─────────────────────────────────────────────────
เคล็ดลับ — ให้อาจารย์ Approve ERD ก่อนเขียนโค้ด

ทีมนำเสนอ idea + ERD + wireframe ให้อาจารย์ approve ก่อนเขียนโค้ด การแก้โครงสร้าง Database หลังจากที่มีข้อมูลอยู่แล้วหรือเขียนโค้ดไปมากแล้วนั้นซับซ้อนและเสียเวลามาก รับ Feedback ตั้งแต่ต้นจะช่วยประหยัดเวลาได้มาก

3. การออกแบบ REST API (API Design Best Practices)

ระบบที่มี Frontend และ Backend แยกกัน (เช่น React + Hono) ต้องการ REST API เป็นสะพานเชื่อม API ที่ออกแบบดีทำให้ทีม Frontend และ Backend ทำงานแบบขนานกันได้โดยตกลง Contract กันก่อน

หลักการออกแบบ REST API ที่ดี:

  • ใช้ Noun ใน URL ไม่ใช่ Verb/api/products ถูก, /api/getProducts ผิด — ใช้ HTTP Method (GET/POST/PUT/DELETE) แทน Verb
  • HTTP Methods ที่เหมาะสมGET อ่านข้อมูล, POST สร้างใหม่, PUT/PATCH แก้ไข, DELETE ลบ
  • HTTP Status Codes200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
  • Response Format ที่สม่ำเสมอ — ตกลง Format กับทีมให้ชัด เช่น {"data": [...], "message": "ok"} หรือ {"error": "Not found"}
  REST API Endpoints ตัวอย่าง (ระบบสต็อกสินค้า)
  ─────────────────────────────────────────────────
  GET    /api/products          → รายการสินค้าทั้งหมด
  GET    /api/products/:id      → สินค้าตาม ID
  POST   /api/products          → เพิ่มสินค้าใหม่ (Admin)
  PUT    /api/products/:id      → แก้ไขสินค้า (Admin)
  DELETE /api/products/:id      → ลบสินค้า (Admin)

  GET    /api/stock              → ประวัติการเคลื่อนไหวสต็อก
  POST   /api/stock/in           → รับสินค้าเข้าสต็อก
  POST   /api/stock/out          → จ่ายสินค้าออกจากสต็อก

  POST   /api/auth/login         → เข้าสู่ระบบ
  POST   /api/auth/logout        → ออกจากระบบ
  ─────────────────────────────────────────────────

4. โครงสร้าง Project สำหรับทีม (Monorepo)

โครงการที่มี Frontend (React + Vite) และ Backend (Hono + Cloudflare Workers) แยกกัน มีสองรูปแบบหลักในการจัดการ Repository:

  • Monorepo — เก็บทั้ง Frontend และ Backend ไว้ใน Repository เดียวกัน แบ่งเป็นโฟลเดอร์ frontend/ และ backend/ ข้อดีคือ Clone ครั้งเดียวได้ทั้งหมด จัดการ Dependency และ Versioning ง่ายกว่า เหมาะสำหรับทีมขนาดเล็ก
  • 2 Repositories — Frontend และ Backend แยก Repository กัน ข้อดีคือแต่ละส่วน Deploy อิสระได้ แต่ต้องจัดการ 2 Repo ซึ่งซับซ้อนกว่า

สำหรับโครงงานทีมนี้ แนะนำ Monorepo เพราะสะดวกและจัดการง่ายกว่า โครงสร้างโฟลเดอร์ที่แนะนำดูได้ในส่วนโค้ดตัวอย่างด้านล่าง

เคล็ดลับ — แต่ละโฟลเดอร์มี package.json แยกกัน

ใน Monorepo แต่ละโฟลเดอร์ (frontend/ และ backend/) มีไฟล์ package.json ของตัวเอง รัน npm install แยกกัน และ npm run dev แยกกัน ทำงานได้เป็นอิสระแต่อยู่ใน Repository เดียวกัน

5. Git Collaboration: Branches, Pull Request, Code Review

การทำงานเป็นทีมบน Git ต้องการ Workflow ที่ชัดเจนเพื่อป้องกัน Conflict และทำให้โค้ดมีคุณภาพสม่ำเสมอ รูปแบบที่ใช้กันทั่วไปคือ Feature Branch Workflow:

  • main branch — โค้ดที่ทดสอบแล้วและพร้อม Deploy เท่านั้น ไม่ commit โดยตรง ต้องผ่าน Pull Request เสมอ
  • feature branches — แต่ละ Feature หรือ Bug Fix สร้าง Branch ใหม่ ตั้งชื่อให้สื่อความหมาย เช่น feature/add-product-crud, fix/login-validation
  • Pull Request (PR) — เมื่อ Feature เสร็จแล้ว สร้าง PR เพื่อขอ Merge เข้า main สมาชิกคนอื่นในทีม Review และ Approve ก่อน Merge
  • Code Review — ตรวจสอบโค้ดของเพื่อน ดู Logic, Security, Style แสดงความคิดเห็นผ่าน GitHub Comments ก่อน Approve
  Feature Branch Workflow
  ─────────────────────────────────────────────────
  main ────●────────────────────────────●──── deploy
            \                          /
  feature    ●──●──●  (code review)  ●
             สร้าง   ทำงาน   เปิด PR   Merge

  Git Commands:
  ─────────────────────────────────────────────────
  git checkout -b feature/add-product-crud
  # ... ทำงาน ...
  git add .
  git commit -m "feat: add product CRUD endpoints"
  git push origin feature/add-product-crud
  # เปิด Pull Request บน GitHub → ขอ Review
  ─────────────────────────────────────────────────
ข้อควรระวัง — Commit Message ที่ดี

เขียน Commit Message ให้สื่อความหมาย เช่น feat: add product search by name หรือ fix: correct stock calculation on checkout หลีกเลี่ยง Message กว้างๆ เช่น update code หรือ fix bug เพราะทำให้ดู History ยากมากเมื่อต้องย้อนกลับไปแก้ปัญหา

💻 โค้ดตัวอย่าง
user-stories.md — ตัวอย่าง User Stories สำหรับโครงงาน Markdown
# ระบบจัดการสต็อกสินค้า

**As a** ผู้ดูแลระบบ (Admin)
**I want to** เพิ่ม/แก้ไข/ลบสินค้าได้
**So that** ข้อมูลสินค้าในระบบถูกต้องและทันสมัย

**As a** พนักงาน
**I want to** บันทึกการรับ-จ่ายสินค้าได้
**So that** ติดตาม stock ได้แบบ real-time

**Acceptance Criteria:**
- [ ] Admin login ด้วย email/password
- [ ] เพิ่มสินค้าพร้อมรูปภาพและราคาได้
- [ ] ระบบแจ้งเตือนเมื่อ stock ต่ำกว่า 10 ชิ้น
- [ ] Export รายงานสต็อกเป็น CSV ได้
โครงสร้าง project ทีม (Monorepo) Bash
# โครงสร้าง project ทีม
my-project/
├── frontend/          # Vite + React
│   ├── src/
│   │   ├── components/
│   │   ├── pages/
│   │   ├── hooks/
│   │   ├── contexts/
│   │   └── lib/
│   └── package.json
├── backend/           # Hono + Cloudflare Workers
│   ├── src/
│   │   ├── routes/
│   │   ├── middleware/
│   │   └── lib/
│   └── package.json
└── README.md

# Git workflow ทีม
git checkout -b feature/add-product-crud
# ... ทำงาน ...
git push origin feature/add-product-crud
# เปิด Pull Request → ขอ code review จากเพื่อนในทีม