refactor(go/handlers): split iace_handler and training_handlers into focused files
iace_handler.go (2706 LOC) split into 9 files: - iace_handler.go: struct, constructor, shared helpers (~156 LOC) - iace_handler_projects.go: project CRUD + InitFromProfile (~310 LOC) - iace_handler_components.go: components + classification (~387 LOC) - iace_handler_hazards.go: hazard library, CRUD, risk assessment (~469 LOC) - iace_handler_mitigations.go: mitigations, evidence, verification plans (~293 LOC) - iace_handler_techfile.go: CE tech file generation/export (~452 LOC) - iace_handler_monitoring.go: monitoring events + audit trail (~134 LOC) - iace_handler_refdata.go: ISO 12100 ref data, patterns, suggestions (~465 LOC) - iace_handler_rag.go: RAG library search + section enrichment (~142 LOC) training_handlers.go (1864 LOC) split into 9 files: - training_handlers.go: struct + constructor (~23 LOC) - training_handlers_modules.go: module CRUD (~226 LOC) - training_handlers_matrix.go: CTM matrix endpoints (~95 LOC) - training_handlers_assignments.go: assignment lifecycle (~243 LOC) - training_handlers_quiz.go: quiz submit/grade/attempts (~185 LOC) - training_handlers_content.go: LLM content/audio/video generation (~274 LOC) - training_handlers_media.go: media, streaming, interactive video (~325 LOC) - training_handlers_blocks.go: block configs + canonical controls (~280 LOC) - training_handlers_stats.go: deadlines, escalation, audit, certificates (~290 LOC) All files remain in package handlers. Zero behavior changes. All exported function names preserved. All files under 500 LOC hard cap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
||||
"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
// Monitoring
|
||||
// ============================================================================
|
||||
|
||||
// CreateMonitoringEvent handles POST /projects/:id/monitoring
|
||||
// Creates a new post-market monitoring event.
|
||||
func (h *IACEHandler) CreateMonitoringEvent(c *gin.Context) {
|
||||
projectID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var req iace.CreateMonitoringEventRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Override project ID from URL path
|
||||
req.ProjectID = projectID
|
||||
|
||||
event, err := h.store.CreateMonitoringEvent(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Audit trail
|
||||
userID := rbac.GetUserID(c)
|
||||
newVals, _ := json.Marshal(event)
|
||||
h.store.AddAuditEntry(
|
||||
c.Request.Context(), projectID, "monitoring_event", event.ID,
|
||||
iace.AuditActionCreate, userID.String(), nil, newVals,
|
||||
)
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"monitoring_event": event})
|
||||
}
|
||||
|
||||
// ListMonitoringEvents handles GET /projects/:id/monitoring
|
||||
// Lists all monitoring events for a project.
|
||||
func (h *IACEHandler) ListMonitoringEvents(c *gin.Context) {
|
||||
projectID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||
return
|
||||
}
|
||||
|
||||
events, err := h.store.ListMonitoringEvents(c.Request.Context(), projectID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if events == nil {
|
||||
events = []iace.MonitoringEvent{}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"monitoring_events": events,
|
||||
"total": len(events),
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateMonitoringEvent handles PUT /projects/:id/monitoring/:eid
|
||||
// Updates a monitoring event with the provided fields.
|
||||
func (h *IACEHandler) UpdateMonitoringEvent(c *gin.Context) {
|
||||
_, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||
return
|
||||
}
|
||||
|
||||
eventID, err := uuid.Parse(c.Param("eid"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid monitoring event ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var updates map[string]interface{}
|
||||
if err := c.ShouldBindJSON(&updates); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
event, err := h.store.UpdateMonitoringEvent(c.Request.Context(), eventID, updates)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if event == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "monitoring event not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"monitoring_event": event})
|
||||
}
|
||||
|
||||
// GetAuditTrail handles GET /projects/:id/audit-trail
|
||||
// Returns all audit trail entries for a project, newest first.
|
||||
func (h *IACEHandler) GetAuditTrail(c *gin.Context) {
|
||||
projectID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||||
return
|
||||
}
|
||||
|
||||
entries, err := h.store.ListAuditTrail(c.Request.Context(), projectID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if entries == nil {
|
||||
entries = []iace.AuditTrailEntry{}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"audit_trail": entries,
|
||||
"total": len(entries),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user