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>
210 lines
8.5 KiB
Go
210 lines
8.5 KiB
Go
package api
|
|
|
|
// Academy Course models
|
|
|
|
// AcademyCourse represents a training course in the Academy module
|
|
type AcademyCourse struct {
|
|
ID string `json:"id"`
|
|
TenantID string `json:"tenantId,omitempty"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Category string `json:"category"`
|
|
PassingScore int `json:"passingScore"`
|
|
DurationMinutes int `json:"durationMinutes"`
|
|
RequiredForRoles []string `json:"requiredForRoles"`
|
|
Status string `json:"status"`
|
|
Lessons []AcademyLesson `json:"lessons"`
|
|
CreatedAt string `json:"createdAt"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
}
|
|
|
|
// AcademyLesson represents a single lesson within a course
|
|
type AcademyLesson struct {
|
|
ID string `json:"id"`
|
|
CourseID string `json:"courseId"`
|
|
Title string `json:"title"`
|
|
Type string `json:"type"` // video, text, quiz
|
|
ContentMarkdown string `json:"contentMarkdown"`
|
|
VideoURL string `json:"videoUrl,omitempty"`
|
|
AudioURL string `json:"audioUrl,omitempty"`
|
|
Order int `json:"order"`
|
|
DurationMinutes int `json:"durationMinutes"`
|
|
QuizQuestions []AcademyQuizQuestion `json:"quizQuestions,omitempty"`
|
|
}
|
|
|
|
// AcademyQuizQuestion represents a single quiz question within a lesson
|
|
type AcademyQuizQuestion struct {
|
|
ID string `json:"id"`
|
|
LessonID string `json:"lessonId"`
|
|
Question string `json:"question"`
|
|
Options []string `json:"options"`
|
|
CorrectOptionIndex int `json:"correctOptionIndex"`
|
|
Explanation string `json:"explanation"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
// AcademyEnrollment represents a user's enrollment in a course
|
|
type AcademyEnrollment struct {
|
|
ID string `json:"id"`
|
|
TenantID string `json:"tenantId,omitempty"`
|
|
CourseID string `json:"courseId"`
|
|
UserID string `json:"userId"`
|
|
UserName string `json:"userName"`
|
|
UserEmail string `json:"userEmail"`
|
|
Status string `json:"status"` // not_started, in_progress, completed, expired
|
|
Progress int `json:"progress"` // 0-100
|
|
StartedAt string `json:"startedAt"`
|
|
CompletedAt string `json:"completedAt,omitempty"`
|
|
CertificateID string `json:"certificateId,omitempty"`
|
|
Deadline string `json:"deadline"`
|
|
CreatedAt string `json:"createdAt,omitempty"`
|
|
UpdatedAt string `json:"updatedAt,omitempty"`
|
|
}
|
|
|
|
// AcademyCertificate represents a certificate issued upon course completion
|
|
type AcademyCertificate struct {
|
|
ID string `json:"id"`
|
|
TenantID string `json:"tenantId,omitempty"`
|
|
EnrollmentID string `json:"enrollmentId"`
|
|
CourseID string `json:"courseId"`
|
|
UserID string `json:"userId"`
|
|
UserName string `json:"userName"`
|
|
CourseName string `json:"courseName"`
|
|
Score int `json:"score"`
|
|
IssuedAt string `json:"issuedAt"`
|
|
ValidUntil string `json:"validUntil"`
|
|
PdfURL string `json:"pdfUrl,omitempty"`
|
|
}
|
|
|
|
// AcademyLessonProgress tracks a user's progress through a single lesson
|
|
type AcademyLessonProgress struct {
|
|
ID string `json:"id"`
|
|
EnrollmentID string `json:"enrollmentId"`
|
|
LessonID string `json:"lessonId"`
|
|
Completed bool `json:"completed"`
|
|
QuizScore *int `json:"quizScore,omitempty"`
|
|
CompletedAt string `json:"completedAt,omitempty"`
|
|
}
|
|
|
|
// AcademyStatistics provides aggregate statistics for the Academy module
|
|
type AcademyStatistics struct {
|
|
TotalCourses int `json:"totalCourses"`
|
|
TotalEnrollments int `json:"totalEnrollments"`
|
|
CompletionRate int `json:"completionRate"`
|
|
OverdueCount int `json:"overdueCount"`
|
|
ByCategory map[string]int `json:"byCategory"`
|
|
ByStatus map[string]int `json:"byStatus"`
|
|
}
|
|
|
|
// Request types
|
|
|
|
// CreateCourseRequest is the request body for creating a new course
|
|
type CreateCourseRequest struct {
|
|
TenantID string `json:"tenantId" binding:"required"`
|
|
Title string `json:"title" binding:"required"`
|
|
Description string `json:"description"`
|
|
Category string `json:"category" binding:"required"`
|
|
DurationMinutes int `json:"durationMinutes"`
|
|
RequiredForRoles []string `json:"requiredForRoles"`
|
|
PassingScore int `json:"passingScore"`
|
|
Lessons []CreateLessonRequest `json:"lessons"`
|
|
}
|
|
|
|
// CreateLessonRequest is the request body for creating a lesson within a course
|
|
type CreateLessonRequest struct {
|
|
Title string `json:"title" binding:"required"`
|
|
Type string `json:"type" binding:"required"`
|
|
ContentMarkdown string `json:"contentMarkdown"`
|
|
VideoURL string `json:"videoUrl"`
|
|
Order int `json:"order"`
|
|
DurationMinutes int `json:"durationMinutes"`
|
|
QuizQuestions []CreateQuizQuestionRequest `json:"quizQuestions"`
|
|
}
|
|
|
|
// CreateQuizQuestionRequest is the request body for creating a quiz question
|
|
type CreateQuizQuestionRequest struct {
|
|
Question string `json:"question" binding:"required"`
|
|
Options []string `json:"options" binding:"required"`
|
|
CorrectOptionIndex int `json:"correctOptionIndex"`
|
|
Explanation string `json:"explanation"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
// UpdateCourseRequest is the request body for updating an existing course
|
|
type UpdateCourseRequest struct {
|
|
Title *string `json:"title"`
|
|
Description *string `json:"description"`
|
|
Category *string `json:"category"`
|
|
DurationMinutes *int `json:"durationMinutes"`
|
|
RequiredForRoles []string `json:"requiredForRoles"`
|
|
PassingScore *int `json:"passingScore"`
|
|
}
|
|
|
|
// EnrollUserRequest is the request body for enrolling a user in a course
|
|
type EnrollUserRequest struct {
|
|
TenantID string `json:"tenantId" binding:"required"`
|
|
CourseID string `json:"courseId" binding:"required"`
|
|
UserID string `json:"userId" binding:"required"`
|
|
UserName string `json:"userName" binding:"required"`
|
|
UserEmail string `json:"userEmail" binding:"required"`
|
|
Deadline string `json:"deadline" binding:"required"`
|
|
}
|
|
|
|
// UpdateProgressRequest is the request body for updating enrollment progress
|
|
type UpdateProgressRequest struct {
|
|
Progress int `json:"progress"`
|
|
LessonID string `json:"lessonId"`
|
|
}
|
|
|
|
// SubmitQuizRequest is the request body for submitting quiz answers
|
|
type SubmitQuizRequest struct {
|
|
Answers []int `json:"answers" binding:"required"`
|
|
}
|
|
|
|
// SubmitQuizResponse is the response for a quiz submission
|
|
type SubmitQuizResponse struct {
|
|
Score int `json:"score"`
|
|
Passed bool `json:"passed"`
|
|
CorrectAnswers int `json:"correctAnswers"`
|
|
TotalQuestions int `json:"totalQuestions"`
|
|
Results []QuizQuestionResult `json:"results"`
|
|
}
|
|
|
|
// QuizQuestionResult represents the result of a single quiz question
|
|
type QuizQuestionResult struct {
|
|
QuestionID string `json:"questionId"`
|
|
Correct bool `json:"correct"`
|
|
Explanation string `json:"explanation"`
|
|
}
|
|
|
|
// GenerateCourseRequest is the request body for AI-generating a course
|
|
type GenerateCourseRequest struct {
|
|
TenantID string `json:"tenantId" binding:"required"`
|
|
Topic string `json:"topic" binding:"required"`
|
|
Category string `json:"category" binding:"required"`
|
|
TargetGroup string `json:"targetGroup"`
|
|
Language string `json:"language"`
|
|
UseRAG bool `json:"useRag"`
|
|
RAGQuery string `json:"ragQuery"`
|
|
}
|
|
|
|
// GenerateVideosRequest is the request body for generating lesson videos
|
|
type GenerateVideosRequest struct {
|
|
TenantID string `json:"tenantId" binding:"required"`
|
|
}
|
|
|
|
// VideoStatusResponse represents the video generation status for a course
|
|
type VideoStatusResponse struct {
|
|
CourseID string `json:"courseId"`
|
|
Status string `json:"status"` // pending, processing, completed, failed
|
|
Lessons []LessonVideoStatus `json:"lessons"`
|
|
}
|
|
|
|
// LessonVideoStatus represents the video generation status for a single lesson
|
|
type LessonVideoStatus struct {
|
|
LessonID string `json:"lessonId"`
|
|
Status string `json:"status"`
|
|
VideoURL string `json:"videoUrl,omitempty"`
|
|
AudioURL string `json:"audioUrl,omitempty"`
|
|
}
|