---
name: coding-standards
description: บังคับใช้มาตรฐานการเขียนโค้ดของโปรเจกต์นี้ ทุกฟังก์ชัน (PHP และ JavaScript) ต้องมี Docstring ครบถ้วน (Description / Args / Returns) และห้ามเขียน inline script ใน HTML ทุกกรณี Trigger เมื่อผู้ใช้ขอเขียนฟังก์ชัน, เพิ่มโค้ด, review โค้ด หรือถามเรื่อง coding style ของโปรเจกต์นี้
---

# Coding Standards

## กฎบังคับ 3 ข้อ

1. **ทุกฟังก์ชันต้องมี Docstring** ครบ 3 ส่วน: Description · Args · Returns  
2. **ห้ามเขียน inline script** ใน HTML โดยเด็ดขาด
3. **หากมีการอัปเดตฐานข้อมูล** ที่เกี่ยวข้อง ต้องอัปเดตไฟล์ `sql/update.sql` ด้วย

---

## 1. Docstring Standard

### PHP — PHPDoc

ทุก function และ method ต้องมี PHPDoc block เหนือ declaration เสมอ

```php
/**
 * [Description] อธิบายหน้าที่ของฟังก์ชันนี้ในหนึ่งบรรทัดหรือมากกว่า
 * ถ้ามีพฤติกรรมพิเศษหรือ side effect ให้อธิบายต่อในบรรทัดถัดไป
 *
 * @param  type  $paramName  คำอธิบาย parameter นี้
 * @param  type  $paramName2 คำอธิบาย parameter นี้
 *
 * @return type  คำอธิบายค่าที่คืนกลับ; ถ้าไม่คืนค่าให้ระบุ void
 */
function myFunction(type $paramName, type $paramName2): type
{
    // ...
}
```

**ตัวอย่างที่ถูกต้อง:**

```php
/**
 * ดึงรายการชิ้นส่วนอะไหล่ที่เหลืออยู่ทั้งหมดสำหรับเครื่องจักรที่กำหนด
 * เรียงตามจำนวนคงเหลือจากน้อยไปมาก
 *
 * @param  int     $machineId  รหัสเครื่องจักรที่ต้องการ
 * @param  int     $limit      จำนวนแถวสูงสุดที่ต้องการ (default 50)
 *
 * @return array   array ของ associative array แต่ละแถวมีคีย์ part_id, part_name, qty
 */
function getSparePartsByMachine(int $machineId, int $limit = 50): array
{
    // ...
}
```

**ตัวอย่างที่ผิด (ห้ามทำ):**

```php
// ❌ ไม่มี docstring เลย
function getSparePartsByMachine(int $machineId): array
{
    // ...
}

// ❌ มีแค่ชื่อ ไม่มี @param / @return
/**
 * get spare parts
 */
function getSparePartsByMachine(int $machineId): array
{
    // ...
}
```

---

### JavaScript — JSDoc

ทุก function declaration, function expression, และ arrow function ที่ export หรือใช้งานข้ามไฟล์ต้องมี JSDoc block

```js
/**
 * [Description] อธิบายหน้าที่ของฟังก์ชันนี้
 *
 * @param  {type}  paramName   คำอธิบาย parameter
 * @param  {type}  paramName2  คำอธิบาย parameter
 *
 * @returns {type}  คำอธิบายค่าที่คืนกลับ; ถ้าไม่คืนค่าให้ระบุ {void}
 */
function myFunction(paramName, paramName2) {
    // ...
}
```

**ตัวอย่างที่ถูกต้อง:**

```js
/**
 * คำนวณ OEE (Overall Equipment Effectiveness) จากข้อมูล KPI ที่รับเข้ามา
 * ผลลัพธ์จะอยู่ในช่วง 0–100 (หน่วยเป็น %)
 *
 * @param  {number}  availability   อัตราความพร้อมใช้งาน (0–1)
 * @param  {number}  performance    อัตราประสิทธิภาพการผลิต (0–1)
 * @param  {number}  quality        อัตราคุณภาพ (0–1)
 *
 * @returns {number}  ค่า OEE เป็น % ปัดทศนิยม 2 ตำแหน่ง
 */
function calculateOEE(availability, performance, quality) {
    return parseFloat((availability * performance * quality * 100).toFixed(2));
}
```

---

## 2. No Inline Script

### กฎ

- **ห้าม** `<script>` tag ภายใน `.php` / `.html` file ที่มีเนื้อหา JavaScript โดยตรง
- JavaScript ทั้งหมดต้องอยู่ใน **ไฟล์ `.js` แยกต่างหาก** ใต้ `assets/js/`
- ยกเว้นกรณีที่จำเป็นต้อง inject ตัวแปร config จาก PHP ลง JS (เช่น `const BASE_URL = "<?= $url ?>";`) — แต่ต้องจำกัดไว้แค่ `const` declarations เท่านั้น ห้ามมีตรรกะหรือฟังก์ชันใดๆ ใน inline script
- โหลดด้วย `<script src="...">` เท่านั้น

### ผิด — ห้ามทำ

```html
<!-- ❌ inline script ใน PHP file -->
<button id="btnSave">Save</button>
<script>
    document.getElementById('btnSave').addEventListener('click', function () {
        fetch('/api/save_repair.php', { method: 'POST' });
    });
</script>
```

### ถูก — วิธีที่ถูกต้อง

```html
<!-- ✅ โหลด JS จากไฟล์แยก -->
<button id="btnSave">Save</button>
<script src="../assets/js/repair_form.js"></script>
```

```js
// assets/js/repair_form.js

/**
 * ผูก event listener ให้ปุ่ม Save บนฟอร์มซ่อมบำรุง
 * เรียกใช้ครั้งเดียวเมื่อ DOM พร้อม
 *
 * @param  {string}  apiUrl  URL ของ endpoint ที่จะ POST ข้อมูลไป
 *
 * @returns {void}
 */
function initSaveButton(apiUrl) {
    document.getElementById('btnSave').addEventListener('click', function () {
        fetch(apiUrl, { method: 'POST' });
    });
}
```

### ข้อยกเว้นที่อนุญาต

| สิ่งที่อนุญาต | เหตุผล |
|---|---|
| `<script src="...">` | โหลดไฟล์ภายนอก ไม่ใช่ inline |
| ตัวแปร config ที่ PHP inject ลงไป เช่น `<script>const BASE_URL = "<?= $url ?>";</script>` | ข้อมูล server-side ที่จำเป็นต้อง inject ณ runtime — ต้องจำกัดไว้แค่ `const` declarations เท่านั้น ห้ามมีตรรกะ |

---

## 3. UI Conventions — ช่องกรอกตัวเลข (number input)

### กฎ

- `<input type="number">` ทุกช่อง ให้ตั้ง **`step="1"` (จำนวนเต็ม) เป็นค่าเริ่มต้น**
  ทั้งจำนวนอะไหล่, ชั่วโมงงาน, ดาวน์ไทม์, เลขมิเตอร์ ฯลฯ
  ห้ามใช้ `step="any"` / `step="0.001"` / `step="0.25"` เว้นแต่มีเหตุผลชัดเจนและระบุกำกับไว้
- การ **แสดงผล** จำนวน ให้ตัด trailing zero ทิ้ง (เช่น `2.000 → 2`, `2.50 → 2.5`)
  - JS: ใช้ helper `fmt()` (`toLocaleString` แบบ `maximumFractionDigits:3` ไม่มี min)
  - SQL: `TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM <col>))`

### ผิด — ห้ามทำ

```html
<input type="number" id="qty" step="0.001">
<input type="number" id="hours" step="0.25">
```

### ถูก

```html
<input type="number" id="qty" min="1" step="1">
<input type="number" id="hours" min="0" step="1">
```

---

## Checklist ก่อน commit

ตรวจข้อต่อไปนี้ทุกครั้งก่อนส่งโค้ด:

- [ ] ทุก function/method มี docstring ครบ 3 ส่วน (Description, Args, Returns)
- [ ] ไม่มี `<script>` block ที่มี JS logic อยู่ใน HTML/PHP file
- [ ] JS ใหม่ทุกชิ้นอยู่ใน `assets/js/*.js`
- [ ] ชื่อ parameter ใน docstring ตรงกับชื่อจริงใน signature
- [ ] `<input type="number">` ใช้ `step="1"` (จำนวนเต็ม) และการแสดงผลตัด `.000` ทิ้ง

---

## ทำเมื่อ review โค้ดที่ไม่ผ่านมาตรฐาน

1. ระบุทุก function ที่ขาด docstring พร้อม file:line
2. ระบุทุก inline script พร้อม file:line
3. เขียน docstring และ/หรือแยก JS ออกมาให้ครบ ก่อน proceed งานอื่น
