Skip to main content
Glama
README.md
# BKK Transit — Bangkok Open Transit Platform

<div align="center">

**แพลตฟอร์มข้อมูลขนส่งสาธารณะและระบบวางแผนการเดินทาง กรุงเทพฯ และปริมณฑล**  
*Open Transit Data Platform, Routing Engine, and Real-Time Tracking for the Bangkok Metropolitan Region*

[![CI](https://img.shields.io/badge/CI-GitHub%20Actions-277150?style=flat-square)](.github/workflows/ci.yml)
[![Python](https://img.shields.io/badge/python-3.10%2B-277150?style=flat-square)](pyproject.toml)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115%2B-009688?style=flat-square&logo=fastapi)](https://fastapi.tiangolo.com)
[![License: MIT](https://img.shields.io/badge/code-MIT-277150?style=flat-square)](LICENSE)
[![Data: CC-BY 4.0](https://img.shields.io/badge/data-CC--BY%204.0-277150?style=flat-square)](NOTICE.md)
[![Status](https://img.shields.io/badge/status-production%20ready%20v0.1.0-b45309?style=flat-square)](CHANGELOG.md)

[คุณสมบัติเด่น](#-คุณสมบัติเด่น-features) •
[ภาพตัวอย่างหน้าจอ](#-ภาพตัวอย่างหน้าจอ-screenshots-showcase) •
[เริ่มต้นใช้งานใน 3 นาที](#-เริ่มต้นใช้งานใน-3-นาที-quick-start) •
[ระบบ GPS และแผนที่](#-ระบบ-gps-และแผนที่ระบุพิกัด-gps--geolocation) •
[การรับมือเหตุฉุกเฉิน / API ดับ](#-การรับมือเหตุฉุกเฉิน-และการป้องกันเมื่อ-api-โดนตัด-resilience--disaster-recovery) •
[สถาปัตยกรรม](#-สถาปัตยกรรมระบบ-architecture) •
[API Reference](#-api-reference) •
[เอกสารประกอบ](#-เอกสารประกอบ-documentation)

</div>

---

## 📸 ภาพตัวอย่างหน้าจอ (Screenshots Showcase)

| 1. หน้าจอหลัก & แผนที่โครงข่ายขนส่งสาธารณะ | 2. ตรวจสอบแนวเส้นทางและตำแหน่งรถ |
|:---:|:---:|
| ![Bangkok Transit Network Overview](docs/images/01_bangkok_transit_overview.png) | ![Route Shape & Vehicles](docs/images/02_route_detail_and_shape.png) |
| *แสดงโครงข่ายรถไฟฟ้า รถเมล์ เรือ และตัวกรองหมวดหมู่สาย* | *แสดงแนวเส้นทาง polyline, ลำดับป้าย, เวลา offset และตำแหน่งรถ* |

| 3. ระบบ GPS เรดาร์ระบุพิกัด & ป้ายใกล้ฉัน | 4. ตารางเวลารถออกถัดไปที่สถานี |
|:---:|:---:|
| ![GPS Radar & Nearby Stops](docs/images/03_gps_nearby_stops.png) | ![Live Departures Board](docs/images/04_stop_departures_board.png) |
| *ปุ่ม GPS เรดาร์ วงแหวนความแม่นยำ และค้นหาป้ายในระยะ 500 ม.* | *เวลารถออกถัดไป ความถี่เดินรถ และสัญลักษณ์คนพิการ ♿* |

| 5. ระบบคำนวณและวางแผนการเดินทาง | 6. เอกสาร API โต้ตอบ (Swagger UI) |
|:---:|:---:|
| ![Trip Planner](docs/images/05_trip_planner.png) | ![Swagger UI Documentation](docs/images/06_fastapi_swagger_docs.png) |
| *คำนวณสายตรงและจุดต่อรถ พร้อมแสดงเส้นทางบนแผนที่* | *ทดสอบและตรวจสอบทุก Endpoint ผ่าน OpenAPI 3.1 มาตรฐาน* |

| 7. เอกสาร API สถาปัตยกรรม ReDoc | 8. หน้าจอสมาร์ทโฟน (Mobile Responsive) |
|:---:|:---:|
| ![ReDoc API Reference](docs/images/07_fastapi_redoc.png) | ![Mobile Responsive UI](docs/images/08_mobile_responsive.png) |
| *เอกสาร 3-panel สำหรับทีม Developer และการ Integrate* | *รองรับการเปิดใช้งานบนมือถือทุกขนาดหน้าจออย่างลื่นไหล* |

---

## 📌 บทนำและที่มาของโครงการ (Why BKK Transit?)

**ข้อเท็จจริงในปัจจุบัน:**  
ระบบขนส่งสาธารณะของกรุงเทพฯ มีความซับซ้อนสูง ประกอบด้วยรถเมล์ (ขสมก. และรถร่วมเอกชน เช่น Thai Smile Bus), รถไฟฟ้าหลากสี (BTS, MRT, ARL, SRTET), เรือด่วนเจ้าพระยา และเรือคลองแสนแสบ ทว่ายังไม่มี Public API ทางการที่เปิดเผยข้อมูลตำแหน่งรถแบบ Real-time สาธารณะ ข้อมูลส่วนใหญ่กระจายตัวอยู่ในแอปพลิเคชันเอกชนหรือระบบปิดภายใน

**สิ่งที่มีและใช้งานได้ถูกต้องตามกฎหมาย:**  
สำนักงานนโยบายและแผนการขนส่งและจราจร (สนข.) กระทรวงคมนาคม ได้เผยแพร่ชุดข้อมูล **GTFS Static** ของกรุงเทพฯ และปริมณฑล (สายรถเมล์, เรือ, รถไฟฟ้า, สถานี/ป้าย, เส้นทาง shape, ตารางความถี่) ภายใต้สัญญาอนุญาตเปิด **Creative Commons CC-BY 4.0** ผ่านระบบ "นำทาง (Namtang)"

**พันธกิจของโครงการ:**  
**BKK Transit** ถูกสร้างขึ้นเพื่อเป็นโครงสร้างพื้นฐานข้อมูลเปิด (Open Transit Infrastructure) ระดับมืออาชีพ:
1. นำเข้าข้อมูล GTFS Static มาตรฐานสากลเข้าสู่ฐานข้อมูลประสิทธิภาพสูง (SQLite สำหรับพัฒนา / PostGIS สำหรับ Production)
2. ให้บริการผ่าน REST API มาตรฐาน พร้อมเอกสาร Interactive Swagger/OpenAPI
3. มีหน้าจอแผนที่ Interactive Web Map (Leaflet.js) รองรับ **GPS ระบุตำแหน่งตนเอง** แบบเรดาร์ ค้นหาป้ายรอบตัว และวางแผนการเดินทาง
4. ออกแบบเลเยอร์ Real-time เป็นสถาปัตยกรรมแบบ Pluggable เพื่อรองรับการ "เสียบ" GTFS-RT ของจริงได้ทันทีเมื่อเจรจาข้อมูลกับหน่วยงานสำเร็จ โดยไม่ต้องรื้อระบบ
5. มี **ความทนทานต่อความล้มเหลว (Fault Tolerance & Resilience)** สูงสุด หาก API ภายนอกหรือระบบ Realtime ขัดข้อง ระบบจะตัดวงจรและทำงานต่อด้วยข้อมูลแคช/ตารางเดินรถได้ทันที 100%

---

## ✨ คุณสมบัติเด่น (Features)

| หมวดหมู่ | ความสามารถ | รายละเอียดทางเทคนิค |
|---|---|---|
| **GTFS Ingestion** | ประมวลผลข้อมูลขนส่งทางการ | สตรีมไฟล์ CSV ขนาดใหญ่แบบ Chunk-based, ตรวจสอบ Referential Integrity และสร้าง `ValidationReport` วิเคราะห์คุณภาพข้อมูล |
| **ค้นหาสายและป้าย** | ค้นหาแบบสองภาษา (ไทย/อังกฤษ) | ค้นหาเลขสาย, ชื่อสาย, ประเภทพาหนะ (รถเมล์/เรือ/ราง) และชื่อป้ายสถานี ค้นหาเร็วระดับมิลลิวินาที |
| **GPS & Nearby** | ระบุตำแหน่งและหาป้ายใกล้ฉัน | ปุ่ม GPS ค้นหาพิกัดผู้ใช้ แสดงหมุดเรดาร์ Pulsing Blue Dot + วงแหวนความแม่นยำ และดึงป้ายในรัศมี 500 เมตรอัตโนมัติ |
| **เวลารถออก (ETA)** | ตารางเวลา + ความถี่เดินรถ | คำนวณเวลาเข้าป้ายถัดไปจาก Headway (`frequencies.txt`) และตารางเวลาตายตัว พร้อมจุดเสียบ GTFS-RT |
| **วางแผนการเดินทาง** | Route Planning MVP | ค้นหาเส้นทางป้าย→ป้าย ทั้งแบบสายตรง และต่อรถ 1 ครั้ง (Pattern-based Transfer) |
| **Realtime Abstraction** | รองรับหลาย Provider | สลับระหว่าง `none`, `mock` (จำลองเพื่อทดสอบ UI), และ `gtfs-rt` (สำหรับเชื่อมต่อ Protobuf จริง) |
| **AI & MCP Ready** | พร้อมเชื่อมต่อโมเดล AI (ChatGPT, Gemini, Claude) | มี Model Context Protocol (MCP) Server ในตัว และมาตรฐาน `/llms.txt` ช่วยให้ AI ค้นหารถเมล์ได้แม่นยำ 100% ไม่มโน |
| **ความพร้อมใช้งาน** | High Availability & Resilience | มี Circuit Breaker และ Graceful Degradation อัตโนมัติเมื่อ Upstream ขัดข้อง |
| **Offline Demo** | ทำงานได้โดยไม่ต้องมีเซิร์ฟเวอร์ | ไฟล์ `dist/demo.html` รวมข้อมูลและ JavaScript ไว้ในไฟล์เดียว สามารถเปิดดูบนเบราว์เซอร์ออฟไลน์ได้ทันที |

---

## 🚀 เริ่มต้นใช้งานใน 3 นาที (Quick Start)

### วิธีที่ 1: โหมดพัฒนาเบาพิเศษ (Zero-Dependency Dev Server)
ใช้เพียง Python มาตรฐาน (stdlib) ไม่ต้องติดตั้งไลบรารีภายนอก:

```bash
# 1. โคลนคลังโค้ด
git clone https://github.com/your-org/bkk-transit.git
cd bkk-transit

# 2. นำเข้าข้อมูลตัวอย่าง GTFS เข้า SQLite (data/transit.db)
python -m app.gtfs_loader --path data/gtfs_sample --report reports/gtfs_report.json
# หรือใช้ make sample

# 3. สตาร์ท Dev Server
python -m app.devserver --port 8000
# หรือใช้ make dev

# 4. เปิดเบราว์เซอร์: http://localhost:8000
```

### วิธีที่ 2: โหมด FastAPI + Uvicorn (พร้อม Interactive Swagger Docs)
เหมาะสำหรับการพัฒนา API และทดสอบ Endpoint:

```bash
# 1. สร้าง Virtual Environment
python -m venv .venv
source .venv/bin/activate  # บน Windows: .venv\Scripts\activate

# 2. ติดตั้ง Dependencies
pip install -r requirements.txt

# 3. รันเซิร์ฟเวอร์แบบ Hot-Reload
python -m uvicorn app.api.main:app --reload --port 8000
# หรือใช้ make api

# เข้าใช้งาน:
# - หน้าเว็บแผนที่: http://localhost:8000
# - API Swagger Docs: http://localhost:8000/docs
# - API Redoc: http://localhost:8000/redoc
```

### วิธีที่ 3: โหมด Production ด้วย Docker Compose + PostGIS
เหมาะสำหรับ Production ที่ต้องการดาวน์โหลดข้อมูล GTFS ฉบับเต็มจาก สนข. และเปิดใช้ Spatial Database:

```bash
cp .env.example .env     # ปรับตั้งค่ารหัสผ่านฐานข้อมูลใน .env
docker compose up -d db  # สตาร์ท PostgreSQL + PostGIS
docker compose run --rm loader  # ดาวน์โหลด GTFS ฉบับเต็มจาก สนข. และโหลดเข้า DB
docker compose up -d api # สตาร์ท FastAPI Service
```

---

## 📍 ระบบ GPS และแผนที่ระบุพิกัด (GPS & Geolocation)

ระบบมีฟังก์ชันระบุตำแหน่งผู้ใช้บนแผนที่อย่างสมบูรณ์แบบ:

1. **ปุ่มค้นหาตำแหน่งลอย (Floating GPS Control):** ไอคอนเป้าเล็ง 🎯 อยู่มุมขวาบนของแผนที่ สามารถกดเรียกพิกัดได้ตลอดเวลา
2. **หมุดระบุตำแหน่งเรดาร์ (Pulsing Location Pin):** เมื่อได้พิกัด แผนที่จะแสดงจุดวงกลมสีน้ำเงินพร้อมแอนิเมชันคลื่นเรดาร์ขยายตัว (Wave Ripple Effect)
3. **วงแหวนความแม่นยำ (Accuracy Radius):** วาดวงกลมรัศมีความคลาดเคลื่อนจริงตามที่ดาวเทียม GPS รายงาน
4. **ค้นหาป้ายรอบตัวอัตโนมัติ (Auto-Discovery):** ซูมแผนที่เข้าสู่ตำแหน่งปัจจุบัน (`map.flyTo`) และค้นหาป้าย/สถานีรถไฟฟ้า/ท่าเรือในรัศมี 500 เมตร พร้อมคำนวณระยะเดินให้ทันที
5. **ความปลอดภัยและข้อกำหนด (HTTPS Requirement):**  
   ตามมาตรฐาน W3C Geolocation API เบราว์เซอร์จะอนุญาตให้ใช้งาน GPS ได้เฉพาะบน **HTTPS** หรือ `http://localhost` เท่านั้น หากรันบน IP ภายนอกต้องติดตั้ง Reverse Proxy SSL เสมอ  
   *(อ่านคู่มือการตั้งค่าและการแก้ปัญหาโดยละเอียดได้ที่ [docs/GPS_GEOLOCATION_GUIDE.md](docs/GPS_GEOLOCATION_GUIDE.md))*

---

## 🛡️ การรับมือเหตุฉุกเฉิน และการป้องกันเมื่อ API โดนตัด (Resilience & Disaster Recovery)

โครงการนี้ถูกออกแบบโดยคำนึงถึงปัญหาความเสถียรของแหล่งข้อมูลภายนอก (Upstream Outage) และสถานการณ์ฉุกเฉินในระบบ Production อย่างรัดกุม:

### 1. ถ้า API หรือ Feed ของ สนข. / ขสมก. โดนตัดหรือหยุดให้บริการ เราจะรู้ได้อย่างไร และป้องกันอย่างไร?
- **การตรวจจับล่วงหน้า (Proactive Synthetic Monitoring):** มีสคริปต์ตรวจเช็คความพร้อมของ Feed ต้นทางเป็นระยะ (HTTP HEAD, ETag, Content-Length) และตรวจสอบวันหมดอายุของข้อมูล (`feed_end_date`) ล่วงหน้า 30 วัน พร้อมส่งแจ้งเตือนผ่าน Discord / LINE / Slack Webhook
- **สถาปัตยกรรมตัดขาด Upstream (Ingestion Architecture):** เซิร์ฟเวอร์ **ไม่ได้เรียก API ไปยัง สนข. สดๆ ทุก Request** แต่ใช้วิธี Ingestion เข้าฐานข้อมูล Local Snapshot (PostGIS/SQLite) ไว้ล่วงหน้า ดังนั้น **แม้เว็บ สนข. จะล่ม ระบบ BKK Transit ก็ยังให้บริการได้ 100%**
- **Circuit Breaker สำหรับ Realtime Feed:** หาก Feed ตำแหน่งรถ (GTFS-RT) ล่มหรือ Timeout ติดต่อกันเกิน 3 ครั้ง วงจรจะตัดทันทีเพื่อป้องกันเซิร์ฟเวอร์ค้าง และสลับไปใช้ **ตารางเดินรถปกติ (Schedule Fallback)** พร้อมติดป้ายแจ้งสถานะให้ผู้ใช้ทราบอย่างโปร่งใส

### 2. ถ้าเซิร์ฟเวอร์หรือฐานข้อมูล Crash จะรับมืออย่างไร?
- **Docker Auto-Recovery:** กำหนด `restart: unless-stopped` และมี Docker Healthcheck Probe คอยตรวจจับสถานะ
- **SQLite WAL Mode:** เปิดใช้งาน Write-Ahead Logging เพื่อรองรับการอ่านข้อมูลพร้อมกันได้ไม่จำกัด โดยไม่เกิดปัญหา Database Lock
- **PostgreSQL Connection Pool:** ควบคุม Connection ผ่าน `psycopg 3` และป้องกัน Memory Leak ด้วยการสตรีมข้อมูล
- **RTO < 3 นาที:** สามารถสร้างฐานข้อมูลใหม่จากไฟล์ตัวอย่างหรือ Snapshot สำรองได้ภายในไม่กี่นาที

*(อ่านรายละเอียดขั้นตอนปฏิบัติการฉุกเฉินและ Runbook ทั้งหมดได้ที่ [docs/OPERATIONS_AND_RESILIENCE.md](docs/OPERATIONS_AND_RESILIENCE.md))*

---

## 🤖 การเชื่อมต่อกับ AI และ Model Context Protocol (MCP)

ในยุคปัจจุบัน ผู้ใช้งานส่วนใหญ่นิยมพิมพ์สอบถามเส้นทางรถเมล์และการเดินทางผ่าน **AI เช่น ChatGPT, Gemini, หรือ Claude** ทว่าโมเดลภาษาทั่วไปมัก **ตอบข้อมูลเก่าก่อนปฏิรูปสาย หรือมโน (Hallucinate) ลำดับป้ายจอด**

**BKK Transit** จึงถูกออกแบบให้เป็น **ฐานข้อมูลความจริง (Ground-Truth Knowledge Base)** สำหรับ AI:

1. **รองรับ Model Context Protocol (MCP):**  
   มีเซิร์ฟเวอร์ MCP ในตัว (`app/mcp_server.py`) ที่รองรับ **Claude Desktop**, **Cursor IDE**, **Antigravity** และ AI Agents ทุกค่าย โดยมี Tools ให้ AI เรียกใช้งาน:
   - `search_transit_routes` — ค้นหาสายรถเมล์ เรือ รถไฟฟ้า
   - `get_route_details` — ดึงลำดับป้ายและทิศทางเดินรถที่ถูกต้อง 100%
   - `search_stops` — ค้นหาป้ายรถเมล์หรือสถานี BTS/MRT
   - `find_nearby_stops` — ค้นหาป้ายรอบพิกัด GPS
   - `get_next_departures` — ตรวจสอบเวลารถออกถัดไปและความถี่
   - `plan_transit_journey` — วางแผนการเดินทางระหว่างป้าย
2. **สร้าง Custom GPTs บน ChatGPT ผ่าน Actions:**  
   นำ URL `http://localhost:8000/openapi.json` ไปใส่ใน Custom GPT Action เพื่อสร้าง AI ผู้ช่วยนำทางรถเมล์ไทยได้ทันที
3. **มาตรฐาน `/llms.txt` สำหรับ AI Web Search:**  
   มี Endpoint `/llms.txt` ตามมาตรฐานสากล เพื่อให้ Search Engine AI (เช่น Perplexity หรือ SearchGPT) ดึงข้อมูลไปตอบได้อย่างแม่นยำ

*(อ่านคู่มือการเชื่อมต่อ AI ทุกแพลตฟอร์มโดยละเอียดได้ที่ [docs/AI_INTEGRATION_GUIDE.md](docs/AI_INTEGRATION_GUIDE.md))*

---

## 🏗 สถาปัตยกรรมระบบ (Architecture)

```mermaid
flowchart LR
  subgraph Sources["แหล่งข้อมูลภายนอก"]
    G["GTFS Static<br/>สนข. Namtang · CC-BY 4.0"]
    RT[("Realtime Feeds<br/>GTFS-RT: NECTEC / ขสมก.")]
  end

  subgraph Ingestion["การนำเข้าและตรวจสอบข้อมูล"]
    L["gtfs_loader.py<br/>Stream Ingestion · ValidationReport"]
  end

  subgraph Storage["การจัดเก็บข้อมูล"]
    DB[("SQLite dev / PostgreSQL + PostGIS prod")]
  end

  subgraph Core["บริการหลัก (Services)"]
    S["Stops · Routes · Departures · Planner · Geo · Calendar"]
    P["Realtime Provider<br/>Null · Mock · GTFS-RT"]
  end

  subgraph API_Layer["ชั้น API และการส่งข้อมูล"]
    H["api/handlers.py<br/>Framework-agnostic Logic"]
    F["FastAPI Backend<br/>/api/* · /docs"]
    D["devserver.py<br/>Python Stdlib"]
    B["scripts/build_demo.py<br/>Standalone Snapshot Builder"]
  end

  subgraph Clients["ส่วนแสดงผล"]
    UI["Web Map UI<br/>Leaflet.js + GPS Radar Pin"]
    Demo["dist/demo.html<br/>Single-file Offline Demo"]
  end

  G --> L
  L --> DB
  DB --> S
  RT -.-> P
  S --> H
  P --> H
  H --> F
  H --> D
  H --> B
  F --> UI
  B --> Demo
```

---

## 🔌 API Reference

Base URL สำหรับการทดสอบในเครื่อง: `http://localhost:8000`  
ทุก Endpoint ทำงานผ่าน HTTP Method `GET` และตอบกลับเป็น JSON UTF-8

| Endpoint | คำอธิบาย | พารามิเตอร์สำคัญ | ตัวอย่างคำสั่ง |
|---|---|---|---|
| `GET /api/health` | ตรวจสอบสถานะการทำงาน (Liveness Probe) | — | `curl localhost:8000/api/health` |
| `GET /api/meta` | ข้อมูลสัญญาอนุญาต สถิติจำนวนสาย/ป้าย และเวอร์ชัน Feed | — | `curl localhost:8000/api/meta` |
| `GET /api/routes` | ค้นหารายชื่อสายรถเมล์ เรือ รถไฟฟ้า | `q`, `route_type`, `agency_id`, `limit`, `offset` | `curl "localhost:8000/api/routes?q=101"` |
| `GET /api/routes/{id}` | รายละเอียดสาย: ทิศทาง ลำดับป้าย พิกัดเส้นทาง (shape) | `route_id` | `curl localhost:8000/api/routes/1` |
| `GET /api/routes/{id}/vehicles` | พิกัดตำแหน่งรถ Realtime ของสายนั้น | `route_id` | `curl localhost:8000/api/routes/1/vehicles` |
| `GET /api/stops` | รายชื่อป้ายในกรอบพิกัด หรือดึงข้อมูลภาพรวม | `bbox=min_lat,min_lon,max_lat,max_lon`, `limit` | `curl "localhost:8000/api/stops?limit=100"` |
| `GET /api/stops/search` | ค้นหาป้ายจากชื่อ (รองรับภาษาไทย/อังกฤษ) | `q` (อย่างน้อย 2 ตัวอักษร), `limit` | `curl "localhost:8000/api/stops/search?q=สยาม"` |
| `GET /api/stops/nearby` | ค้นหาป้ายใกล้พิกัดพิกัด GPS ที่ระบุ | `lat`, `lon`, `radius_m` (ค่าเริ่มต้น 500m) | `curl "localhost:8000/api/stops/nearby?lat=13.7456&lon=100.5347"` |
| `GET /api/stops/{id}` | ข้อมูลป้ายและรายชื่อสายที่แล่นผ่าน | `stop_id` | `curl localhost:8000/api/stops/12` |
| `GET /api/stops/{id}/departures` | เวลารถออกถัดไปจากป้าย (Schedule + Realtime) | `at` (ISO 8601), `window_min`, `limit` | `curl "localhost:8000/api/stops/12/departures"` |
| `GET /api/plan` | วางแผนการเดินทางระหว่างป้าย (ตรงหรือต่อ 1 ครั้ง) | `from`, `to`, `max_results` | `curl "localhost:8000/api/plan?from=214&to=245"` |

---

## ⚙️ ตัวแปรสภาพแวดล้อม (Environment Variables)

กำหนดค่าได้ผ่านไฟล์ `.env` หรือส่งผ่าน Environment ของ Container:

| ตัวแปร | ค่าเริ่มต้น | รายละเอียด |
|---|---|---|
| `DATABASE_URL` | `sqlite:///./data/transit.db` | URL ฐานข้อมูล (`sqlite:///...` หรือ `postgresql://user:pass@host:5432/db`) |
| `GTFS_URL` | URL ของ สนข. (Namtang) | ลิงก์ดาวน์โหลด GTFS Static .zip ทางการ |
| `REALTIME_PROVIDER` | `mock` | เลือกระบบ Realtime: `none`, `mock` (ข้อมูลจำลอง), หรือ `gtfs-rt` |
| `GTFS_RT_VEHICLE_URL` | `""` | URL ของ GTFS-RT VehiclePositions Protobuf feed |
| `GTFS_RT_TRIP_URL` | `""` | URL ของ GTFS-RT TripUpdates Protobuf feed |
| `CORS_ORIGINS` | `*` | โดเมนที่อนุญาตให้เรียก API ผ่านเว็บเบราว์เซอร์ |

---

## 🧪 การทดสอบและควบคุมคุณภาพ (Testing & Quality)

โครงการนี้มี Unit Test ครอบคลุมทั้ง Ingestion Loader, Geo Math, Routing Planner, Realtime Provider และ HTTP Endpoints:

```bash
# รันชุดทดสอบทั้งหมด
make test
# หรือ: python -m unittest -v

# ตรวจสอบรูปแบบโค้ด (Linting)
make lint
# หรือ: ruff check app tests
```

---

## 📚 เอกสารประกอบ (Documentation)

| เอกสาร | รายละเอียด |
|---|---|
| [docs/OPERATIONS_AND_RESILIENCE.md](docs/OPERATIONS_AND_RESILIENCE.md) | **คู่มือปฏิบัติการฉุกเฉิน (Runbook):** การรับมือเมื่อ API โดนตัด, การตั้งระบบแจ้งเตือน, Circuit Breaker |
| [docs/GPS_GEOLOCATION_GUIDE.md](docs/GPS_GEOLOCATION_GUIDE.md) | **คู่มือระบบระบุตำแหน่ง GPS:** การทำงานของ W3C Geolocation, การตั้งค่า HTTPS, การทดสอบด้วย DevTools |
| [docs/AI_INTEGRATION_GUIDE.md](docs/AI_INTEGRATION_GUIDE.md) | **คู่มือการเชื่อมต่อ AI & MCP:** เชื่อมต่อ Claude Desktop, Cursor, ChatGPT Custom GPTs, และ Gemini |
| [docs/API.md](docs/API.md) | ข้อกำหนดสัญญา API ฉบับเต็ม พร้อมตัวอย่าง JSON Request/Response ทุกเส้นทาง |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | สถาปัตยกรรมระบบโดยละเอียด Data Flow Diagram และการออกแบบฐานข้อมูล |
| [docs/DATA.md](docs/DATA.md) | ที่มาของข้อมูล GTFS, คุณภาพข้อมูล, ข้อจำกัดที่พบ และรอบการอัปเดต |
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | คู่มือการติดตั้งบน Production, การตั้งค่า Caddy HTTPS, Backup & Restore |
| [docs/FEASIBILITY.md](docs/FEASIBILITY.md) | รายงานการศึกษาความเป็นไปได้และข้อจำกัดเชิงเทคนิคของระบบขนส่งมวลชนไทย |
| [docs/ROADMAP.md](docs/ROADMAP.md) | แผนการพัฒนาในอนาคต (Phase 0 ถึง Phase 4) |
| [docs/adr/](docs/adr/) | Architecture Decision Records (บันทึกการตัดสินใจทางสถาปัตยกรรม 0001–0006) |
| [NOTICE.md](NOTICE.md) | การให้เกียรติแหล่งข้อมูลและสัญญาอนุญาต (Attribution & Legal Notices) |

---

## 📄 สัญญาอนุญาตและลิขสิทธิ์ (License & Attribution)

- **Source Code:** เผยแพร่ภายใต้สัญญาอนุญาต [MIT License](LICENSE) © 2026 Synergy Technology Co., Ltd. (SynTech)
- **Transit Data:** ข้อมูลการเดินรถและเส้นทางขนส่งมวลชน เผยแพร่ภายใต้สัญญาอนุญาต **Creative Commons Attribution 4.0 International (CC-BY 4.0)** โดย **สำนักงานนโยบายและแผนการขนส่งและจราจร (สนข.) กระทรวงคมนาคม** ผ่านระบบ "นำทาง (Namtang)"
- **Basemap Tiles:** แผนที่ฐาน © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors