// Package api provides the REST + WebSocket API for the bot dashboard. // // Endpoints: // GET /api/status — bot status, current state, routine, stats // GET /api/config — current configuration // PUT /api/config — update configuration // POST /api/start — start bot with routine // POST /api/stop — stop bot // POST /api/pause — pause/resume // GET /api/routines — list available routines // GET /api/loot/rules — get loot filter rules // PUT /api/loot/rules — update loot filter rules // GET /api/stats — run statistics, items found, etc. // WS /api/ws — real-time status stream // // The API is served by the bot process itself (single binary). package api import ( "encoding/json" "net/http" "sync" ) // Status represents the current bot status. type Status struct { Running bool `json:"running"` Paused bool `json:"paused"` GameState string `json:"gameState"` Routine string `json:"routine,omitempty"` Phase string `json:"phase,omitempty"` RunCount int `json:"runCount"` ItemsFound int `json:"itemsFound"` Uptime string `json:"uptime"` CaptureFPS float64 `json:"captureFps"` HealthPct float64 `json:"healthPct"` ManaPct float64 `json:"manaPct"` } // Server provides the HTTP API and WebSocket endpoint. type Server struct { mu sync.RWMutex status Status addr string mux *http.ServeMux } // NewServer creates an API server on the given address. func NewServer(addr string) *Server { s := &Server{ addr: addr, mux: http.NewServeMux(), } s.registerRoutes() return s } // Start begins serving the API. func (s *Server) Start() error { return http.ListenAndServe(s.addr, s.mux) } // UpdateStatus updates the bot status (called by the engine). func (s *Server) UpdateStatus(status Status) { s.mu.Lock() defer s.mu.Unlock() s.status = status // TODO: Broadcast to WebSocket clients } func (s *Server) registerRoutes() { s.mux.HandleFunc("GET /api/status", s.handleStatus) s.mux.HandleFunc("POST /api/start", s.handleStart) s.mux.HandleFunc("POST /api/stop", s.handleStop) // TODO: Remaining routes } func (s *Server) handleStatus(w http.ResponseWriter, r *http.Request) { s.mu.RLock() defer s.mu.RUnlock() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(s.status) } func (s *Server) handleStart(w http.ResponseWriter, r *http.Request) { // TODO: Signal engine to start w.WriteHeader(http.StatusAccepted) } func (s *Server) handleStop(w http.ResponseWriter, r *http.Request) { // TODO: Signal engine to stop w.WriteHeader(http.StatusAccepted) }