แนวทางการพัฒนา โครงสร้างและข้อควรระวังในการเขียนโค้ดสำหรับโปรเจกต์ Backend เครื่องแยกขวด
Resources
5Install
npx skillscat add hourdevtool/botteproject Install via the SkillsCat registry.
SKILL.md
Bottle Project Backend Skill / Guidelines
ไฟล์นี้เป็นข้อตกลงและหลักการพัฒนา (Development Principles) สำหรับผู้ที่จะเข้ามาพัฒนาโปรเจกต์ต่อ เพื่อให้โค้ดมีโครงสร้างเดียวกันและง่ายต่อการดูแลรักษา (Maintainability)
1. โครงสร้างสถาปัตยกรรม (Architecture)
โปรเจกต์นี้ใช้โครงสร้างแบบ MVC (Model-View-Controller) แบบกำหนดเอง (Custom PHP MVC) โดยมีโครงสร้างดังนี้:
src/Routes/api.php: เป็นที่รวมการประกาศเส้นทาง (Routing) ทั้งหมด หากเพิ่มฟีเจอร์ใหม่ให้มาลงทะเบียน Route ที่นี่src/Router.php: เป็น Core Logic ของการนำทาง หากมีการทำ Public/Private Endpoint ให้แก้ไขตัวแปร$public_routesที่นี่src/Controllers/: ทำหน้าที่รับ Request, ตรวจสอบ (Validate), เรียกใช้ Model และส่งคืน Response ไม่ควรเขียน Logic การจัดการฐานข้อมูลตรงๆ ที่นี่src/Models/: ทำหน้าที่เชื่อมต่อและกระทำกับฐานข้อมูล ทุก Model ควร Extends จากApp\Models\Basemodel
2. หลักการพัฒนา (Development Principles)
2.1 การจัดการ API และ Routing
- RESTful API Design: ตั้งชื่อ Endpoint ให้สื่อความหมาย เช่น
GET /api/admin/machinesไม่ใช่GET /api/admin/get_machines - Controller Separation: แบ่ง Controller ตามลักษณะผู้ใช้งาน (Role) หรือ Entity หลักๆ
AdminControllerสำหรับผู้ดูแลระบบOperatorControllerสำหรับเจ้าของตู้UserControllerสำหรับผู้ใช้งานหน้าตู้MachineControllerสำหรับจัดการ Entity ของตู้ทั่วไป
2.2 การตรวจสอบข้อมูล (Validation)
- ใช้ฟังก์ชัน
checkEmpty($data, ['field1', 'field2'])ในการตรวจสอบ Payload เสมอ เพื่อลดปัญหา Null Exception - ห้าม Trust Client (อย่าเชื่อข้อมูลที่ส่งมาจาก Frontend แบบ 100%) หากมีการคำนวณ เช่น เรทราคา ต้องมีกระบวนการกรองข้อมูลเสมอ
2.3 การจัดการฐานข้อมูล (Database Management)
- ใช้ PDO เสมอ: เพื่อป้องกัน SQL Injection โดยการใช้
prepare()และbindParam() - ห้ามแก้ไข Schema แบบ Manual ทิ้งไว้: หากต้องแก้ไข Table ให้ไปแก้ไขในไฟล์
src/Database/Schema.phpหรือเขียนสคริปต์ Migration เก็บไว้ - Foreign Keys: รักษา Data Integrity โดยตารางที่มีความสัมพันธ์ (เช่น ตู้ กับ เจ้าของตู้) ควรมีการระบุ
ON DELETE SET NULLหรือON DELETE CASCADEให้เหมาะสม
2.4 การจัดการความปลอดภัยและ Role-based (Authentication & Authorization)
- JWT Tokens: ควบคุมสิทธิ์การเข้าใช้งานผ่าน JWT สำหรับ Admin/Operator ให้ระวังความลับของ
JWT_SECRET - Dynamic Public Routes: โปรเจกต์มีการรองรับ Regex ในการตรวจสอบ Public Endpoint ใน
Router.phpโปรดตรวจสอบให้แน่ใจว่า Route ที่กำหนดในนั้นไม่ทำให้ข้อมูลรั่วไหล
2.5 การทำงานกับ Model และ Base Model
- เมื่อจะสร้างตารางใหม่ ให้สร้างคลาสใน
src/Models/...เสมอ โดยการประกาศตัวแปร$tableและ$primarykeyเพื่อให้สามารถใช้ฟังก์ชันพื้นฐานของBasemodelได้แก่Create,Update,Delete,findByIdได้โดยไม่ต้องเขียน SQL ใหม่
3. วิธีการอ่านเอกสารและใช้งาน API (API Documentation)
เราได้จัดทำไฟล์ API_DOCUMENTATION.md ไว้เพื่อให้ทีม Frontend หรือผู้ที่นำ API ไปต่อยอดสามารถเข้าใจได้ง่าย โดยมีหลักการอ่านดังนี้:
- ดู Role ของตัวเอง: เอกสารแบ่งตามหัวข้อ 1. Admin, 2. Operator, 3. User ให้ดูหัวข้อที่ตรงกับสิทธิ์ที่คุณมี
- ดู Endpoint และ Method: ระบุชัดเจนว่าต้องใช้
GET,POST,PUT, หรือDELETEกับ URL ไหน - ตรวจสอบ Authentication:
- สังเกตที่หัวข้อ Authentication หากเขียนว่า
Authorization: Bearer <Token>แปลว่าต้องแนบ Token ทุกครั้งใน Header - หากเขียนว่า
ไม่ต้องใช้ Tokenแปลว่าเป็น Public Route (เช่น การล็อกอิน/ลงทะเบียนหน้าตู้)
- สังเกตที่หัวข้อ Authentication หากเขียนว่า
- ดู Request Body และ Response: เอกสารมีบล็อกโค้ดตัวอย่าง JSON Payload ที่คุณต้องส่งไป และผลลัพธ์ที่คุณจะได้รับกลับมา ให้ยึดตามตัวแปรในตัวอย่างนั้น (เช่น
amount,weight,type)
4. จุดที่ต้องโฟกัสในการพัฒนาต่อ (Focus Areas)
- การบันทึกประวัติแต้ม (Transaction Logs): ตาราง
tb_pointlogควรถูกใช้ทุกครั้งที่มีการเข้าใช้งานตู้และมีการเพิ่ม/ลด Point เพื่อการตรวจสอบย้อนหลัง (Audit trail) - การทำ Validation เชิงลึก: เพิ่มการเช็คประเภทข้อมูล (เช่น เป็นตัวเลข เป็นอีเมล ฯลฯ) ไม่ใช่แค่การเช็คว่าว่างหรือไม่ (
checkEmpty) - การรับรองความหนาแน่นผู้ใช้งาน (Concurrency): การล็อกอินหน้าตู้ หรือการตัด/เพิ่มยอดขวด อาจจะต้องคำนึงถึง Race Conditions เล็กน้อย แนะนำให้ใช้ Transaction (
$db->beginTransaction()) หากมีการเซฟข้อมูล 2 ตารางพร้อมกัน - Error Handling: ปัจจุบันใช้ JSON Return กลับไปเป็น HTTP Status code แนะนำให้ทำ Global Exception Handler เพื่อรองรับ 500 Internal Server Error อย่างสวยงามและเป็นระบบ