# 485Tech.com — Project Architecture and Handoff

**สถานะ:** เอกสารอ้างอิงกลางของ repository
**Audience:** AI agents, maintainers, reviewers และผู้ที่จะรับช่วงพัฒนา
**Source of truth:** source files, manifests, tests และ generated build output ตามลำดับที่ตรวจสอบได้ใน repository

## ภาพรวมระบบ

485Tech.com เป็นแพลตฟอร์ม **Free Online Tools แบบ local-first/privacy-first** ที่รวมเครื่องมือ browser utilities จำนวน 159 รายการไว้ใน Tools Hub และ standalone studio pages. เว็บไซต์ใช้ static HTML/CSS/JavaScript เป็นหลัก ไม่มี frontend framework และใช้ Cloudflare Worker เป็น edge entrypoint สำหรับ routing, security headers, static asset binding และ API handlers บางส่วน. เครื่องมือทั่วไปประมวลผล input ใน browser; ไฟล์และข้อความไม่ถูกอัปโหลดโดยค่าเริ่มต้น.

> **Boundary ที่ต้องจำ:** “ทำงานใน browser” ไม่ได้แปลว่า “offline เสมอไป”. ปัจจุบัน `bg-remover`, `diagram` และ `excel-chat` มี first-use dependency ที่อาจดาวน์โหลด model/library จาก network และ capability contract ระบุเรื่องนี้ไว้ใน UI แล้ว.

ตารางนี้สรุปชั้นของระบบจาก request ที่ผู้ใช้เห็นไปจนถึง source ที่ต้องแก้.

| ชั้น | หน้าที่ | Source หลัก | Output/ผลกระทบ |
|---|---|---|---|
| Public pages | Home, Tools Hub, use cases, about, privacy, terms, blog, store | `src/layout.html`, `src/pages/*.html`, `src/pages.json` | `public/*.html` |
| Standalone studio shell | top bar, theme/language/share/pin, app root, capability details, ads/footer | `src/app-layout.html`, `public/scripts/tools/tools-app.js` | `public/tools/<id>/index.html` |
| Tool catalog | stable id, name key, category, module, icon, status, asset manifest | `public/scripts/tools/catalog.json` และ app manifests | Hub cards, build pages, validators |
| Tool runtime | registration, mount, controls, processing, cleanup | `public/scripts/tools/apps/<id>/index.js`, shared runtimes | DOM behavior ในแต่ละ tool |
| Shared browser runtime | DOM helpers, i18n, clipboard/download, pins/history, workspace/draft/snapshot | `public/scripts/tools/tools-core.js` | behavior ที่ใช้ร่วมกันทุก tool |
| Legacy/pro runtime | adapters และ shared implementations สำหรับกลุ่ม tool เดิม/ขั้นสูง | `public/scripts/tools/mega-tools.js`, `pro-tools.js`, `pro-tools-extra.js` | ลดการซ้ำของ implementation |
| Build system | compile templates, copy vendors, resolve capability metadata, generate pages/SEO | `scripts/build.mjs` | catalog, standalone pages, sitemap, public assets |
| Edge runtime | HTTPS redirect, CSP/HSTS/security headers, API routing, ASSETS fallback | `src/worker/index.js`, middleware/lib | Cloudflare Worker `home` |
| Validation | catalog, contract, docs, syntax, unit, smoke, functional, browser/UI, dry-run | `scripts/*.mjs`, `.github/workflows/ci.yml` | release evidence ใน `docs/` |

## Repository map

```text
485Tech.com/
├── src/
│   ├── app-layout.html              # template ของ standalone tool pages
│   ├── layout.html                  # template/public page layout
│   ├── pages/                       # source HTML pages
│   ├── pages.json                   # page metadata/build inputs
│   ├── i18n/{th,en}.json            # source translation dictionaries
│   ├── tool-capabilities.json       # capability contract schema v2 source
│   └── worker/
│       ├── index.js                 # Cloudflare Worker entrypoint/router
│       ├── middleware/auth.js       # JWT/auth boundary
│       └── lib/db.js                # D1 data access wrapper
├── public/
│   ├── scripts/tools/
│   │   ├── apps/<tool-id>/           # tool modules, CSS, local assets
│   │   ├── tools-core.js             # shared client runtime/workspace
│   │   ├── tools-app.js              # standalone studio bootstrap
│   │   ├── mega-tools.js             # legacy shared adapters/runtime
│   │   ├── pro-tools*.js             # advanced shared runtimes
│   │   └── catalog.json              # generated catalog consumed by Hub
│   ├── styles/{main,pages}.css       # shared visual system
│   ├── i18n/{th,en}.json             # copied/generated runtime dictionaries
│   ├── tools/<tool-id>/index.html    # generated standalone pages
│   └── *.html, sitemap.xml, ads.txt  # generated/public site assets
├── scripts/                          # build, validators, tests, local preview
├── test-fixtures/                    # synthetic fixtures for reproducible functional QA
├── .github/workflows/ci.yml          # push/PR validation-only automation
├── migrations/                       # D1 SQL migrations; only used when DB bound
├── docs/                             # audit, architecture, standards, release evidence
├── wrangler.toml                      # Worker name, assets binding, env vars
├── build.py                           # Cloudflare legacy-command bridge to npm run build
├── package.json                        # scripts, npm@10.9.2 package-manager contract
├── package-lock.json                   # npm dependency lockfile; do not add a second manager lock
└── SECURITY.md                        # security rollout and operational guidance
```

## Build pipeline

คำสั่ง `npm run build` เรียก `scripts/build.mjs`. Build อ่าน source templates, page metadata, tool catalog/manifests และ `src/tool-capabilities.json`; จากนั้น resolve metadata แบบ defaults/category/override, copy vendor assets, inject i18n-safe values และสร้าง standalone page สำหรับทุก live tool. Build ยังสร้าง `public/scripts/tools/catalog.json`, canonical pages และ `public/sitemap.xml`. `build.py` เป็น compatibility bridge สำหรับ Cloudflare configuration เดิมที่เรียก `python3 build.py`; มัน delegate ไป `npm run build` เท่านั้นและห้ามเพิ่ม logic generation แยกอีกชุด.

`public/` เป็น deploy directory ไม่ใช่จุดเริ่มต้นของ business logic. หาก generated output เปลี่ยน ให้แก้ source หรือ build script แล้วรัน build ใหม่. ห้ามแก้ `public/tools/<id>/index.html` เพียงหน้าเดียวเพื่อแก้ behavior เพราะ build ครั้งถัดไปจะเขียนทับ.

| งาน | คำสั่ง | Definition of done |
|---|---|---|
| Build | `npm run build` | ไม่มี error; generated pages/catalog/sitemap ครบ |
| Local preview | `PORT=8788 npm run preview` | เปิด `/`, `/tools`, `/tools/<id>` ได้ |
| Catalog/contract | `npm run validate:tools` | 159 catalog/live entries และ schema pass |
| Syntax | `node scripts/validate_syntax.mjs` | JSON parse และ JS syntax pass |
| Wrangler preflight | `CI=1 npx --yes wrangler@4.127.0 deploy --dry-run --env production` | อ่าน assets/bindings ได้โดยไม่ deploy |
| Cloudflare legacy build | `python3 build.py` | delegate ไป canonical `npm run build`; ใช้เฉพาะจนกว่าจะเปลี่ยน dashboard command |
| Dependency install | `npm ci` | ใช้ `package-lock.json` เดียว; `bun.lock` ถูกลบเพื่อป้องกัน provider เลือก lockfile ผิด |

## Standalone page lifecycle

เมื่อผู้ใช้เปิด `/tools/<id>` Worker/preview server จะ resolve ไปยัง `public/tools/<id>/index.html`. หน้าโหลด shared CSS และ scripts, ตั้ง theme ก่อน paint, เตรียม `window.APP_CAPABILITIES`, รอ `window.app.readyPromise` ของ global shell, แล้ว `tools-app.js` ทำงานตามลำดับนี้:

1. อ่าน `data-app-id` จาก `#app-root` และรอ core readiness.
2. wire top bar: back, language, theme, share, pin และ optional credits.
3. load module `/scripts/tools/apps/<id>/index.js` ด้วย asset version ที่ build inject.
4. เรียก `Tools.runApp(appId, root, options)` เพื่อ mount registered app.
5. ลบ loading state; ถ้า mount สำเร็จให้ render shared capability details จาก injected metadata.
6. ให้ ads runtime scan slot หลัง consent gate; จากนั้น app เป็นเจ้าของ event handlers และ cleanup ของตัวเอง.

App module ต้อง register ผ่าน `Tools.registerApp(id, mountFunction)` หรือ adapter ที่ shared runtime รองรับ. `mountFunction` ควรคืน cleanup function เมื่อมี listener, timer, object URL, worker หรือ dynamic resource. หาก mount ล้มเหลว shell แสดง retry error state แทนการปล่อยหน้า blank.

## Tool implementation model

Tool จำนวนมากเป็น adapter ขนาดเล็กที่ส่งต่อไปยัง `mega-tools.js`, `pro-tools.js` หรือ `pro-tools-extra.js`. Adapter สั้นไม่ได้แปลว่าเป็น placeholder; ต้อง trace registration และ shared implementation ก่อนสรุปว่า tool ขาดฟังก์ชัน. Tool ใหม่ควรเลือกเส้นทางดังนี้:

| กรณี | ตำแหน่งที่เหมาะสม |
|---|---|
| Behavior ใช้เฉพาะ tool เดียว | `public/scripts/tools/apps/<id>/index.js` และ CSS ข้างกัน |
| Behavior ใช้หลาย tool ในกลุ่มเดิม | เพิ่ม shared function ใน runtime ที่ถูกกลุ่ม แล้วทำ adapter |
| File/format library | ใช้ vendor ที่มีอยู่หรือเพิ่ม asset ผ่าน `scripts/build.mjs`; ระบุ license/size/network |
| Capability/privacy/limit | เพิ่ม source metadata ใน `src/tool-capabilities.json` และ i18n keys; อย่า hardcode เฉพาะ generated page |
| New public page/SEO | เพิ่ม source page/metadata แล้วให้ build สร้าง canonical/sitemap |

ทุก tool ที่รับ file ต้องตรวจ MIME/extension/size ใน browser, แสดง error ที่ผู้ใช้เข้าใจได้, ไม่แทนที่ queue/input เมื่อ reject และ revoke object URLs หลังใช้งาน. ทุก download ต้องสร้างผลลัพธ์จาก browser-side data และใช้ shared helper หากมี.

## Local workspace and storage

`Tools.workspace` ใช้ IndexedDB ใน browser. Draft เดิมใช้เพื่อ restore input ของ tool ส่วน named snapshots ใช้ object store `snapshots` ใน DB schema version 2. Snapshot record มี app id, name, timestamp, byte size และ value. Limits ปัจจุบันคือ 5 MB ต่อ value และ 25 MB รวม snapshot budget. API มี list/save/load/duplicate/delete/clear/usage.

ข้อมูลนี้เป็น local browser state ไม่ใช่ account sync. การแก้ schema ต้องเป็น additive migration และต้องรักษา draft ของผู้ใช้ version เดิม. UI ต้องแสดง privacy boundary, limit และ fallback เมื่อ IndexedDB ใช้ไม่ได้. ห้ามเพิ่มการ sync ขึ้น server โดยไม่มี threat model, consent, encryption design และ migration plan.

## Capability contract

`src/tool-capabilities.json` เป็น source ของ capability metadata schema v2. Build เติมข้อมูลลง catalog และฝัง payload ลง standalone page เพื่อไม่ต้อง fetch catalog เพิ่มตอน runtime. Contract ปัจจุบันประกอบด้วย:

| Field | ความหมาย | กฎ |
|---|---|---|
| `capabilities` | ความสามารถที่ UI แสดง | ต้องเป็น allowlisted keys |
| `clientSide` | processing หลักทำใน browser | live tools ปัจจุบันเป็น `true` |
| `offline` | ไม่ต้องใช้ network ระหว่าง runtime | ห้ามเป็น `true` เมื่อมี dependency ที่ต้องดาวน์โหลด |
| `needsNetwork` | มี first-use/runtime network dependency | ต้องระบุให้ชัดเมื่อมี model/library download |
| `fileTypes` | extension ที่ตรวจจาก implementation | ใส่เฉพาะชนิดที่ code รองรับจริง |
| `maxFileBytes` | per-file/value limit | ต้องเป็น positive integer และตรงกับ UI/test |
| `privacyKey` | i18n privacy disclosure | ต้องมีทั้ง `th` และ `en` |
| `limitationsKey` | i18n limitation disclosure | ต้องมีทั้ง `th` และ `en` |

หากเพิ่ม network dependency ให้แก้ metadata, UI disclosure และ test ใน change เดียวกัน. ห้ามใช้ label “fully offline” กับ Background Remover ในสถานะปัจจุบัน.

## Security and data boundaries

Worker `src/worker/index.js` ทำ HTTPS redirect, security headers, HSTS rollout, CSP Report-Only/Enforce, per-request nonce, same-origin/CSRF checks, body limit และ optional KV rate limiting. API handlers ได้แก่ CSP report, subscribe, authenticated user/credits และ credit charge. D1/KV bindings ใน `wrangler.toml` ยังเป็น optional/commented ตาม environment ที่ตรวจ.

HTML ถูกตั้ง `Cache-Control: no-store` หลัง nonce injection เพื่อไม่ให้ cached nonce ถูก reuse. Static CSS/JS/assets ใช้ ASSETS binding และ normal caching behavior. หากแก้ CSP ให้รัน Worker smoke และตรวจ CSP reports ก่อนเปลี่ยน `CSP_MODE` จาก report-only เป็น enforce.

AdSense เป็น consent-gated และ non-personalized default. Publisher ID และ account ownership ต้องตรวจโดยเจ้าของ production account; code readiness ไม่ใช่หลักฐานว่า ads serve จริง. อย่าใส่ guessed slot IDs หรือ claim compliance ที่ยังไม่ได้ยืนยัน.

## Validation layers

การตรวจระบบมีหลายชั้นและแต่ละชั้นตอบคำถามต่างกัน. Test หนึ่งชั้นผ่านไม่ได้แปลว่าทุกชั้นผ่าน.

| Layer | Script | สิ่งที่ป้องกัน |
|---|---|---|
| Static catalog | `validate_catalog.mjs` | missing/duplicate/non-live catalog entries |
| Capability contract | `validate_tool_contract.mjs` | schema/type/i18n/network contradiction |
| Syntax | `validate_syntax.mjs` | invalid JSON/JS ที่ build อาจไม่จับครบ |
| Unit app | `unit-app-test.mjs` และ focused app tests | core conversion/mount/edge behavior |
| Worker | `worker-smoke.mjs` | route, headers, auth, CSRF, API errors |
| Smoke all | `smoke_all_tools.mjs` | page can load/mount across all 159 tools |
| Functional | `functional_extra.mjs` | representative file/PDF/Office/ZIP/image/audio flows |
| Matrix | `functional-matrix.mjs` | all tools ready/interactive/console-clean |
| Deep sweep | `deep-tool-sweep.mjs` | inputs/selects/files/actions safe across all tools |
| UI | `ui-regression.mjs` | desktop/mobile user journeys, persistence, downloads |
| Focused QA | `qa-json-snapshots.mjs`, `qa-capability-details.mjs` | named snapshots, locale, responsive details disclosures |
| Deploy preflight | Wrangler dry-run | assets/bindings/config can be packaged |
| CI automation | `.github/workflows/ci.yml` | clean runner builds, validates docs/contracts and runs browser gate; validation-only |

เมื่อเพิ่ม tool ให้เพิ่ม focused test หาก behavior มี risk สูง; เมื่อแก้ shared runtime ต้องรันอย่างน้อย unit, smoke, matrix, deep sweep และ UI regression.

## AI handoff protocol

AI ที่รับช่วงต้องอ่านเอกสารต่อไปนี้ก่อนแก้ code:

1. `AGENTS.md` — working agreement และลำดับการอ่าน
2. `docs/project-architecture.md` — system map และ lifecycle
3. `docs/code-commenting-standard.md` — comment/contract/data boundary rules
4. `docs/tool-authoring-standard.md` — วิธีเพิ่มหรือปรับ tool
5. `docs/release-checklist.md` — validation, commit, push และ production truth
6. `docs/release-gate-final.md` และ `docs/cloudflare-deployment-audit.md` — สถานะ release ล่าสุดและ blocker

ก่อนลงมือให้ตรวจ `git status --short --branch`, อ่าน source ที่เกี่ยวข้อง และห้าม reset/revert user changes. หลังแก้ให้รายงาน changed files, contract changes, tests ที่รัน, known limitations และ next action. ถ้าเป็น generated output ให้ระบุ source ที่สร้างมัน.

## Human review protocol

Reviewer ควรเริ่มจาก intent และ risk ไม่ใช่เริ่มจากจำนวนบรรทัด. ตรวจว่า comment อธิบายเหตุผลจริง, runtime behavior ตรงกับ docs, privacy claim ตรงกับ network behavior, limits ตรงกับ UI, generated output มาจาก build ล่าสุด และ test ตรวจ acceptance criteria จริง. ตรวจ diff ของ shared runtime ด้วยความระมัดระวังมากกว่า adapter เพราะมี blast radius ต่อ 159 tools.

## Current production boundary

Local source, GitHub validation และ release gate ผ่านตาม `docs/release-gate-final.md`. Cloudflare production source of truth คือ Workers Builds ของ Worker `home`, เชื่อม GitHub `485Tech.com` branch `main`; custom domains `485tech.com`/`www.485tech.com` อยู่ใน production service และ final build `4656cf4` สำเร็จด้วย UUID `35a95605-6ebe-4365-aede-e98f9b6381e3`. Live probe ผ่าน routes, Worker security headers, CSP nonce parity และ HTML `no-store` โดยไม่พบ `1101`. ยังต้องให้ owner ยืนยัน active version/rollback record ใน dashboard เพราะ script metadata API คืน `deployment_id` ว่าง; ห้ามเพิ่ม GitHub deployment workflow ซ้อนกับ Workers Builds.

## References

[1]: https://developers.cloudflare.com/workers/ci-cd/builds/git-integration/github-integration/ "Cloudflare Workers — GitHub integration"
[2]: https://developers.cloudflare.com/api/operations/workers-builds-get-worker-build-configuration "Cloudflare API — Get worker build configuration"
[3]: https://developers.cloudflare.com/api/operations/workers-builds-get-worker-triggers "Cloudflare API — Get worker build triggers"
