# Checkpoint 001 — Project Scaffold **Ngày:** 2026-04-24 **Trạng thái:** ✅ Hoàn thành **Verify:** `go build ./...` thành công, không lỗi --- ## Việc đã làm ### 1. Khởi tạo Go module ``` go mod init github.com/thuanle/claw-email ``` ### 2. Tạo cấu trúc thư mục ``` claw-email/ ├── cmd/bridge/main.go # Entrypoint ├── internal/ │ ├── config/config.go # Đọc .env, validate required vars │ ├── database/ │ │ ├── database.go # Open SQLite + auto-migrate + health check │ │ └── models.go # Task model (đầy đủ schema từ requirements) │ ├── logging/logger.go # Structured JSON logging (slog) │ ├── api/router.go # Gin router: /healthz, /readyz │ ├── mail/mail.go # [stub] IMAP ingress + SMTP egress │ └── ai_client/client.go # [stub] OpenClaw HTTP dispatch ├── .env.example ├── .gitignore ├── Dockerfile # Multi-stage, CGO_ENABLED=0 ├── docker-compose.yml # Named volume cho SQLite ├── go.mod / go.sum └── requirements.md ``` ### 3. Kết nối SQLite + auto-migrate bảng `tasks` - Driver: `github.com/glebarez/sqlite` (pure Go, wraps `modernc.org/sqlite`) - WAL mode enabled - Auto-migrate bảng `tasks` khi khởi động - Health check: `SELECT 1` ### 4. Module config (.env) - Dùng `github.com/joho/godotenv` load `.env` - Validate tất cả biến bắt buộc, trả lỗi rõ ràng nếu thiếu - Parse `WHITELIST_EMAILS` (comma-separated) - Default `LISTEN_ADDR=:8080` ### 5. Structured Logging - Dùng `log/slog` (Go stdlib 1.21+), JSON handler ra stdout - Helper `TaskLogger(taskUUID, threadID, messageID)` — mọi log liên quan task đều có context ### 6. API endpoints (Gin) - `GET /healthz` → `200 {"status":"ok"}` (liveness) - `GET /readyz` → kiểm tra DB writable + config token (readiness) ### 7. Docker - **Dockerfile**: Multi-stage, `golang:1.23-alpine` → `alpine:3.20`, `CGO_ENABLED=0` - **docker-compose.yml**: Named volume `bridge-data:/app/data`, `env_file: .env` --- ## Quyết định thiết kế | Quyết định | Lý do | |---|---| | `glebarez/sqlite` thay vì `gorm.io/driver/sqlite` | Pure Go, không cần CGO → Docker build đơn giản | | `log/slog` thay vì zap/logrus | Stdlib, zero dependency, đủ dùng | | `gin-gonic/gin` | Đúng requirements, nhẹ, phổ biến | | WAL mode SQLite | Tăng throughput đọc concurrent | | `internal/` layout | Chuẩn Go, ngăn import từ bên ngoài | ## Dependencies (go.mod) ``` github.com/gin-gonic/gin v1.12.0 github.com/glebarez/sqlite v1.11.0 (→ modernc.org/sqlite) github.com/joho/godotenv v1.5.1 gorm.io/gorm v1.31.1 ``` --- ## Tiếp theo (chưa implement) 1. IMAP Ingress — IDLE, anti-loop, whitelist, idempotency, threading 2. OpenClaw Dispatch — HTTP POST, retry 3 lần (1s/5s/15s) 3. Callback handler — webhook xác thực token, cập nhật task 4. SMTP Egress — gửi reply, In-Reply-To/References, retry 5. Integration tests — 6 scenarios từ requirements