# 485Tech.com — Tool Authoring Standard

เอกสารนี้กำหนดวิธีเพิ่มหรือปรับเครื่องมือใน 485Tech.com ให้ทุก tool มี behavior จริง, privacy disclosure ถูกต้อง, UI สม่ำเสมอ และสร้างซ้ำได้จาก build pipeline. ใช้ร่วมกับ `docs/project-architecture.md` และ `docs/code-commenting-standard.md`.

## Tool contract

Tool หนึ่งรายการต้องมี stable id แบบ lowercase kebab-case, ชื่อและคำอธิบายสองภาษา, category ที่มีอยู่หรือมีเหตุผลรองรับ, icon ที่มีอยู่ใน sprite, registration path, primary action และ error/empty state. Tool ที่ยังทำงานไม่ครบห้ามประกาศเป็น `live` หรือแสดงเป็นฟีเจอร์ที่พร้อมใช้.

| Contract | สิ่งที่ต้องมี |
|---|---|
| Identity | id ไม่เปลี่ยนหลัง release; name key และ description key มีทั้ง `th`/`en` |
| Runtime | `Tools.registerApp` หรือ adapter ที่ตรวจสอบแล้ว; mount ไม่ throw; คืน cleanup เมื่อมี resource |
| Input | validation สำหรับ text/file/select; reject ไม่ทำลาย input เดิม |
| Output | result/status ที่มองเห็นและอ่านได้; empty/error/success state |
| Privacy | ระบุ local/network behavior ตาม code; ไม่อ้าง fully offline เกินจริง |
| Capability | `client`, `download`, `clientSide`, `offline`, `needsNetwork`, privacy/limitations keys |
| Accessibility | label, keyboard path, focus-visible, status/error ที่ไม่พึ่งสีอย่างเดียว |
| Responsiveness | ใช้ได้ตั้งแต่ 320px โดยไม่เกิด horizontal overflow |
| Verification | focused test เมื่อ behavior มีความเสี่ยง และ full shared regression เมื่อแตะ runtime กลาง |

## ขั้นตอนเพิ่ม tool

เริ่มด้วยการเขียน intent และ acceptance criteria จาก user outcome. Trace ว่ามี shared runtime ที่ทำ behavior เดิมอยู่แล้วหรือไม่ก่อนสร้างไฟล์ใหม่. เลือก implementation ที่เล็กที่สุดแต่ไม่ซ่อน failure; อย่าใช้ fake result, disabled button ที่ทำให้ดูเหมือนเสร็จ หรือ placeholder ที่ไม่มี owner.

จากนั้นสร้างหรือแก้ source ตามลำดับ:

1. เพิ่ม module/adapter ใน `public/scripts/tools/apps/<id>/index.js` และ CSS ที่จำเป็น
2. เพิ่ม manifest/catalog data ตามรูปแบบที่ build อ่านได้
3. เพิ่ม capability metadata ใน `src/tool-capabilities.json` เฉพาะค่าที่ตรวจจาก implementation
4. เพิ่ม i18n keys ใน `src/i18n/th.json` และ `src/i18n/en.json`
5. เพิ่ม focused test/QA หากเพิ่ม file handling, storage, network, download, worker หรือ asynchronous behavior
6. รัน build เพื่อสร้าง `public/tools/<id>/index.html`, catalog และ sitemap
7. ตรวจ generated diff ว่ามี payload ถูกต้อง ไม่มี placeholder/secret/local path

## Runtime pattern

ตัวอย่าง module ที่มี lifecycle ครบ:

```js
/**
 * @module example-tool
 * @description Processes user input locally and renders a deterministic result.
 *
 * @ai-handoff
 * - Input stays in browser memory; this module has no network request.
 * - Mount returns cleanup for listeners, timers and object URLs.
 * - Keep result/status text synchronized with the UI controls.
 */
(function () {
  'use strict';

  Tools.registerApp('example-tool', function mount(root) {
    // Build DOM, attach listeners, and keep references for cleanup.
    const onInput = () => { /* validate and render */ };
    root.addEventListener('input', onInput);
    return function cleanup() {
      root.removeEventListener('input', onInput);
    };
  });
})();
```

ปรับตัวอย่างให้ตรงกับ runtime ที่ repository ใช้จริง; อย่าคัดลอกชื่อหรือ fake behavior ไปใช้โดยไม่เปลี่ยน contract. `Tools.el`, `Tools.copyText`, `Tools.downloadBlob`, `Tools.workspace` และ shared helpers ควรใช้เมื่อเหมาะสมเพื่อรักษา behavior ที่ผ่าน audit แล้ว.

## File tool rules

ไฟล์ต้องตรวจ extension/MIME/ขนาดก่อน parse. ต้องแสดง error ที่อธิบายวิธีแก้, ไม่ล้าง queue/input เดิมเมื่อ reject และไม่อ้างว่าไฟล์ถูกเก็บหรือส่งที่ใดเกินจริง. ใช้ `URL.createObjectURL` เท่าที่จำเป็นและ `URL.revokeObjectURL` เมื่อ resource หมดอายุ. สำหรับหลายไฟล์ ให้แสดง queue state, processing state, success/failed ต่อรายการ และ cancel semantics ที่ผู้ใช้คาดเดาได้.

| จุดเสี่ยง | Acceptance criteria |
|---|---|
| Unsupported type | reject แบบไม่ทำลาย valid state และมีข้อความที่แปลแล้ว |
| Oversized file | แสดง limit ตรงกับ `maxFileBytes` และไม่เริ่ม processing |
| Parse failure | สถานะ error ต่อ input; ไม่มี unhandled rejection |
| Cancel | หยุดรายการถัดไปตาม contract และคืน UI ไปยัง state ที่ใช้งานต่อได้ |
| Download | ผลลัพธ์เป็น Blob/URL ใน browser และชื่อไฟล์ปลอดภัย |
| Multiple inputs | queue ไม่ duplicate และ progress/status ไม่โกหก |

## Storage and privacy rules

ถ้า tool มี draft หรือ snapshot ให้ใช้ `Tools.workspace` ไม่สร้าง IndexedDB schema แยกโดยไม่จำเป็น. ระบุ app id, record shape, migration, per-value/total limit และ behavior เมื่อ storage unavailable. ข้อมูล local workspace ไม่ใช่ account sync; อย่าเพิ่ม server sync โดยไม่มี threat model, consent, encryption design และ test.

ถ้า tool ดาวน์โหลด library/model ตอน first use ให้เพิ่ม `needsNetwork: true`, `offline: false`, privacy copy และ limitation copy ใน change เดียวกัน. “local inference” หมายถึง computation อยู่ใน browser ไม่ได้หมายความว่า asset source ไม่มี network.

## Capability metadata guidance

Capability contract ต้อง conservative. ใส่ `fileTypes` และ `maxFileBytes` ต่อเมื่อ implementation validate ค่านั้นจริง. ถ้าไม่รองรับ copy อย่าใส่ `copy` เพื่อให้ badge ดูครบ. หากแก้ behavior แล้ว metadata เดิมไม่จริง ต้องอัปเดต validator/test.

| Capability | ใส่เมื่อ |
|---|---|
| `client` | มี processing ที่ทำใน client จริง |
| `download` | ผู้ใช้ดาวน์โหลด output ได้จริง |
| `file` | มี file input/drop/queue ที่ใช้งานได้ |
| `copy` | มี copy output ที่ enabled ตาม state จริง |
| `batch` | ประมวลผล input หลายรายการใน workflow เดียว |
| `ai` | ใช้ model/AI inference จริงและมี disclosure |

## Accessibility checklist

ใช้ heading hierarchy ที่ไม่ข้ามอย่างไร้เหตุผล, `label` กับ form controls, `button` สำหรับ action, `a` สำหรับ navigation และ `aria-live` เฉพาะ status ที่เปลี่ยนจริง. ทุก action ที่ทำได้ด้วย mouse ควรทำได้ด้วย keyboard. Focus ต้องเห็นได้ทั้ง light/dark theme. Error ไม่ควรสื่อด้วยสีอย่างเดียว.

ตรวจอย่างน้อย: Tab order, Enter/Space บน drop zone หรือ custom control, Escape/cancel, disabled state, long filename wrapping, 320–390px layout, reduced motion และ locale switch. อย่าเพิ่ม `aria-label` ที่ขัดกับ visible label.

## Testing matrix for a tool

Focused test ควรครอบคลุม empty, valid, invalid, boundary และ cleanup. File tool เพิ่ม unsupported/oversized/multiple/cancel/download. Network-dependent tool เพิ่ม no-network fallback หรือ expected warning โดยไม่ถือว่า warning ที่ประกาศแล้วเป็น silent failure.

```text
mount -> controls visible -> valid input -> result/status
      -> invalid/boundary input -> error without data loss
      -> action/download/copy -> cleanup -> remount
```

เมื่อแก้ shared runtime ให้รัน `npm run validate:tools`, unit app test, smoke all tools, functional matrix, deep sweep และ UI regression. เมื่อแก้เฉพาะ CSS/layout ให้เพิ่ม mobile no-overflow check และตรวจ screenshot/DOM geometry ตามความเหมาะสม.

## Review and handoff

PR/commit ต้องระบุ tool id, shared runtime ที่ได้รับผล, capability/privacy changes, limitations, exact test commands/results และ generated files. Reviewer ต้องเปิด standalone page จริงอย่างน้อยหนึ่ง locale และตรวจว่า source, UI copy, metadata, test และ docs พูดเรื่องเดียวกัน.

Tool จะถือว่าเสร็จในเฟสเมื่อผู้ใช้ทำ happy path ได้จริง, invalid/boundary path ไม่ทำให้ page พัง, ไม่มี placeholder, metadata ผ่าน validator, accessibility baseline ผ่าน, generated output ถูก rebuild และ known limits ถูกบันทึกใน docs.
