// Package api is OpenMail's agent-facing HTTP surface: the AgentMail-shaped v0 // REST API (see ARCHITECTURE.md ยง4). v0 routes are stubbed pending the core // services; health and auth are real. package api import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/karti-ai/openmail/internal/config" "github.com/karti-ai/openmail/internal/store" ) type Server struct { cfg config.Config store *store.Store } func New(cfg config.Config, st *store.Store) *Server { return &Server{cfg: cfg, store: st} } func (s *Server) Router() http.Handler { r := chi.NewRouter() r.Use(middleware.RequestID) r.Use(middleware.RealIP) r.Use(middleware.Recoverer) // Unauthenticated liveness/readiness. r.Get("/healthz", s.handleHealth) // Authenticated v0 surface. r.Group(func(r chi.Router) { r.Use(s.bearerAuth) r.Route("/v0/inboxes", func(r chi.Router) { r.Post("/", notImplemented) // create inbox r.Get("/", notImplemented) // list inboxes r.Get("/{id}", notImplemented) // get inbox r.Post("/{id}/messages/send", notImplemented) r.Get("/{id}/messages", notImplemented) r.Get("/{id}/messages/{msgID}", notImplemented) r.Post("/{id}/messages/{msgID}/reply", notImplemented) r.Get("/{id}/threads", notImplemented) r.Get("/{id}/threads/{threadID}", notImplemented) }) }) return r } func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { status := map[string]any{"status": "ok"} if s.store != nil { if err := s.store.Pool.Ping(r.Context()); err != nil { status["status"] = "degraded" status["db"] = err.Error() writeJSON(w, http.StatusServiceUnavailable, status) return } status["db"] = "ok" } else { status["db"] = "not configured" } writeJSON(w, http.StatusOK, status) } func notImplemented(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusNotImplemented, map[string]string{ "error": "not_implemented", "message": "endpoint scaffolded; core service pending (milestone 1)", }) } func writeJSON(w http.ResponseWriter, code int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) _ = json.NewEncoder(w).Encode(v) }