package api import ( "encoding/json" "net/http" "time" "crypto-miner-server/internal/models" "github.com/go-chi/chi/v5" ) func (f *FleetHandler) GetAudit(w http.ResponseWriter, r *http.Request) { if f.db == nil { writeJSON(w, []*models.AuditEntry{}) return } entries, err := f.db.ListAudit(50) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if entries == nil { entries = []*models.AuditEntry{} } writeJSON(w, entries) } func (f *FleetHandler) GetFleetTasks(w http.ResponseWriter, r *http.Request) { if f.db == nil { writeJSON(w, []*models.FleetTask{}) return } tasks, err := f.db.ListFleetTasks() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if tasks == nil { tasks = []*models.FleetTask{} } writeJSON(w, tasks) } func (f *FleetHandler) PutFleetTask(w http.ResponseWriter, r *http.Request) { var t models.FleetTask if err := json.NewDecoder(r.Body).Decode(&t); err != nil { http.Error(w, "invalid JSON", http.StatusBadRequest) return } if t.Name == "" || t.Action == "" || t.Trigger == "" { http.Error(w, "name, trigger, and action are required", http.StatusBadRequest) return } if f.db == nil { http.Error(w, "database unavailable", http.StatusServiceUnavailable) return } if err := f.db.UpsertFleetTask(&t); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } _ = f.db.InsertAudit(AuthUsername(r), "fleet_task_save", "", map[string]string{"task_id": t.ID, "name": t.Name}) writeJSON(w, t) } func (f *FleetHandler) DeleteFleetTask(w http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id") if id == "" { http.Error(w, "id required", http.StatusBadRequest) return } if f.db == nil { http.Error(w, "database unavailable", http.StatusServiceUnavailable) return } if err := f.db.DeleteFleetTask(id); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } _ = f.db.InsertAudit(AuthUsername(r), "fleet_task_delete", "", map[string]string{"task_id": id}) writeJSON(w, map[string]bool{"ok": true}) } func (f *FleetHandler) GetSpreadFunnel(w http.ResponseWriter, r *http.Request) { if f.db == nil { writeJSON(w, map[string]interface{}{"by_build": []interface{}{}, "new_connects_today": 0, "total_agents": 0}) return } since := time.Now().Add(-7 * 24 * time.Hour) stats, err := f.db.GetSpreadFunnelStats(since) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } writeJSON(w, stats) }