feat: implement service history view and tracking
This commit is contained in:
@@ -13,10 +13,12 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
services = []models.Service{}
|
||||
mu sync.Mutex
|
||||
dataFile = "services.json"
|
||||
apiToken = "ENVGUARD_SECRET_TOKEN"
|
||||
services = []models.Service{}
|
||||
history = []models.HistoryEntry{}
|
||||
mu sync.Mutex
|
||||
dataFile = "services.json"
|
||||
historyFile = "history.json"
|
||||
apiToken = "ENVGUARD_SECRET_TOKEN"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -33,7 +35,14 @@ func main() {
|
||||
fmt.Printf("✅ %d servicios cargados desde disco\n", len(services))
|
||||
}
|
||||
|
||||
if err := loadHistory(); err != nil {
|
||||
log.Printf("⚠️ No se pudo cargar history.json: %v", err)
|
||||
} else {
|
||||
fmt.Printf("📜 %d entradas de historial cargadas\n", len(history))
|
||||
}
|
||||
|
||||
http.HandleFunc("/services", authMiddleware(handleServices))
|
||||
http.HandleFunc("/history", authMiddleware(handleHistory))
|
||||
http.HandleFunc("/lock", authMiddleware(handleLock))
|
||||
http.HandleFunc("/unlock", authMiddleware(handleUnlock))
|
||||
|
||||
@@ -64,6 +73,30 @@ func saveServices() error {
|
||||
return encoder.Encode(services)
|
||||
}
|
||||
|
||||
func loadHistory() error {
|
||||
file, err := os.Open(historyFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
return json.NewDecoder(file).Decode(&history)
|
||||
}
|
||||
|
||||
func saveHistory() error {
|
||||
file, err := os.Create(historyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetIndent("", " ")
|
||||
return encoder.Encode(history)
|
||||
}
|
||||
|
||||
func handleServices(w http.ResponseWriter, r *http.Request) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
@@ -101,6 +134,15 @@ func handleLock(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Error guardando estado: %v", err)
|
||||
}
|
||||
|
||||
// Add to history
|
||||
history = append(history, models.HistoryEntry{
|
||||
ServiceName: req.ServiceName,
|
||||
Action: "LOCK",
|
||||
User: req.User,
|
||||
Timestamp: time.Now(),
|
||||
})
|
||||
saveHistory()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
@@ -142,6 +184,15 @@ func handleUnlock(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Error guardando estado: %v", err)
|
||||
}
|
||||
|
||||
// Add to history
|
||||
history = append(history, models.HistoryEntry{
|
||||
ServiceName: req.ServiceName,
|
||||
Action: "UNLOCK",
|
||||
User: req.User,
|
||||
Timestamp: time.Now(),
|
||||
})
|
||||
saveHistory()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
@@ -150,6 +201,27 @@ func handleUnlock(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Service not found", http.StatusNotFound)
|
||||
}
|
||||
|
||||
func handleHistory(w http.ResponseWriter, r *http.Request) {
|
||||
serviceName := r.URL.Query().Get("service")
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
var result []models.HistoryEntry
|
||||
for _, h := range history {
|
||||
if serviceName == "" || h.ServiceName == serviceName {
|
||||
result = append(result, h)
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse order (newest first)
|
||||
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
|
||||
result[i], result[j] = result[j], result[i]
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
|
||||
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("X-API-Key")
|
||||
|
||||
Reference in New Issue
Block a user