package main import ( "encoding/json" "inou/lib" "net/http" ) type AuditRequest struct { Dossier string `json:"dossier"` Action string `json:"action"` Target string `json:"target"` Details string `json:"details"` } type AuditResponse struct { ID string `json:"id"` Dossier string `json:"dossier"` Action string `json:"action"` Target string `json:"target"` Details string `json:"details"` Timestamp int64 `json:"timestamp"` } func handleAudit(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if r.Method == "POST" { // Localhost only for writes if !isLocalhost(r) { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } var req AuditRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } dossierID := req.Dossier targetID := req.Target if dossierID == "" || req.Action == "" { http.Error(w, "dossier and action required", http.StatusBadRequest) return } lib.AuditLog(dossierID, req.Action, targetID, req.Details) json.NewEncoder(w).Encode(map[string]bool{"ok": true}) return } // GET - query audit log targetHex := r.URL.Query().Get("target") dossierHex := r.URL.Query().Get("dossier") var entries []*lib.AuditEntry var err error if targetHex != "" { entries, err = lib.AuditList(&lib.AuditFilter{TargetID: targetHex}) } else if dossierHex != "" { entries, err = lib.AuditList(&lib.AuditFilter{ActorID: dossierHex}) } else { http.Error(w, "target or dossier parameter required", http.StatusBadRequest) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var resp []AuditResponse for _, e := range entries { resp = append(resp, AuditResponse{ ID: e.AuditID, Dossier: e.Actor1ID, Action: e.Action, Target: e.TargetID, Details: e.Details, Timestamp: e.Timestamp, }) } if resp == nil { resp = []AuditResponse{} } json.NewEncoder(w).Encode(resp) }