# DEPLOY 256 — ผลเตรียมไฟล์ในเครื่อง

วันที่ 7 ตุลาคม 2026 (Asia/Bangkok)

## ผลลัพธ์

Location: `C:\Users\Admin\Downloads\TourAppProject\DEPLOY_256`

| รายการ | ผล | รายละเอียด |
|---|---|---|
| Flutter Web release build | PASS | base href `/256/`, 296 ไฟล์ ประมาณ 127 MB; เฉพาะ build output |
| Portal production build | PASS | base `/256/portal/`, 3 ไฟล์ ประมาณ 376 KB; JS/CSS asset paths ถูกต้อง |
| Backend runtime/source package | PASS | 31 ไฟล์ ประมาณ 8.33 MB, รวม executable Windows x64 ประมาณ 7.80 MB |
| Flutter analyze | PASS | No issues found |
| Backend standalone analyze | PASS | No issues found; วิเคราะห์ source/runtime package ที่ไม่มี Flutter dependency |
| Portal lint | PASS | `npm run lint` |
| Backend tests ที่ปลอดภัย | PASS | 204 ผ่าน, 19 ข้าม เนื่องจากไม่ตั้ง isolated test DB/API |
| Flutter tests ทั้ง `test/` | FAIL | 359 ผ่าน, 10 ไม่ผ่าน, 19 ข้าม |
| Executable startup safety smoke | PASS | production ไม่ตั้ง port → exit 64 ก่อนเปิด listener/อ่าน keys/เชื่อม DB/เรียก provider |
| Build/launcher guards | PASS | rebuild ไม่ให้ URL → exit 1; launcher ไม่มี private .env → exit 1; ไม่มี build/start/upload และ PowerShell syntax errors = 0 |
| Secret/package scan + base/API check | PASS | ไม่พบค่าลับตาม pattern ที่ตรวจ; ไม่มี credential files/source maps/uploads ใน package; checksum manifest สร้างแล้ว |
| เชื่อมต่อระบบมหาวิทยาลัย end-to-end | NOT RUN | ไม่ทราบ Backend URL/port และไม่ได้รับคำสั่งให้ deploy จริง |

**Build ผ่านไม่ได้หมายความว่าระบบพร้อมใช้งานกับ Backend จริงแล้ว**
API URL ที่บรรจุใน Web/Portal คือ `https://backend-url-not-configured.invalid`; `BUILD_INFO.json` ระบุ `apiConfigured=false`
เป็น placeholder ที่ตั้งใจให้เรียกไม่สำเร็จ ไม่ใช่ Backend URL ที่เดาหรือ port ที่สมมุติ
ให้ rebuild ในเครื่องด้วย Public Backend URL จริงก่อนนำไปใช้งาน

## ไฟล์ที่สร้าง

- `web/`: Flutter static output เช่น index.html, flutter.js, flutter_bootstrap.js, main.dart.js, assets, canvaskit และไฟล์ generated จริง
- `portal/`: index.html กับ assets JS/CSS เท่านั้น
- `backend/`: transitive local imports ที่จำเป็นจาก `server/gemini_proxy.dart`, `lib/matching`, `lib/dev`, standalone pubspec/lock, placeholder `.env.example`, launcher และ Windows x64 executable
- `templates/backend.env.example`, `templates/START_BACKEND.ps1`: templates ที่ใช้ rebuild package
- `README_DEPLOY_256.md`: FileZilla mapping, rebuild และ Backend start ทั้งสองวิธี
- `BUILD_DEPLOY_256.bat`, `BUILD_DEPLOY_256.ps1`: rebuild ในเครื่อง; ไม่มี upload/FTP/SSH/start process
- `SCAN_PACKAGE.ps1`, `VERIFY_DEPLOY_256.ps1`: secret/file/path/source-integrity scan
- `BUILD_INFO.json`, `PACKAGE_VERIFICATION.json`, `SHA256SUMS.txt`: metadata/checksums
- logs ผล build/analyze/test/lint/scan และ startup smoke อยู่ที่ root ของชุดนี้เพื่อให้ตรวจผลได้ ไม่ใช่ public upload files

## Source config ที่แก้

1. `travelin_app/lib/core/api_config.dart`: ใช้ `TRAVELIN_API_BASE_URL` เดิม; debug fallback เดิมยังอยู่ แต่ release/profile ที่ไม่มี URL จะ fail ชัดเจนและไม่ฝัง API fallback `localhost:8787` ไว้ใน release
2. `travelin_app/portal/src/main.tsx`: BrowserRouter อ่าน `import.meta.env.BASE_URL` เพื่อรองรับ nested base; local Vite base `/` และ proxy เดิมยังทำงาน
3. `travelin_app/server/gemini_proxy.dart`: เรียก network runtime config ตอน start และ bind ตาม config; startup messages สะท้อน host/port จริง
4. `travelin_app/server/runtime_configuration.dart` (ใหม่): `BIND_HOST`, `PORT`/`TRAVELIN_PORT`, ตรวจ port 1..65535 และห้าม production fallback เมื่อไม่ระบุ port; development เดิม `127.0.0.1:8787`
5. `travelin_app/test/server/runtime_configuration_test.dart` (ใหม่): 5 unit tests สำหรับ local compatibility, production bind, existing port alias, required production port และ invalid/placeholder port

ไม่มีการเปลี่ยน dependencies ของโปรเจกต์เดิมหรือ upgrade package
Backend standalone lock ตัด Flutter-only dependencies ที่ไม่ใช้ และตรวจทุก dependency version ที่เหลือว่าเท่ากับ lock ของโปรเจกต์เดิม
ตัวเลข “Changed 67 dependencies” ใน build log เป็นการตัด entries ที่ไม่จำเป็นสำหรับ standalone Backend ไม่ใช่การ upgrade โครงงาน
ตัวอย่าง `server/.env.example` เดิมมีรอ 24 ชั่วโมง จึงไม่ copy ตัวอย่างนั้นมาใช้; production template ใหม่ใช้ 300 วินาทีตาม default ปัจจุบัน โดยไม่แก้ waiting policy

## Flutter test failures ที่ต้องรับทราบ

ทั้ง 10 failures อยู่ใน `test/widgets/matching_status_view_test.dart` ซึ่งไม่ได้แก้ในงานนี้
Assertions ยังหา `เหลือเวลา ... ชม. ... นาที ... วินาที`; source ปัจจุบัน `lib/widgets/matching_status_view.dart` แสดง `MM:SS`
เช่น test คาด `เหลือเวลา 1 นาที 0 วินาที` แต่ UI แสดง `01:00`

- waiting countdown is shown before deadline and alternatives stay hidden
- waiting countdown includes seconds and clamps expired time
- local countdown rebuilds 60 to 59 to 58 to 57 every second
- server deadline and server clock take precedence over remaining
- zero is clamped and refresh fires only once for the same window
- a new Backend deadline starts a new countdown and expiry refresh
- normal parent rebuilds do not reset the deadline or duplicate ticks
- background time jump is recalculated from deadline on resume
- expiry refresh waits for an in-flight status operation to finish
- new preference anchors a fresh remaining-only waiting window

ไม่แก้ Matching UI/behavior หรือ tests เดิมเพื่อบังคับให้ผ่านในงานนี้
ผลปัจจุบันจึงไม่ใช่ 196/196; ดู `FLUTTER_TESTS.log` และ `BACKEND_TESTS.log` สำหรับ evidence จริง
Backend tests รันด้วย Flutter test runner ของโครงงาน; package standalone วิเคราะห์/compile ผ่านแยกต่างหาก
Database integration tests ถูกข้ามโดยล้างเฉพาะ test-configuration environment ใน subprocess ไม่ได้แก้ `.env` หรือฐานข้อมูลใด

## Security/package audit

- ไม่อ่าน/พิมพ์ค่าจาก local `.env`, `gemini_key.txt`, `database_key.txt` และไม่ copy files เหล่านี้
- ใช้ allowlist จาก import dependency graph แทนการ copy ทั้งโครงงาน/server directory
- ไม่รวม database dump/backups/schema, test/work/audit folders, local payment evidence, private documents, uploaded profile files หรือ node_modules
- public package ไม่มี Flutter `lib/test/android/.dart_tool`, React `src`, `.env`, maps หรือ Backend source
- ก่อน build สแกน reachable Flutter source, Portal source และ web template; หลัง build สแกน package ทั้ง text/binary สำหรับ key patterns/private key/credential literals และ forbidden paths
- ตัว build มีเพียง public API URL ไม่มี DB password, Gemini key, SlipOK key หรือ PromptPay ID จริงที่ถูกส่งผ่าน build variables
- Backend `.env.example` มี placeholders เท่านั้น; secrets ให้ผู้ใช้กรอกเองใน private server directory ภายหลัง
- `backend/lib/dev/development_accounts.dart` เป็น dependency เดิมของ server สำหรับ fixtures การพัฒนา จึงยังอยู่ใน private runtime/source package ไม่อยู่ใน Web/Portal; production template ตั้ง `TRAVELIN_ENABLE_DEVELOPMENT_ACCOUNTS=0`
- พบ `http://localhost` แบบไม่มี port 2 จุดใน JS ของ Portal เป็น base URL ภายใน React Router URL parsing ไม่ใช่ API config; ส่วน API loopback ที่มี port ถูกตรวจว่าไม่เหลือใน main.dart.js/Portal bundle
- ไม่มีการลด CORS, Auth, amount/receiver validation หรือ duplicate protection
- การ scan แบบ pattern/allowlist ไม่ใช่การรับประกันว่าตรวจพบ secret ได้ทุกชนิด แต่ไม่พบค่าจริงหรือ credential files ในชุดที่เตรียมนี้

### ข้อจำกัดของ URL HTTP ที่มหาวิทยาลัยให้

Source ใช้ FlutterSecureStorage ใน `lib/services/saved_account_store.dart`
dependency ที่ติดตั้งจริง `flutter_secure_storage_web-2.1.1` ตรวจ `window.isSecureContext` และระบุว่ารองรับ HTTPS หรือ localhost
URL `http://202.28.34.205:8080/256/` ไม่ใช่ secure context ใน browser ตามปกติ จึงมีข้อจำกัดกับการอ่าน/บันทึก saved login/session บน Flutter Web
ให้มหาวิทยาลัยยืนยัน HTTPS URL/secure hosting ก่อนใช้งานเต็ม flow; ไม่ได้แก้ Auth/storage หรือ bypass ข้อกำหนดของ browser
Android ไม่ได้ใช้ Web storage plugin นี้ แต่ยังต้องตั้ง Public Backend URL ที่เข้าถึงได้

## Backend runtime ที่ตรวจจาก source

- entrypoint `server/gemini_proxy.dart`
- start source: `dart run server/gemini_proxy.dart` จาก backend root หลัง `dart pub get --enforce-lockfile`
- start compiled: `START_BACKEND.ps1 -Mode Executable` หลังผู้ใช้สร้าง private `.env` และกรอกค่าจริง
- executable target ที่สร้างจริง Windows x64, Dart 3.9.2; SDK ไม่จำเป็นต่อการรัน executable บน OS/architecture ที่ตรงกัน
- Server OS/architecture ยังไม่ยืนยัน; มี source package สำหรับ Dart SDK หรือ compile บน target จริง ไม่สมมุติว่า Server มี Dart
- bind `BIND_HOST=0.0.0.0` ในตัวอย่าง; port ต้องให้มหาวิทยาลัยกำหนด
- DB environment รองรับอยู่แล้ว: `DB_HOST/DB_PORT/DB_NAME/DB_USER/DB_PASSWORD`; ตั้ง production `db256` เฉพาะ template/launcher ไม่ hard-code ใน database service
- scheduler เดิม: destination-poll reconciliation ทุก 1 นาที; ไม่เปลี่ยน matching window, vote lifecycle หรือ scheduler behavior
- process environment สำหรับ Gemini, SlipOK, PromptPay, reviews, CORS, development policy และ optional Admin bootstrap ระบุใน `.env.example`
- file storage ต้อง persistent/writable และอยู่นอก web root; ไม่มี private media เดิมบรรจุมาด้วย
- `.env` ไม่ได้ถูกโหลดโดย Dart เอง; `START_BACKEND.ps1` โหลด values เข้า process โดยไม่แสดง secrets

## FileZilla mapping

- **เนื้อหาภายใน** `DEPLOY_256/web/` → `/256/`
- **เนื้อหาภายใน** `DEPLOY_256/portal/` → `/256/portal/`
- `DEPLOY_256/backend/` → private directory **นอก public web root** ที่มหาวิทยาลัยกำหนด; ไม่ใช่ `/256/backend/`
- ห้าม upload root ของ DEPLOY_256 ซึ่งมี reports/scripts/logs; upload เฉพาะ build directories ที่ระบุ
- Direct Portal routes ต้องมี server SPA fallback; ยังไม่ทราบ web server ชนิดใด จึงไม่สร้าง/ติดตั้ง config บน Server

## ยังขาดข้อมูลจากมหาวิทยาลัย

Backend port/Public Backend URL, OS/architecture, สิทธิ์รัน long-lived process/executable/SDK, firewall/routing, private storage path,
DB host/port/user/password, Gemini key, SlipOK credentials, PromptPay production receiver, Portal SPA fallback และ HTTPS URL
ไม่ควรเริ่มทดสอบ payment ก่อนกรอก config จริงและได้รับการยืนยันว่าพร้อม

## ไม่ได้ทำ

ไม่มี upload, FileZilla/FTP automation, SSH, แก้ Server, import/migrate/write university DB, real payment หรือเรียก SlipOK Live
ไม่แก้ Login/Auth business behavior, Matching Engine, 5-minute waiting/MM:SS, Alternative Destination, Absolute Majority,
Chat, Agency Bidding, Payment/PromptPay/SlipOK validation, Reviews หรือ Notifications
ไม่ได้ rewrite เป็น PHP, ไม่ restart MariaDB/Emulator/Flutter/Portal/Backend process ที่รันอยู่

เอกสารอ้างอิงของเครื่องมือ:
[Flutter Web](https://docs.flutter.dev/deployment/web),
[Vite public base](https://vite.dev/guide/build#public-base-path),
[Dart compile](https://dart.dev/tools/dart-compile),
[React Router BrowserRouter](https://reactrouter.com/api/declarative-routers/BrowserRouter)
