# 485Tech.com — Code Commenting Standard

**สถานะ:** มาตรฐานกลางของ repository
**ผู้รับผิดชอบเริ่มต้น:** Manus AI และ maintainer ของ 485Tech.com
**เป้าหมาย:** ทำให้โค้ดอ่านต่อได้โดยคนและ AI โดย comment อธิบายเหตุผลและ contract ที่โค้ดเปิดเผยจริง ไม่กลายเป็นเอกสารที่ขัดกับ implementation

## หลักการสำคัญ

Comment ที่ดีตอบคำถามว่า **โค้ดนี้มีหน้าที่อะไร, ทำไมต้องทำแบบนี้, มีข้อจำกัดอะไร, และใครต้องระวังเมื่อแก้ไข**. หลีกเลี่ยงการบรรยายสิ่งที่ syntax บอกอยู่แล้ว เช่น `i += 1 // add one`. หาก implementation เปลี่ยนจน comment ไม่จริง ต้องแก้ comment ใน commit เดียวกัน หรือเอา comment ที่ล้าสมัยออกทันที.

> **กฎสูงสุด:** source code, test และ runtime behavior เป็น source of truth; comment มีหน้าที่อธิบาย intent, invariant, contract และ trade-off ไม่ใช่ประกาศฟีเจอร์ที่โค้ดไม่ได้ทำ

ตารางต่อไปนี้เป็น decision rule สำหรับเลือกว่าจะใส่ comment แบบใด.

| สถานการณ์ | สิ่งที่ควรอธิบาย | สิ่งที่ไม่ควรทำ |
|---|---|---|
| Module/shared runtime | ขอบเขตความรับผิดชอบ, dependency, lifecycle, side effects | คัดลอกชื่อฟังก์ชันมาเขียนซ้ำ |
| Public function/API | input/output, async behavior, error behavior, privacy/security contract | ซ่อน assumption สำคัญไว้ในชื่อสั้น ๆ |
| Security/privacy | threat, allowlist, data boundary, เหตุผลของ default | อ้างว่า secure/offline โดยไม่มีหลักฐานจาก code |
| Browser storage | database/schema version, keys, limits, migration, failure fallback | บอกว่า sync/cloud ทั้งที่เป็น local-only |
| Workaround/quirk | bug หรือ browser behavior ที่ทำให้ต้องใช้วิธีนี้, เงื่อนไขเอาออกได้ | comment ว่า `temporary` โดยไม่ระบุ issue/เงื่อนไข |
| Build/generated output | ไฟล์ต้นทางและคำสั่งสร้างใหม่ | แก้ generated file แล้วไม่แก้ source |
| Test fixture | behavior ที่ fixture จำลองและเหตุผลที่ต้องรอ/patch | ทำให้ test ผ่านด้วย timeout ยาวโดยไม่อธิบาย race |

## รูปแบบ module header

ไฟล์ที่เป็น shared runtime, entrypoint, build script, validator หรือ tool ที่มี lifecycle ซับซ้อนควรมี header แบบ JSDoc ต่อไปนี้. ไฟล์ adapter ขนาดเล็กไม่จำเป็นต้องมี header ซ้ำ หาก reference ไปยัง runtime ที่เป็นเจ้าของ behavior ได้ชัดเจน.

```js
/**
 * @module <stable-module-name>
 * @description <ขอบเขตความรับผิดชอบหนึ่งย่อหน้า>
 *
 * @ai-handoff
 * - Inputs: <ข้อมูลที่ module รับ>
 * - Outputs: <ผลลัพธ์/DOM/API ที่ module สร้าง>
 * - Side effects: <storage, URL, download, external request, global state>
 * - Invariants: <เงื่อนไขที่ห้ามทำลาย>
 * - Failure behavior: <fallback/error path>
 * - Change carefully: <จุดที่กระทบ module อื่นหรือ generated assets>
 *
 * @human-handoff
 * Read <relative/path> and <test/path> before changing this module.
 */
```

ใช้ `@ai-handoff` เฉพาะเมื่อข้อมูลมีประโยชน์ต่อการตัดสินใจของ AI ในรอบถัดไป เช่น data boundary, migration rule หรือ generated-file rule. ไม่ใส่ token, secret, personal data, session cookie หรือค่า environment ที่เป็นความลับลงใน comment.

## Function/JSDoc contract

ฟังก์ชันที่เป็น public-like API หรือมี behavior ข้าม module ให้ใช้ comment แบบ contract. ระบุชนิดข้อมูลเท่าที่ repository รองรับจริง และระบุว่า function คืน `Promise`, อาจ throw, หรือกลืน error แล้วใช้ fallback หรือไม่.

```js
/**
 * Save one named snapshot in the browser-local workspace.
 *
 * @param {string} appId Stable catalog/tool id; never user input.
 * @param {string} name User-visible label, normalized and length-limited by this module.
 * @param {string} value Tool state; kept in IndexedDB and never sent to a server.
 * @returns {Promise<object>} Stored snapshot metadata, including id and byte size.
 * @throws {Error} When IndexedDB is unavailable, the value exceeds the per-value cap,
 *                 or the total snapshot budget would be exceeded.
 */
```

ถ้าฟังก์ชันมี security-sensitive behavior ให้เพิ่มเหตุผลของ default และอธิบายสิ่งที่ **ไม่** รับประกัน เช่น `needsNetwork` หมายถึง first-use asset download ไม่ใช่การส่ง input ไป server. อย่าใช้คำว่า `secure`, `private`, `offline`, `AI` หรือ `encrypted` โดยไม่มีคำอธิบายขอบเขตที่ตรวจสอบได้.

## Comment สำหรับ privacy และ data flow

ทุก feature ที่แตะ input, file, clipboard, URL, download, IndexedDB, CDN หรือ external API ต้องบอก data flow ที่แท้จริงใกล้จุดสำคัญ. Comment ควรตอบคำถามสั้น ๆ ต่อไปนี้:

| คำถาม | ตัวอย่างคำตอบที่ยอมรับได้ |
|---|---|
| Input ไปที่ใด | อยู่ใน memory/IndexedDB ของ browser; ไม่ถูกอัปโหลดโดย runtime นี้ |
| มี network หรือไม่ | ไม่มีตอนประมวลผล; ดาวน์โหลด model/library ตอนใช้ครั้งแรก |
| เก็บนานเท่าใด | อยู่ใน browser storage จนผู้ใช้ลบ/clear หรือ browser ล้าง storage |
| Download คืออะไร | สร้าง Blob URL และเริ่ม download ใน browser |
| Share/export รวมอะไร | เฉพาะ preference ที่ระบุ; ไม่รวม raw tool input เว้นแต่ UX แจ้งชัดเจน |

คำอธิบายต้องสอดคล้องกับ capability contract และ UI disclosure. หากเพิ่ม network dependency ต้องแก้สามจุดพร้อมกัน: source metadata, user-facing translation/privacy copy และ test/validator.

## Comment สำหรับ async และ race condition

เมื่อใช้ debounce, `setTimeout`, `requestAnimationFrame`, event listener, IndexedDB หรือ dynamic script loading ให้ comment lifecycle และจุดที่ต้องรอ. ระบุว่า cleanup ทำอะไรและเหตุใด test ต้องรอ condition นั้น.

```js
// Restore is async because IndexedDB resolves outside the click handler. Update the
// textarea only after the record is loaded, then schedule the normal draft write so
// reload behavior remains identical to a user edit.
```

ห้ามแก้ flaky test ด้วย `waitForTimeout` อย่างเดียว หากรอ state ที่ตรวจได้. ให้ใช้ `waitForFunction`, event, locator state หรือ explicit promise. หากจำเป็นต้องหน่วงเวลาเพื่อจำลอง browser timing ให้ comment ว่า fixture จำลอง behavior อะไรและ test ต้องยืนยันผลลัพธ์ใด.

## Comment สำหรับ schema, migration และ generated files

เมื่อเปลี่ยน storage schema, catalog schema หรือ generated HTML ต้องบันทึก migration rule.

```js
// DB_VERSION 2 adds the snapshots store without deleting drafts. Keep the upgrade
// transaction additive so users with version 1 drafts can open the database safely.
```

ไฟล์ generated ต้องมี comment ที่ source หรือ build script ไม่ใช่แก้เฉพาะ output. เมื่อ build เปลี่ยนทุก standalone page ให้ระบุใน commit และเอกสารว่า output ถูก rebuild จาก source ใด. ห้าม commit generated output ที่มี placeholder, secret หรือ local absolute path.

## Comment ที่ไม่ควรใช้

ไม่ใช้ comment ต่อไปนี้เป็นคำอธิบายถาวร:

```js
// TODO: fix later
// temporary
// magic number
// AI: do the obvious thing
// secure because it is local
// offline (ถ้ายังดาวน์โหลด asset จาก CDN)
```

ให้เปลี่ยนเป็นเหตุผลที่ตรวจสอบได้ เช่น `MAX_FILE_BYTES is aligned with the UI error copy and batch fixture; change both together.` ถ้างานยังค้าง ให้ใส่ issue/acceptance criteria ใน roadmap หรือ issue tracker ไม่ทิ้งคำว่า TODO ที่ไม่มี owner หรือเงื่อนไขจบ.

## มาตรฐานการส่งต่องานระหว่าง AI และคน

ทุก change ที่มีผลข้าม module ควรส่งมอบด้วย summary สั้นใน commit/PR และรายละเอียดในเอกสาร โดยมีข้อมูลอย่างน้อยดังนี้:

| หัวข้อ | ต้องระบุ |
|---|---|
| Intent | ปัญหาหรือ outcome ที่เปลี่ยน |
| Scope | ไฟล์ source, generated output และ runtime ที่ได้รับผล |
| Contract | input/output, storage/network behavior, limits |
| Validation | คำสั่งที่รันและผลจริง ไม่ใช้คำว่า “น่าจะผ่าน” |
| Known limits | สิ่งที่ยังไม่ทำ, dependency, production blocker |
| Follow-up | acceptance criteria และลำดับงานถัดไป |

AI ที่เริ่มงานใหม่ต้องอ่าน `AGENTS.md`, `docs/project-architecture.md`, `docs/tool-authoring-standard.md` และเอกสารที่ระบุใน handoff ก่อนแก้ code. มนุษย์ที่ review ต้องตรวจว่า comment ไม่ขัดกับ test, manifest, i18n, privacy copy และ generated output.

## Definition of done สำหรับ comment

Comment ผ่านมาตรฐานเมื่ออธิบาย intent และ boundary ได้โดยไม่ซ้ำ syntax, ไม่อ้างเกิน implementation, ไม่มี secret/ข้อมูลส่วนตัว, ระบุ lifecycle/failure path ในจุดที่มีความเสี่ยง, เชื่อมไปยัง test หรือ source of truth ได้ และยังเป็นจริงหลังรัน build/test. การเพิ่ม comment ไม่ควรทำให้โค้ดยาวขึ้นโดยไม่มีข้อมูลที่ช่วยการดูแลรักษา.
