feat: Implement Compliance Academy E-Learning module (Phases 1-7)
Some checks failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled

Add complete Academy backend (Go) and frontend (Next.js) for DSGVO/IT-Security/AI-Literacy compliance training:
- Go backend: Course CRUD, enrollments, quiz evaluation, PDF certificates (gofpdf), video generation pipeline (ElevenLabs + HeyGen)
- In-memory data store with PostgreSQL migration for future DB support
- Frontend: Course creation (AI + manual), lesson viewer, interactive quiz, certificate viewer with PDF download
- Fix existing compile errors in generate.go (SearchResult type mismatch), llm/service.go (unused var), rag/service.go (Unicode chars)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
BreakPilot Dev
2026-02-14 21:18:51 +01:00
parent 71cde313d5
commit ac1bb1d97b
19 changed files with 4070 additions and 22 deletions

View File

@@ -19,6 +19,9 @@ import {
AcademyStatistics,
SubmitQuizRequest,
SubmitQuizResponse,
GenerateCourseRequest,
GenerateCourseResponse,
VideoStatus,
isEnrollmentOverdue
} from './types'
@@ -273,6 +276,90 @@ export async function fetchAcademyStatistics(): Promise<AcademyStatistics> {
)
}
// =============================================================================
// AI GENERATION
// =============================================================================
/**
* KI-generiert einen kompletten Kurs
*/
export async function generateCourse(request: GenerateCourseRequest): Promise<GenerateCourseResponse> {
return fetchWithTimeout<GenerateCourseResponse>(
`${ACADEMY_API_BASE}/api/v1/academy/courses/generate`,
{
method: 'POST',
body: JSON.stringify(request)
}
)
}
/**
* Einzelne Lektion neu generieren
*/
export async function regenerateLesson(lessonId: string): Promise<{ lessonId: string; status: string }> {
return fetchWithTimeout<{ lessonId: string; status: string }>(
`${ACADEMY_API_BASE}/api/v1/academy/lessons/${lessonId}/regenerate`,
{
method: 'POST'
}
)
}
// =============================================================================
// VIDEO GENERATION
// =============================================================================
/**
* Videos fuer alle Lektionen eines Kurses generieren
*/
export async function generateVideos(courseId: string): Promise<VideoStatus> {
return fetchWithTimeout<VideoStatus>(
`${ACADEMY_API_BASE}/api/v1/academy/courses/${courseId}/generate-videos`,
{
method: 'POST'
}
)
}
/**
* Video-Generierungs-Status abrufen
*/
export async function getVideoStatus(courseId: string): Promise<VideoStatus> {
return fetchWithTimeout<VideoStatus>(
`${ACADEMY_API_BASE}/api/v1/academy/courses/${courseId}/video-status`
)
}
// =============================================================================
// CERTIFICATES (Extended)
// =============================================================================
/**
* Zertifikat als PDF herunterladen
*/
export async function downloadCertificatePDF(certificateId: string): Promise<Blob> {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT)
try {
const response = await fetch(
`${ACADEMY_API_BASE}/api/v1/academy/certificates/${certificateId}/pdf`,
{
signal: controller.signal,
headers: getAuthHeaders()
}
)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return response.blob()
} finally {
clearTimeout(timeoutId)
}
}
// =============================================================================
// SDK PROXY FUNCTION (wraps fetchCourses + fetchAcademyStatistics)
// =============================================================================

View File

@@ -240,6 +240,39 @@ export interface SubmitQuizResponse {
results: { questionId: string; correct: boolean; explanation: string }[]
}
// =============================================================================
// AI GENERATION TYPES
// =============================================================================
export interface GenerateCourseRequest {
tenantId: string
topic: string
category: CourseCategory
targetGroup?: string
language?: string
useRag?: boolean
ragQuery?: string
}
export interface GenerateCourseResponse {
course: Course
ragSources?: { id: string; content: string; source: string; score: number }[]
model: string
}
export interface VideoStatus {
courseId: string
status: 'not_started' | 'pending' | 'processing' | 'completed' | 'failed'
lessons: LessonVideoStatus[]
}
export interface LessonVideoStatus {
lessonId: string
status: string
videoUrl?: string
audioUrl?: string
}
// =============================================================================
// HELPER FUNCTIONS
// =============================================================================