CN331 Software Engineering · Project Presentation

BoardWipe

แพลตฟอร์มชุมชนคนเล่นบอร์ดเกม — หาเพื่อน หาเวลา แล้วเปิดกล่องเล่นกัน

Phetphong Kanmud

6710615169

Napat Chumcome

6710615086

Phudinan Jenjobketr

6710545028

Purich Amposre

6710545036

Tortawan Luangaramchai

6710615128

Live: boardwipe.onrender.comRelease v1.0.0CI: passingCoverage 97%

Problem & Value Proposition

ปัญหาของคนอยากเล่นบอร์ดเกม

ปัญหา

  • ไม่รู้ว่าใครเล่นเกมไหนเป็น หรือใครมีเกมนั้นอยู่
  • นัดเวลาว่างตรงกันยาก
  • ข้อมูลกระจายอยู่หลายแชต หลายแอป

BoardWipe ช่วยอย่างไร

  • คลังเกม — เลือกจาก Catalog (Wikidata) ระบุว่า “เล่นเป็น” / “มีเกม”
  • เพื่อน — ค้นหาผู้เล่นและส่งคำขอเป็นเพื่อน
  • เวลาว่าง — ปฏิทินเวลาว่างบนโปรไฟล์
  • แชต — ข้อความส่วนตัว พร้อมแจ้งเตือนทางอีเมล

ผู้ใช้หลัก: นักศึกษาและคนทั่วไปที่อยากหาเพื่อนเล่นบอร์ดเกม

Live Software Demonstration · boardwipe.onrender.com

เส้นทางการสาธิต (Core User Journey)

  1. เข้าสู่ระบบ → หน้าโปรไฟล์
  2. เพิ่มเกมจาก Catalog เข้าคลัง (เล่นเป็น / มีเกม)
  3. ค้นหาผู้เล่น → ส่งคำขอเป็นเพื่อน
  4. สลับบัญชี → ยอมรับคำขอ
  5. เพิ่มเวลาว่างในปฏิทิน
  6. ส่งแชต → แจ้งเตือนทางอีเมล
  7. กรอกข้อมูลผิด → ระบบแจ้งเตือน (Boundary case)

บัญชีที่ใช้สาธิต

ผู้ใช้ A — ส่งคำขอ / ส่งแชต

ผู้ใช้ B — ยอมรับ / รับแชต

รันบน Production จริง · DEBUG=False · HTTPS

Architecture · C4 Model

สถาปัตยกรรมระบบ

Level 1 — System Context

C4 System Context diagram ของ BoardWipe

Level 2 — Container

C4 Container diagram ของ BoardWipe

Browser → Render (HTTPS) → Gunicorn → Django [accounts · chat] → PostgreSQL  |  ภายนอก: Wikidata · Cloudinary · Gmail SMTP

Architecture · Modular Monolith

แบ่งขอบเขตเป็น Django Apps

accounts

ผู้ใช้ · โปรไฟล์ · เพื่อน · Catalog เกม · คลังเกม · เวลาว่าง

chat

ข้อความส่วนตัว · แจ้งเตือนทางอีเมล (จำกัด 1 ฉบับ / 15 นาที)

config

Settings · URL หลัก · WSGI · ตั้งค่า Production บน Render

chat ใช้ User จาก accounts ทางเดียว — accounts ไม่ import chat จึงไม่มี Circular Import

ทำไมเลือก Modular Monolith แทน Microservices?
  • ทีม 5 คน ระบบขนาดนี้ — Deploy เดียว ฐานข้อมูลเดียว ดูแลง่าย ไม่ต้องจัดการ Network ระหว่าง Service
  • ข้อมูลผูกกันแน่น (เพื่อน ↔ แชต ↔ คลังเกม) — Query ข้าม App ได้ใน Transaction เดียว
  • แบ่ง App ตามขอบเขตไว้แล้ว ถ้าโตขึ้นค่อยแยกเป็น Service ได้ภายหลัง
Database · ERD

โครงสร้างฐานข้อมูล (7 Models)

1 : N ×2 1 : N 0..1 : N สร้าง 1 : N 0..1 : N 1 : N ×2 1 : N ×2 M : N เพื่อน User id · usernameemail (unique)display_name · bio favorite_genrefavorite_boardgameprofile_pictureemail_notifications FriendRequest from_user → Userto_user → Usercreated_at FreeTime user → Userdatestart_timeend_time (> start) Boardgame (Catalog) external_id (Wikidata)namecover · cover_url min / max_playersgenresratingcreated_by → User ProfileBoardgame user → Userboardgame → Boardgamename · picture is_knownis_owned Message sender → Userrecipient → Userbodycreated_at ConversationNotification recipient → Usersender → Userlast_notified_at
Clean Code · Transactions & ORM Queries

ตัวอย่างโค้ดจากโปรเจกต์จริง

@transaction.atomic — สร้างเกม + เพิ่มเข้าคลัง

@transaction.atomic
def save(self):
    """Create the catalog game and add it
    to the user's profile as known."""
    game = super().save(commit=False)
    game.genres = Boardgame.format_genres(
        self.cleaned_data["genre_choices"])
    game.created_by = self.user
    game.save()
    ProfileBoardgame.objects.create(
        user=self.user, name=game.name,
        boardgame=game, is_known=True)
    return game

accounts/forms.py — สองตารางสำเร็จพร้อมกัน หรือไม่บันทึกเลย

ป้องกัน N+1 Query

# โปรไฟล์: ดึงเกมพร้อม Catalog ใน query เดียว
"profile_boardgames":
    user.profile_boardgames
        .select_related("boardgame"),

# ค้นหาผู้เล่น: โหลดคลังเกมของทุกคนครั้งเดียว
users = users.distinct().order_by("username")
    .prefetch_related("profile_boardgames")

# หน้าเพื่อน: คำขอพร้อมข้อมูลผู้ส่ง
user.received_friend_requests
    .select_related("from_user")

accounts/views.py · chat/views.py

Quality Evidence · Testing & CI/CD

หลักฐานคุณภาพซอฟต์แวร์

202

Test cases — ผ่านทั้งหมด

97%

Statement coverage (เกณฑ์ ≥ 80%)

4

ด่านตรวจใน GitHub Actions

GitHub Actions — ทุก Push / PR เข้า main

  • Black — Format
  • Flake8 — Lint
  • Bandit — Security scan
  • Tests + Coverage (fail < 80%)

Security Hardening บน Render

  • DEBUG=False · SECRET_KEY จาก Environment
  • HTTPS redirect · HSTS 1 ปี
  • Secure / HttpOnly cookies · CSRF trusted origins
Agile Governance

กระบวนการทำงานของทีม

GitHub Projects

ติดตาม User Story บน Board · ประเมินงานด้วย Story Point ในแต่ละ Issue

Branch ต่อ Feature

feat/… fix/… chore/… → Pull Request → Review → Merge

PR Template

Related Issue · Summary · Test Evidence · Reviewer Checklist

3

Sprints

21

Pull Requests ที่ Merge

v1.0.0

Release Tag

Burn-down Chart · Story Points จาก GitHub Issues

Story Points คงเหลือ (Aug 31 – Nov 8)

ช่วงว่างระหว่าง Sprint Sprint 1Sprint 2Sprint 3 010203040506070 Aug 31Sep 14Sep 29Oct 12Oct 26Nov 8 Story Points คงเหลือ 61 53 33 +18 SP (Nov 6) 9 0 คงเหลือจริง เส้นอุดมคติ เพิ่มขอบเขตงาน

Sprint Velocity (SP)

Sprint 18

Auth (3) · Profile (5)

Sprint 221

Own / Known Game · Friend · Search (5 ×4) · Fix 1

Sprint 352

Free Time (20) · Chat (13) · Email (8) · Visual (8) · Fix ×3

เฉลี่ย 27 SP / Sprint

+18 SP (Nov 6): เพิ่ม US-09 Email (8) · US-10 Visual Design (8) · Fix 2 รายการ (1+1)

รวม 81 SP · Issue ที่ไม่มี SP (fix/chore) นับ 1 SP

Sprint Retrospectives

บทเรียนของทีม

Sprint 1

Start

  • ตกลงขอบเขต User Story ให้ชัดก่อนเขียนโค้ด
  • เขียน Unit Test ควบคู่การพัฒนา
  • ใช้ GitHub Milestone ผูกทุก Issue

Stop

  • เลิกทำงานใกล้เดดไลน์ — กระจายงานตลอด Sprint

Continue

  • เข้าประชุมตรงเวลา

Sprint 2

Start

  • ใช้ CI/CD Pipeline ตรวจโค้ดอัตโนมัติทุก PR
  • ตรวจด้วย Black · Flake8 · Bandit · Coverage
  • Merge main เข้า branch ก่อนเปิด PR

Stop

  • Merge ช้า — ยิ่งมี PR อื่นเข้าก่อนมาก ยิ่งเกิด Conflict ง่าย
  • วางแผนไม่ละเอียด จนงานไปกองใกล้กำหนดส่ง

Continue

  • 1 Branch ต่อ 1 Feature / Fix
  • เข้าประชุมตรงเวลา
Capstone Deliverables

สรุปสิ่งที่ส่งมอบ

รายการหลักฐาน
Live Cloud Appboardwipe.onrender.com · DEBUG=False · HTTPS✓
Clean ArchitectureModular Monolith (accounts · chat) · Transactions · select/prefetch_related✓
Automated QualityGitHub Actions · 202 tests · Coverage 97% · Black / Flake8 / Bandit✓
DocumentationREADME (Setup · C4 · ERD · Tests) · Tag v1.0.0✓

ขอบคุณครับ