diff --git a/admin-compliance/lib/sdk/academy/api.ts b/admin-compliance/lib/sdk/academy/api.ts index 46e259e..c9b90f4 100644 --- a/admin-compliance/lib/sdk/academy/api.ts +++ b/admin-compliance/lib/sdk/academy/api.ts @@ -10,6 +10,7 @@ import { CourseCategory, CourseCreateRequest, CourseUpdateRequest, + GenerateCourseRequest, Enrollment, EnrollmentStatus, EnrollmentListResponse, @@ -273,6 +274,52 @@ export async function fetchAcademyStatistics(): Promise { ) } +// ============================================================================= +// COURSE GENERATION (via Training Engine) +// ============================================================================= + +/** + * KI-gestuetzten Kurs generieren (nutzt intern Training Content Pipeline) + */ +export async function generateCourse(request: GenerateCourseRequest): Promise { + return fetchWithTimeout( + `${ACADEMY_API_BASE}/courses/generate`, + { + method: 'POST', + body: JSON.stringify(request) + }, + 120000 // 2 min timeout for LLM generation + ) +} + +/** + * Videos fuer alle Lektionen eines Kurses generieren + */ +export async function generateVideos(courseId: string): Promise<{ status: string; jobId?: string }> { + return fetchWithTimeout<{ status: string; jobId?: string }>( + `${ACADEMY_API_BASE}/courses/${courseId}/generate-videos`, + { + method: 'POST' + }, + 300000 // 5 min timeout for video generation + ) +} + +/** + * Video-Generierungsstatus abrufen + */ +export async function getVideoStatus(courseId: string): Promise<{ + status: string + total: number + completed: number + failed: number + videos: Array<{ lessonId: string; status: string; url?: string }> +}> { + return fetchWithTimeout( + `${ACADEMY_API_BASE}/courses/${courseId}/video-status` + ) +} + // ============================================================================= // SDK PROXY FUNCTION (wraps fetchCourses + fetchAcademyStatistics) // ============================================================================= diff --git a/admin-compliance/lib/sdk/academy/types.ts b/admin-compliance/lib/sdk/academy/types.ts index 2a09fc4..a9d7317 100644 --- a/admin-compliance/lib/sdk/academy/types.ts +++ b/admin-compliance/lib/sdk/academy/types.ts @@ -215,6 +215,15 @@ export interface CourseUpdateRequest { requiredForRoles?: string[] } +export interface GenerateCourseRequest { + title: string + category: CourseCategory + description?: string + regulationArea?: string + language?: string + durationMinutes?: number +} + export interface EnrollUserRequest { courseId: string userId: string diff --git a/ai-compliance-sdk/cmd/server/main.go b/ai-compliance-sdk/cmd/server/main.go index 54923ef..66254c3 100644 --- a/ai-compliance-sdk/cmd/server/main.go +++ b/ai-compliance-sdk/cmd/server/main.go @@ -18,6 +18,7 @@ import ( "github.com/breakpilot/ai-compliance-sdk/internal/academy" "github.com/breakpilot/ai-compliance-sdk/internal/incidents" "github.com/breakpilot/ai-compliance-sdk/internal/roadmap" + "github.com/breakpilot/ai-compliance-sdk/internal/training" "github.com/breakpilot/ai-compliance-sdk/internal/ucca" "github.com/breakpilot/ai-compliance-sdk/internal/whistleblower" "github.com/breakpilot/ai-compliance-sdk/internal/iace" @@ -69,6 +70,7 @@ func main() { incidentStore := incidents.NewStore(pool) vendorStore := vendor.NewStore(pool) iaceStore := iace.NewStore(pool) + trainingStore := training.NewStore(pool) // Initialize services rbacService := rbac.NewService(rbacStore) @@ -90,6 +92,10 @@ func main() { // Initialize PII detector piiDetector := llm.NewPIIDetectorWithPatterns(llm.AllPIIPatterns()) + // Initialize TTS client and content generator for training + ttsClient := training.NewTTSClient(cfg.TTSServiceURL) + contentGenerator := training.NewContentGenerator(providerRegistry, piiDetector, trainingStore, ttsClient) + // Initialize access gate accessGate := llm.NewAccessGate(policyEngine, piiDetector, providerRegistry) @@ -113,6 +119,7 @@ func main() { incidentHandlers := handlers.NewIncidentHandlers(incidentStore) vendorHandlers := handlers.NewVendorHandlers(vendorStore) iaceHandler := handlers.NewIACEHandler(iaceStore) + trainingHandlers := handlers.NewTrainingHandlers(trainingStore, contentGenerator) // Initialize middleware rbacMiddleware := rbac.NewMiddleware(rbacService, policyEngine) @@ -478,6 +485,63 @@ func main() { academyRoutes.GET("/stats", academyHandlers.GetStatistics) } + // Training Engine routes - Compliance Training Content Pipeline + trainingRoutes := v1.Group("/training") + { + // Module CRUD + trainingRoutes.GET("/modules", trainingHandlers.ListModules) + trainingRoutes.GET("/modules/:id", trainingHandlers.GetModule) + trainingRoutes.POST("/modules", trainingHandlers.CreateModule) + trainingRoutes.PUT("/modules/:id", trainingHandlers.UpdateModule) + + // Compliance Training Matrix (CTM) + trainingRoutes.GET("/matrix", trainingHandlers.GetMatrix) + trainingRoutes.GET("/matrix/:role", trainingHandlers.GetMatrixForRole) + trainingRoutes.POST("/matrix", trainingHandlers.SetMatrixEntry) + trainingRoutes.DELETE("/matrix/:role/:moduleId", trainingHandlers.DeleteMatrixEntry) + + // Assignments + trainingRoutes.POST("/assignments/compute", trainingHandlers.ComputeAssignments) + trainingRoutes.GET("/assignments", trainingHandlers.ListAssignments) + trainingRoutes.GET("/assignments/:id", trainingHandlers.GetAssignment) + trainingRoutes.POST("/assignments/:id/start", trainingHandlers.StartAssignment) + trainingRoutes.POST("/assignments/:id/progress", trainingHandlers.UpdateAssignmentProgress) + trainingRoutes.POST("/assignments/:id/complete", trainingHandlers.CompleteAssignment) + + // Quiz + trainingRoutes.GET("/quiz/:moduleId", trainingHandlers.GetQuiz) + trainingRoutes.POST("/quiz/:moduleId/submit", trainingHandlers.SubmitQuiz) + trainingRoutes.GET("/quiz/attempts/:assignmentId", trainingHandlers.GetQuizAttempts) + + // Content Generation (LLM) + trainingRoutes.POST("/content/generate", trainingHandlers.GenerateContent) + trainingRoutes.POST("/content/generate-quiz", trainingHandlers.GenerateQuiz) + trainingRoutes.POST("/content/generate-all", trainingHandlers.GenerateAllContent) + trainingRoutes.POST("/content/generate-all-quiz", trainingHandlers.GenerateAllQuizzes) + trainingRoutes.GET("/content/:moduleId", trainingHandlers.GetContent) + trainingRoutes.POST("/content/:id/publish", trainingHandlers.PublishContent) + + // Media (Audio/Video via TTS Service) + trainingRoutes.POST("/content/:moduleId/generate-audio", trainingHandlers.GenerateAudio) + trainingRoutes.POST("/content/:moduleId/generate-video", trainingHandlers.GenerateVideo) + trainingRoutes.POST("/content/:moduleId/preview-script", trainingHandlers.PreviewVideoScript) + trainingRoutes.GET("/media/module/:moduleId", trainingHandlers.GetModuleMedia) + trainingRoutes.GET("/media/:id/url", trainingHandlers.GetMediaURL) + trainingRoutes.POST("/media/:id/publish", trainingHandlers.PublishMedia) + + // Deadlines & Escalation + trainingRoutes.GET("/deadlines", trainingHandlers.GetDeadlines) + trainingRoutes.GET("/deadlines/overdue", trainingHandlers.GetOverdueDeadlines) + trainingRoutes.POST("/escalation/check", trainingHandlers.CheckEscalation) + + // Audit & Statistics + trainingRoutes.GET("/audit-log", trainingHandlers.GetAuditLog) + trainingRoutes.GET("/stats", trainingHandlers.GetStats) + + // Certificates + trainingRoutes.GET("/certificates/:id/verify", trainingHandlers.VerifyCertificate) + } + // Whistleblower routes - Hinweisgebersystem (HinSchG) whistleblowerRoutes := v1.Group("/whistleblower") {