94233b7c66
Three coupled pieces of work, all landing the same PoC:
1. Backend gap-review endpoint (Task #7)
- internal/api/handlers/iace_handler_gap_review.go:
POST /projects/:id/llm-gap-review
feeds Limits-Form + current hazards + current mitigations to
the configured LLM (Qwen / Claude / OpenAI via ProviderRegistry),
parses a JSON suggestion list, filter+stamps confidence, falls
back to a static checklist when LLM is unavailable.
- Adopt step is NOT in this endpoint by design — the user clicks
Adopt in the frontend which calls the existing CreateHazard /
CreateMitigation handlers so provenance flows through the normal
audit trail.
2. Frontend modal + button (Task #8)
- app/sdk/iace/[projectId]/hazards/_components/LLMGapReviewModal.tsx:
reusable modal that POSTs the gap-review endpoint, renders
suggestions with Adopt/Reject UX, shows confidence + norm refs,
source-stamp llm_gap_review vs fallback_static.
- hazards/page.tsx: indigo "KI-Gap-Review" button next to the
existing "Eigene Gefaehrdung" button + modal mount.
3. Tech-File sources appendix (Task #29 — Stufe 4)
- internal/iace/document_export_sources.go: new pdfSourcesAppendix
method appended to ExportPDF. Groups cited norms by license rule
(R1 OSHA/EU-Recht / R3 BreakPilot patterns / R3 DIN-EN-ISO
identifier-only) and emits the legally required statement that
pauschal Impressum-Hinweise nicht ausreichen.
- extractCitedNorms() scans hazard/mitigation text for EN/ISO/IEC/
DIN identifiers in a narrow grammar so prose isn't turned into
spurious citations.
Bonus refactor:
- internal/app/routes.go reached the 500-LOC hard cap when the new
llm-gap-review route was added. Extracted registerIACERoutes into
routes_iace.go (136 LOC). Same wiring, no behaviour change.
Three of the four Attribution-Renderer stages (1, 2, 4) now produce
real output. Stufe 3 ships as <SourceBadge> + <LicenseModuleBanner>
already (commits dfac940 + b9e3eea earlier in this branch).
The PoC is intentionally conservative: every LLM-Suggestion stays
unverbindlich until a human clicks Adopt, and Adopt goes through the
existing normal CreateHazard/CreateMitigation flow (not yet wired in
this commit — separate iteration). The endpoint, modal and provenance
chain are in place for the next iteration to wire Adopt → write path.
402 lines
17 KiB
Go
402 lines
17 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/breakpilot/ai-compliance-sdk/internal/api/handlers"
|
|
"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func registerRoutes(
|
|
router *gin.Engine,
|
|
rbacMiddleware *rbac.Middleware,
|
|
rbacHandlers *handlers.RBACHandlers,
|
|
llmHandlers *handlers.LLMHandlers,
|
|
auditHandlers *handlers.AuditHandlers,
|
|
uccaHandlers *handlers.UCCAHandlers,
|
|
escalationHandlers *handlers.EscalationHandlers,
|
|
obligationsHandlers *handlers.ObligationsHandlers,
|
|
ragHandlers *handlers.RAGHandlers,
|
|
roadmapHandlers *handlers.RoadmapHandlers,
|
|
workshopHandlers *handlers.WorkshopHandlers,
|
|
portfolioHandlers *handlers.PortfolioHandlers,
|
|
academyHandlers *handlers.AcademyHandlers,
|
|
trainingHandlers *handlers.TrainingHandlers,
|
|
whistleblowerHandlers *handlers.WhistleblowerHandlers,
|
|
iaceHandler *handlers.IACEHandler,
|
|
gapHandler *handlers.GapHandler,
|
|
maximizerHandlers *handlers.MaximizerHandlers,
|
|
regulatoryNewsHandlers *handlers.RegulatoryNewsHandlers,
|
|
useCaseHandler *handlers.UseCaseHandler,
|
|
) {
|
|
v1 := router.Group("/sdk/v1")
|
|
{
|
|
v1.GET("/health", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"status": "ok", "timestamp": time.Now().UTC()})
|
|
})
|
|
v1.Use(rbacMiddleware.ExtractUserContext())
|
|
|
|
registerRBACRoutes(v1, rbacHandlers)
|
|
registerLLMRoutes(v1, rbacMiddleware, llmHandlers)
|
|
registerAuditRoutes(v1, rbacMiddleware, auditHandlers)
|
|
registerUCCARoutes(v1, uccaHandlers, escalationHandlers, obligationsHandlers)
|
|
registerRAGRoutes(v1, ragHandlers)
|
|
registerRoadmapRoutes(v1, roadmapHandlers)
|
|
registerWorkshopRoutes(v1, workshopHandlers)
|
|
registerPortfolioRoutes(v1, portfolioHandlers)
|
|
registerAcademyRoutes(v1, academyHandlers)
|
|
registerTrainingRoutes(v1, trainingHandlers)
|
|
registerWhistleblowerRoutes(v1, whistleblowerHandlers)
|
|
registerIACERoutes(v1, iaceHandler)
|
|
registerGapRoutes(v1, gapHandler)
|
|
registerMaximizerRoutes(v1, maximizerHandlers)
|
|
registerUseCaseRoutes(v1, useCaseHandler)
|
|
v1.GET("/regulatory-news", regulatoryNewsHandlers.GetNews)
|
|
}
|
|
}
|
|
|
|
func registerRBACRoutes(v1 *gin.RouterGroup, h *handlers.RBACHandlers) {
|
|
tenants := v1.Group("/tenants")
|
|
{
|
|
tenants.GET("", h.ListTenants)
|
|
tenants.GET("/:id", h.GetTenant)
|
|
tenants.POST("", h.CreateTenant)
|
|
tenants.PUT("/:id", h.UpdateTenant)
|
|
tenants.GET("/:id/namespaces", h.ListNamespaces)
|
|
tenants.POST("/:id/namespaces", h.CreateNamespace)
|
|
}
|
|
v1.GET("/namespaces/:id", h.GetNamespace)
|
|
roles := v1.Group("/roles")
|
|
{
|
|
roles.GET("", h.ListRoles)
|
|
roles.GET("/system", h.ListSystemRoles)
|
|
roles.GET("/:id", h.GetRole)
|
|
roles.POST("", h.CreateRole)
|
|
}
|
|
userRoles := v1.Group("/user-roles")
|
|
{
|
|
userRoles.POST("", h.AssignRole)
|
|
userRoles.DELETE("/:userId/:roleId", h.RevokeRole)
|
|
userRoles.GET("/:userId", h.GetUserRoles)
|
|
}
|
|
permissions := v1.Group("/permissions")
|
|
{
|
|
permissions.GET("/effective", h.GetEffectivePermissions)
|
|
permissions.GET("/context", h.GetUserContext)
|
|
permissions.GET("/check", h.CheckPermission)
|
|
}
|
|
policies := v1.Group("/llm/policies")
|
|
{
|
|
policies.GET("", h.ListLLMPolicies)
|
|
policies.GET("/:id", h.GetLLMPolicy)
|
|
policies.POST("", h.CreateLLMPolicy)
|
|
policies.PUT("/:id", h.UpdateLLMPolicy)
|
|
policies.DELETE("/:id", h.DeleteLLMPolicy)
|
|
}
|
|
}
|
|
|
|
func registerLLMRoutes(v1 *gin.RouterGroup, mw *rbac.Middleware, h *handlers.LLMHandlers) {
|
|
llmRoutes := v1.Group("/llm")
|
|
llmRoutes.Use(mw.RequireLLMAccess())
|
|
{
|
|
llmRoutes.POST("/chat", h.Chat)
|
|
llmRoutes.POST("/complete", h.Complete)
|
|
llmRoutes.GET("/models", h.ListModels)
|
|
llmRoutes.GET("/providers/status", h.GetProviderStatus)
|
|
llmRoutes.POST("/analyze", h.AnalyzeText)
|
|
llmRoutes.POST("/redact", h.RedactText)
|
|
}
|
|
}
|
|
|
|
func registerAuditRoutes(v1 *gin.RouterGroup, mw *rbac.Middleware, h *handlers.AuditHandlers) {
|
|
auditRoutes := v1.Group("/audit")
|
|
auditRoutes.Use(mw.RequireAnyPermission(rbac.PermissionAuditAll, rbac.PermissionAuditRead, rbac.PermissionAuditLogRead))
|
|
{
|
|
auditRoutes.GET("/llm", h.QueryLLMAudit)
|
|
auditRoutes.GET("/general", h.QueryGeneralAudit)
|
|
auditRoutes.GET("/llm-operations", h.QueryLLMAudit)
|
|
auditRoutes.GET("/trail", h.QueryGeneralAudit)
|
|
auditRoutes.GET("/usage", h.GetUsageStats)
|
|
auditRoutes.GET("/compliance-report", h.GetComplianceReport)
|
|
auditRoutes.GET("/export/llm", h.ExportLLMAudit)
|
|
auditRoutes.GET("/export/general", h.ExportGeneralAudit)
|
|
auditRoutes.GET("/export/compliance", h.ExportComplianceReport)
|
|
}
|
|
}
|
|
|
|
func registerUCCARoutes(v1 *gin.RouterGroup, h *handlers.UCCAHandlers, eh *handlers.EscalationHandlers, oh *handlers.ObligationsHandlers) {
|
|
uccaRoutes := v1.Group("/ucca")
|
|
{
|
|
uccaRoutes.POST("/assess", h.Assess)
|
|
uccaRoutes.POST("/assess-enriched", h.AssessEnriched)
|
|
uccaRoutes.GET("/assessments", h.ListAssessments)
|
|
uccaRoutes.GET("/assessments/:id", h.GetAssessment)
|
|
uccaRoutes.PUT("/assessments/:id", h.UpdateAssessment)
|
|
uccaRoutes.DELETE("/assessments/:id", h.DeleteAssessment)
|
|
uccaRoutes.POST("/assessments/:id/explain", h.Explain)
|
|
uccaRoutes.GET("/patterns", h.ListPatterns)
|
|
uccaRoutes.GET("/examples", h.ListExamples)
|
|
uccaRoutes.GET("/rules", h.ListRules)
|
|
uccaRoutes.GET("/controls", h.ListControls)
|
|
uccaRoutes.GET("/problem-solutions", h.ListProblemSolutions)
|
|
uccaRoutes.GET("/export/:id", h.Export)
|
|
uccaRoutes.GET("/escalations", eh.ListEscalations)
|
|
uccaRoutes.GET("/escalations/stats", eh.GetEscalationStats)
|
|
uccaRoutes.GET("/escalations/:id", eh.GetEscalation)
|
|
uccaRoutes.POST("/escalations", eh.CreateEscalation)
|
|
uccaRoutes.POST("/escalations/:id/assign", eh.AssignEscalation)
|
|
uccaRoutes.POST("/escalations/:id/review", eh.StartReview)
|
|
uccaRoutes.POST("/escalations/:id/decide", eh.DecideEscalation)
|
|
oh.RegisterRoutes(uccaRoutes)
|
|
}
|
|
}
|
|
|
|
func registerRAGRoutes(v1 *gin.RouterGroup, h *handlers.RAGHandlers) {
|
|
ragRoutes := v1.Group("/rag")
|
|
{
|
|
ragRoutes.POST("/search", h.Search)
|
|
ragRoutes.GET("/regulations", h.ListRegulations)
|
|
ragRoutes.GET("/corpus-status", h.CorpusStatus)
|
|
ragRoutes.GET("/corpus-versions/:collection", h.CorpusVersionHistory)
|
|
ragRoutes.GET("/scroll", h.HandleScrollChunks)
|
|
}
|
|
}
|
|
|
|
func registerRoadmapRoutes(v1 *gin.RouterGroup, h *handlers.RoadmapHandlers) {
|
|
roadmapRoutes := v1.Group("/roadmaps")
|
|
{
|
|
roadmapRoutes.POST("", h.CreateRoadmap)
|
|
roadmapRoutes.GET("", h.ListRoadmaps)
|
|
roadmapRoutes.GET("/:id", h.GetRoadmap)
|
|
roadmapRoutes.PUT("/:id", h.UpdateRoadmap)
|
|
roadmapRoutes.DELETE("/:id", h.DeleteRoadmap)
|
|
roadmapRoutes.GET("/:id/stats", h.GetRoadmapStats)
|
|
roadmapRoutes.POST("/:id/items", h.CreateItem)
|
|
roadmapRoutes.GET("/:id/items", h.ListItems)
|
|
roadmapRoutes.POST("/import/upload", h.UploadImport)
|
|
roadmapRoutes.GET("/import/:jobId", h.GetImportJob)
|
|
roadmapRoutes.POST("/import/:jobId/confirm", h.ConfirmImport)
|
|
}
|
|
roadmapItemRoutes := v1.Group("/roadmap-items")
|
|
{
|
|
roadmapItemRoutes.GET("/:id", h.GetItem)
|
|
roadmapItemRoutes.PUT("/:id", h.UpdateItem)
|
|
roadmapItemRoutes.PATCH("/:id/status", h.UpdateItemStatus)
|
|
roadmapItemRoutes.DELETE("/:id", h.DeleteItem)
|
|
}
|
|
}
|
|
|
|
func registerWorkshopRoutes(v1 *gin.RouterGroup, h *handlers.WorkshopHandlers) {
|
|
workshopRoutes := v1.Group("/workshops")
|
|
{
|
|
workshopRoutes.POST("", h.CreateSession)
|
|
workshopRoutes.GET("", h.ListSessions)
|
|
workshopRoutes.GET("/:id", h.GetSession)
|
|
workshopRoutes.PUT("/:id", h.UpdateSession)
|
|
workshopRoutes.DELETE("/:id", h.DeleteSession)
|
|
workshopRoutes.POST("/:id/start", h.StartSession)
|
|
workshopRoutes.POST("/:id/pause", h.PauseSession)
|
|
workshopRoutes.POST("/:id/complete", h.CompleteSession)
|
|
workshopRoutes.GET("/:id/participants", h.ListParticipants)
|
|
workshopRoutes.PUT("/:id/participants/:participantId", h.UpdateParticipant)
|
|
workshopRoutes.DELETE("/:id/participants/:participantId", h.RemoveParticipant)
|
|
workshopRoutes.POST("/:id/responses", h.SubmitResponse)
|
|
workshopRoutes.GET("/:id/responses", h.GetResponses)
|
|
workshopRoutes.POST("/:id/comments", h.AddComment)
|
|
workshopRoutes.GET("/:id/comments", h.GetComments)
|
|
workshopRoutes.POST("/:id/advance", h.AdvanceStep)
|
|
workshopRoutes.POST("/:id/goto", h.GoToStep)
|
|
workshopRoutes.GET("/:id/stats", h.GetSessionStats)
|
|
workshopRoutes.GET("/:id/summary", h.GetSessionSummary)
|
|
workshopRoutes.GET("/:id/export", h.ExportSession)
|
|
workshopRoutes.POST("/join/:code", h.JoinSession)
|
|
}
|
|
}
|
|
|
|
func registerPortfolioRoutes(v1 *gin.RouterGroup, h *handlers.PortfolioHandlers) {
|
|
portfolioRoutes := v1.Group("/portfolios")
|
|
{
|
|
portfolioRoutes.POST("", h.CreatePortfolio)
|
|
portfolioRoutes.GET("", h.ListPortfolios)
|
|
portfolioRoutes.GET("/:id", h.GetPortfolio)
|
|
portfolioRoutes.PUT("/:id", h.UpdatePortfolio)
|
|
portfolioRoutes.DELETE("/:id", h.DeletePortfolio)
|
|
portfolioRoutes.POST("/:id/items", h.AddItem)
|
|
portfolioRoutes.GET("/:id/items", h.ListItems)
|
|
portfolioRoutes.POST("/:id/items/bulk", h.BulkAddItems)
|
|
portfolioRoutes.DELETE("/:id/items/:itemId", h.RemoveItem)
|
|
portfolioRoutes.PUT("/:id/items/order", h.ReorderItems)
|
|
portfolioRoutes.GET("/:id/stats", h.GetPortfolioStats)
|
|
portfolioRoutes.GET("/:id/activity", h.GetPortfolioActivity)
|
|
portfolioRoutes.POST("/:id/recalculate", h.RecalculateMetrics)
|
|
portfolioRoutes.POST("/:id/submit-review", h.SubmitForReview)
|
|
portfolioRoutes.POST("/:id/approve", h.ApprovePortfolio)
|
|
portfolioRoutes.POST("/merge", h.MergePortfolios)
|
|
portfolioRoutes.POST("/compare", h.ComparePortfolios)
|
|
}
|
|
}
|
|
|
|
func registerAcademyRoutes(v1 *gin.RouterGroup, h *handlers.AcademyHandlers) {
|
|
academyRoutes := v1.Group("/academy")
|
|
{
|
|
academyRoutes.POST("/courses", h.CreateCourse)
|
|
academyRoutes.GET("/courses", h.ListCourses)
|
|
academyRoutes.GET("/courses/:id", h.GetCourse)
|
|
academyRoutes.PUT("/courses/:id", h.UpdateCourse)
|
|
academyRoutes.DELETE("/courses/:id", h.DeleteCourse)
|
|
academyRoutes.POST("/enrollments", h.CreateEnrollment)
|
|
academyRoutes.GET("/enrollments", h.ListEnrollments)
|
|
academyRoutes.PUT("/enrollments/:id/progress", h.UpdateProgress)
|
|
academyRoutes.POST("/enrollments/:id/complete", h.CompleteEnrollment)
|
|
academyRoutes.GET("/certificates/:id", h.GetCertificate)
|
|
academyRoutes.POST("/enrollments/:id/certificate", h.GenerateCertificate)
|
|
academyRoutes.POST("/courses/:id/quiz", h.SubmitQuiz)
|
|
academyRoutes.PUT("/lessons/:id", h.UpdateLesson)
|
|
academyRoutes.POST("/lessons/:id/quiz-test", h.TestQuiz)
|
|
academyRoutes.GET("/stats", h.GetStatistics)
|
|
academyRoutes.POST("/courses/generate", h.GenerateCourseFromTraining)
|
|
academyRoutes.POST("/courses/generate-all", h.GenerateAllCourses)
|
|
academyRoutes.GET("/certificates/:id/pdf", h.DownloadCertificatePDF)
|
|
}
|
|
}
|
|
|
|
func registerTrainingRoutes(v1 *gin.RouterGroup, h *handlers.TrainingHandlers) {
|
|
trainingRoutes := v1.Group("/training")
|
|
{
|
|
trainingRoutes.GET("/modules", h.ListModules)
|
|
trainingRoutes.GET("/modules/:id", h.GetModule)
|
|
trainingRoutes.POST("/modules", h.CreateModule)
|
|
trainingRoutes.PUT("/modules/:id", h.UpdateModule)
|
|
trainingRoutes.DELETE("/modules/:id", h.DeleteModule)
|
|
trainingRoutes.GET("/matrix", h.GetMatrix)
|
|
trainingRoutes.GET("/matrix/:role", h.GetMatrixForRole)
|
|
trainingRoutes.POST("/matrix", h.SetMatrixEntry)
|
|
trainingRoutes.DELETE("/matrix/:role/:moduleId", h.DeleteMatrixEntry)
|
|
trainingRoutes.POST("/assignments/compute", h.ComputeAssignments)
|
|
trainingRoutes.GET("/assignments", h.ListAssignments)
|
|
trainingRoutes.GET("/assignments/:id", h.GetAssignment)
|
|
trainingRoutes.POST("/assignments/:id/start", h.StartAssignment)
|
|
trainingRoutes.POST("/assignments/:id/progress", h.UpdateAssignmentProgress)
|
|
trainingRoutes.POST("/assignments/:id/complete", h.CompleteAssignment)
|
|
trainingRoutes.PUT("/assignments/:id", h.UpdateAssignment)
|
|
trainingRoutes.GET("/quiz/:moduleId", h.GetQuiz)
|
|
trainingRoutes.POST("/quiz/:moduleId/submit", h.SubmitQuiz)
|
|
trainingRoutes.GET("/quiz/attempts/:assignmentId", h.GetQuizAttempts)
|
|
trainingRoutes.POST("/content/generate", h.GenerateContent)
|
|
trainingRoutes.POST("/content/generate-quiz", h.GenerateQuiz)
|
|
trainingRoutes.POST("/content/generate-all", h.GenerateAllContent)
|
|
trainingRoutes.POST("/content/generate-all-quiz", h.GenerateAllQuizzes)
|
|
trainingRoutes.GET("/content/:moduleId", h.GetContent)
|
|
trainingRoutes.POST("/content/:moduleId/publish", func(c *gin.Context) {
|
|
c.Params = append(c.Params, gin.Param{Key: "id", Value: c.Param("moduleId")})
|
|
h.PublishContent(c)
|
|
})
|
|
trainingRoutes.POST("/content/:moduleId/generate-audio", h.GenerateAudio)
|
|
trainingRoutes.POST("/content/:moduleId/generate-video", h.GenerateVideo)
|
|
trainingRoutes.POST("/content/:moduleId/preview-script", h.PreviewVideoScript)
|
|
trainingRoutes.GET("/media/module/:moduleId", h.GetModuleMedia)
|
|
trainingRoutes.GET("/media/:mediaId/url", func(c *gin.Context) {
|
|
c.Params = append(c.Params, gin.Param{Key: "id", Value: c.Param("mediaId")})
|
|
h.GetMediaURL(c)
|
|
})
|
|
trainingRoutes.POST("/media/:mediaId/publish", func(c *gin.Context) {
|
|
c.Params = append(c.Params, gin.Param{Key: "id", Value: c.Param("mediaId")})
|
|
h.PublishMedia(c)
|
|
})
|
|
trainingRoutes.GET("/media/:mediaId/stream", func(c *gin.Context) {
|
|
c.Params = append(c.Params, gin.Param{Key: "id", Value: c.Param("mediaId")})
|
|
h.StreamMedia(c)
|
|
})
|
|
trainingRoutes.GET("/deadlines", h.GetDeadlines)
|
|
trainingRoutes.GET("/deadlines/overdue", h.GetOverdueDeadlines)
|
|
trainingRoutes.POST("/escalation/check", h.CheckEscalation)
|
|
trainingRoutes.GET("/audit-log", h.GetAuditLog)
|
|
trainingRoutes.GET("/stats", h.GetStats)
|
|
trainingRoutes.POST("/certificates/generate/:assignmentId", h.GenerateCertificate)
|
|
trainingRoutes.GET("/certificates", h.ListCertificates)
|
|
trainingRoutes.GET("/certificates/:id/verify", h.VerifyCertificate)
|
|
trainingRoutes.GET("/certificates/:id/pdf", h.DownloadCertificatePDF)
|
|
trainingRoutes.GET("/blocks", h.ListBlockConfigs)
|
|
trainingRoutes.POST("/blocks", h.CreateBlockConfig)
|
|
trainingRoutes.GET("/blocks/:id", h.GetBlockConfig)
|
|
trainingRoutes.PUT("/blocks/:id", h.UpdateBlockConfig)
|
|
trainingRoutes.DELETE("/blocks/:id", h.DeleteBlockConfig)
|
|
trainingRoutes.POST("/blocks/:id/preview", h.PreviewBlock)
|
|
trainingRoutes.POST("/blocks/:id/generate", h.GenerateBlock)
|
|
trainingRoutes.GET("/blocks/:id/controls", h.GetBlockControls)
|
|
trainingRoutes.GET("/canonical/controls", h.ListCanonicalControls)
|
|
trainingRoutes.GET("/canonical/meta", h.GetCanonicalMeta)
|
|
trainingRoutes.POST("/content/:moduleId/generate-interactive", h.GenerateInteractiveVideo)
|
|
trainingRoutes.GET("/content/:moduleId/interactive-manifest", h.GetInteractiveManifest)
|
|
trainingRoutes.POST("/checkpoints/:checkpointId/submit", h.SubmitCheckpointQuiz)
|
|
trainingRoutes.GET("/checkpoints/progress/:assignmentId", h.GetCheckpointProgress)
|
|
}
|
|
}
|
|
|
|
func registerWhistleblowerRoutes(v1 *gin.RouterGroup, h *handlers.WhistleblowerHandlers) {
|
|
wbRoutes := v1.Group("/whistleblower")
|
|
{
|
|
wbRoutes.POST("/reports/submit", h.SubmitReport)
|
|
wbRoutes.GET("/reports/access/:accessKey", h.GetReportByAccessKey)
|
|
wbRoutes.POST("/reports/access/:accessKey/messages", h.SendPublicMessage)
|
|
wbRoutes.GET("/reports", h.ListReports)
|
|
wbRoutes.GET("/reports/:id", h.GetReport)
|
|
wbRoutes.PUT("/reports/:id", h.UpdateReport)
|
|
wbRoutes.DELETE("/reports/:id", h.DeleteReport)
|
|
wbRoutes.POST("/reports/:id/acknowledge", h.AcknowledgeReport)
|
|
wbRoutes.POST("/reports/:id/investigate", h.StartInvestigation)
|
|
wbRoutes.POST("/reports/:id/measures", h.AddMeasure)
|
|
wbRoutes.POST("/reports/:id/close", h.CloseReport)
|
|
wbRoutes.POST("/reports/:id/messages", h.SendAdminMessage)
|
|
wbRoutes.GET("/reports/:id/messages", h.ListMessages)
|
|
wbRoutes.GET("/stats", h.GetStatistics)
|
|
}
|
|
}
|
|
|
|
|
|
func registerMaximizerRoutes(v1 *gin.RouterGroup, h *handlers.MaximizerHandlers) {
|
|
m := v1.Group("/maximizer")
|
|
{
|
|
m.POST("/optimize", h.Optimize)
|
|
m.POST("/optimize-from-intake", h.OptimizeFromIntake)
|
|
m.POST("/optimize-from-intake-enriched", h.OptimizeFromIntakeWithProfile)
|
|
m.POST("/optimize-from-assessment/:id", h.OptimizeFromAssessment)
|
|
m.POST("/evaluate", h.Evaluate)
|
|
m.GET("/optimizations", h.ListOptimizations)
|
|
m.GET("/optimizations/:id", h.GetOptimization)
|
|
m.DELETE("/optimizations/:id", h.DeleteOptimization)
|
|
m.GET("/dimensions", h.GetDimensionSchema)
|
|
}
|
|
}
|
|
|
|
func registerUseCaseRoutes(v1 *gin.RouterGroup, h *handlers.UseCaseHandler) {
|
|
uc := v1.Group("/use-case")
|
|
{
|
|
uc.GET("/templates", h.GetTemplates)
|
|
uc.GET("/templates/:id", h.GetTemplate)
|
|
uc.POST("/compile", h.Compile)
|
|
uc.POST("/audits", h.CreateAudit)
|
|
uc.GET("/audits", h.ListAudits)
|
|
uc.GET("/audits/:id", h.GetAudit)
|
|
uc.POST("/audits/:id/answer", h.AnswerQuestion)
|
|
uc.GET("/audits/:id/score", h.GetScore)
|
|
uc.GET("/audits/:id/gaps", h.GetGaps)
|
|
}
|
|
}
|
|
|
|
func registerGapRoutes(v1 *gin.RouterGroup, h *handlers.GapHandler) {
|
|
g := v1.Group("/gap")
|
|
{
|
|
g.POST("/projects", h.CreateProject)
|
|
g.GET("/projects", h.ListProjects)
|
|
g.GET("/projects/:id", h.GetProject)
|
|
g.POST("/projects/:id/analyze", h.AnalyzeProject)
|
|
g.POST("/analyze", h.QuickAnalyze)
|
|
g.GET("/templates", h.GetTemplates)
|
|
g.GET("/templates/:key", h.GetTemplate)
|
|
g.GET("/regulations", h.GetRegulations)
|
|
}
|
|
}
|