vtrc-ocr-api — Endpoint Catalog
บทนี้ (branch: main) เอกสาร ทุก HTTP surface ที่ process เปิดรับ — รวม static, Swagger, health, OCR, และ 404/error
Global middleware ทุก request (ยกเว้นก่อน mount ตามลำดับใน app.js):
helmet()—app.js:15cors()— ไม่มี origin allowlist —app.js:16morgan('dev')—app.js:17express.json()—app.js:18express.urlencoded({ extended: true })—app.js:19
Auth: ไม่มีทุก endpoint
1. GET / — Landing page
| Item | Detail |
|---|---|
| Handler | inline res.sendFile(public/index.html) |
| Citation | app.js:36-38 |
| Response | HTML |
| Auth | ไม่มี |
หน้า landing ลิงก์ไป /health, /api, /api/health/detailed (public/index.html)
2. Static files
| Item | Detail |
|---|---|
| Mount | express.static(public/) |
| Citation | app.js:22 |
| Files in repo | public/index.html เท่านั้น |
3. GET /docs — Swagger UI
| Item | Detail |
|---|---|
| Handler | swaggerUi.serve + setup(swaggerSpec, { explorer: true }) |
| Citation | app.js:25 |
| Spec source | docs/swagger.js (OpenAPI 3.0.0, title VTRC OCR API) |
| Server URL ใน spec | http://localhost:{config.port} — docs/swagger.js:14-17 |
4. GET /docs.json — Raw OpenAPI
| Item | Detail |
|---|---|
| Handler | inline send swaggerSpec |
| Citation | app.js:26-29 |
| Content-Type | application/json |
5. GET /health — Top-level health (นอก /api)
| Item | Detail |
|---|---|
| Handler | inline ใน app.js |
| Citation | app.js:41-47 |
Response 200:
{
"status": "OK",
"message": "Server is running",
"timestamp": "<ISO>"
}ต่างจาก /api/health ทั้ง shape และ path — มีสอง health surface
6. GET /api — API root metadata
| Item | Detail |
|---|---|
| Route file | routes/index.js:35-44 |
| Swagger tag | General (index.js:13-33) |
Response 200:
{
"message": "VTRC OCR API",
"version": "1.0.0",
"endpoints": {
"health": "/api/health",
"ocr": "/api/ocr"
}
}version จาก config.api.version (config.js:11)
7. GET /api/health — Basic API health
| Item | Detail |
|---|---|
| Mount | router.use('/health', healthRoutes) — routes/index.js:10 |
| Route | GET / บน health router — health.routes.js |
| Controller | healthController.checkHealth — health.controller.js:3-13 |
| Service | getHealthStatus() — health.service.js:1-8 |
Response 200:
{
"status": "healthy",
"timestamp": "<ISO>",
"uptime": <number>,
"environment": "<NODE_ENV or development>"
}Response 500:
{ "error": "Health check failed", "message": "<error.message>" }(health.controller.js:8-11)
หมายเหตุ: response นี้ไม่มี wrapper { success, data } ต่างจาก OCR controllers
8. GET /api/health/detailed — Detailed health
| Item | Detail |
|---|---|
| Route | health.routes.js detailed path |
| Controller | getDetailedHealth — health.controller.js:15-25 |
| Service | health.service.js:10-24 |
Response 200:
{
"status": "healthy",
"timestamp": "<ISO>",
"uptime": <number>,
"environment": "<string>",
"memory": { "used": <MB>, "total": <MB>, "unit": "MB" },
"nodeVersion": "<process.version>",
"platform": "<process.platform>"
}Response 500:
{ "error": "Detailed health check failed", "message": "<error.message>" }ไม่ตรวจ DB/OCR dependency (ยังไม่มีให้ตรวจ)
9. POST /api/ocr/process — Submit OCR job (MOCKED)
| Item | Detail |
|---|---|
| Route | ocr.routes.js:38 |
| Middleware | validateOCRRequest |
| Controller | processOCR — ocr.controller.js:3-18 |
| Service | processImage — ocr.service.js:6-41 |
Request body
| Field | Type | Required | Validation | Citation |
|---|---|---|---|---|
image | string | ใช่ | notEmpty + isString (ข้อความบอกว่า base64 แต่ไม่ verify) | validation.middleware.js:4-8, swagger OCRRequest |
options | object | ไม่ | optional isObject | validation.middleware.js:9-12 |
Response 200
{
"success": true,
"data": {
"processingId": "ocr_<timestamp>_<random>",
"status": "processing",
"message": "OCR processing started"
}
}(ocr.controller.js:8-11, return shape ocr.service.js:36-40)
Response 400 (validation)
{ "success": false, "errors": [ /* express-validator */ ] }Response 400 (service)
{ "success": false, "error": "Image is required" }Response 500
{ "success": false, "error": "<message or 'OCR processing failed'>" }หลัง 1 วินาที record ใน Map ถูกอัปเดตเป็น completed ด้วย text/confidence คงที่ — ดู 02-core-pipeline
10. GET /api/ocr/status/:id — Poll status
| Item | Detail |
|---|---|
| Route | ocr.routes.js:61 |
| Controller | getStatus — ocr.controller.js:20-35 |
| Service | getProcessingStatus — ocr.service.js:43-51 |
| Path param | id string |
Response 200
{ "success": true, "data": <record> }record ตาม lifecycle processing → completed (mock fields ตาม swagger OCRStatusResponse: id, status, text, confidence, createdAt, completedAt — docs/swagger.js:35-45)
Response 404
{ "success": false, "error": "Processing record not found" }(ocr.service.js:46-48, controller ใช้ error.status || 404)
11. GET /api/ocr/history — Paginated history
| Item | Detail |
|---|---|
| Route | ocr.routes.js:84 |
| Controller | getHistory — ocr.controller.js:37-52 |
| Service | getProcessingHistory — ocr.service.js:53-67 |
Query params
| Param | Default | Validation | Citation |
|---|---|---|---|
page | 1 | ไม่มี (string จาก query → parseInt ท้ายทาง) | ocr.controller.js:39, swagger default 1 |
limit | 10 | ไม่มี | 同上 |
Response 200
{
"success": true,
"data": {
"records": [ /* newest first */ ],
"pagination": {
"page": <int>,
"limit": <int>,
"total": <int>,
"totalPages": <int>
}
}
}Response 500
{ "success": false, "error": "<message or 'Failed to retrieve history'>" }12. Catch-all 404
| Item | Detail |
|---|---|
| Handler | app.js:50-55 |
| Response | { "error": "Not Found", "message": "Route <originalUrl> not found" } |
| Status | 404 |
13. Global error handler (inline)
| Item | Detail |
|---|---|
| Handler | app.js:58-64 |
| Response | { "error": <message>, "stack"?: <dev only> } |
| Status | err.status || 500 |
middleware/error.middleware.js มี errorHandler / asyncHandler แต่ไม่ถูก mount — dead code
สรุปตาราง endpoint
| Method | Path | Mock/Real | Auth |
|---|---|---|---|
| GET | / | HTML static | ไม่มี |
| GET | /docs | Swagger UI | ไม่มี |
| GET | /docs.json | OpenAPI JSON | ไม่มี |
| GET | /health | process alive | ไม่มี |
| GET | /api | metadata | ไม่มี |
| GET | /api/health | process metrics | ไม่มี |
| GET | /api/health/detailed | + memory/node | ไม่มี |
| POST | /api/ocr/process | MOCK | ไม่มี |
| GET | /api/ocr/status/:id | in-memory read | ไม่มี |
| GET | /api/ocr/history | in-memory list | ไม่มี |
| * | (unmatched) | 404 JSON | ไม่มี |
Example curl (local default port 3000)
# metadata
curl -s http://localhost:3000/api
# submit mock job
curl -s -X POST http://localhost:3000/api/ocr/process \
-H 'Content-Type: application/json' \
-d '{"image":"dGVzdA==","options":{}}'
# poll (แทน {id} ด้วย processingId จากคำตอบ)
curl -s http://localhost:3000/api/ocr/status/{id}
# history
curl -s 'http://localhost:3000/api/ocr/history?page=1&limit=10'ผล text หลัง completed จะเป็น 'Sample OCR result text' เสมอ — ไม่ขึ้นกับเนื้อหา image