A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
291 lines
10 KiB
Go
291 lines
10 KiB
Go
package workshop
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// ============================================================================
|
|
// Constants / Enums
|
|
// ============================================================================
|
|
|
|
// SessionStatus represents the status of a workshop session
|
|
type SessionStatus string
|
|
|
|
const (
|
|
SessionStatusDraft SessionStatus = "DRAFT"
|
|
SessionStatusScheduled SessionStatus = "SCHEDULED"
|
|
SessionStatusActive SessionStatus = "ACTIVE"
|
|
SessionStatusPaused SessionStatus = "PAUSED"
|
|
SessionStatusCompleted SessionStatus = "COMPLETED"
|
|
SessionStatusCancelled SessionStatus = "CANCELLED"
|
|
)
|
|
|
|
// ParticipantRole represents the role of a participant
|
|
type ParticipantRole string
|
|
|
|
const (
|
|
ParticipantRoleFacilitator ParticipantRole = "FACILITATOR"
|
|
ParticipantRoleExpert ParticipantRole = "EXPERT" // DSB, IT-Security, etc.
|
|
ParticipantRoleStakeholder ParticipantRole = "STAKEHOLDER" // Business owner
|
|
ParticipantRoleObserver ParticipantRole = "OBSERVER"
|
|
)
|
|
|
|
// ResponseStatus represents the status of a question response
|
|
type ResponseStatus string
|
|
|
|
const (
|
|
ResponseStatusPending ResponseStatus = "PENDING"
|
|
ResponseStatusDraft ResponseStatus = "DRAFT"
|
|
ResponseStatusSubmitted ResponseStatus = "SUBMITTED"
|
|
ResponseStatusReviewed ResponseStatus = "REVIEWED"
|
|
)
|
|
|
|
// ============================================================================
|
|
// Main Entities
|
|
// ============================================================================
|
|
|
|
// Session represents a workshop session
|
|
type Session struct {
|
|
ID uuid.UUID `json:"id"`
|
|
TenantID uuid.UUID `json:"tenant_id"`
|
|
NamespaceID *uuid.UUID `json:"namespace_id,omitempty"`
|
|
|
|
// Session info
|
|
Title string `json:"title"`
|
|
Description string `json:"description,omitempty"`
|
|
SessionType string `json:"session_type"` // "ucca", "dsfa", "custom"
|
|
Status SessionStatus `json:"status"`
|
|
|
|
// Wizard configuration
|
|
WizardSchema string `json:"wizard_schema,omitempty"` // Reference to wizard schema version
|
|
CurrentStep int `json:"current_step"`
|
|
TotalSteps int `json:"total_steps"`
|
|
|
|
// Linked entities
|
|
AssessmentID *uuid.UUID `json:"assessment_id,omitempty"` // Link to UCCA assessment
|
|
RoadmapID *uuid.UUID `json:"roadmap_id,omitempty"` // Link to roadmap
|
|
PortfolioID *uuid.UUID `json:"portfolio_id,omitempty"` // Link to portfolio
|
|
|
|
// Scheduling
|
|
ScheduledStart *time.Time `json:"scheduled_start,omitempty"`
|
|
ScheduledEnd *time.Time `json:"scheduled_end,omitempty"`
|
|
ActualStart *time.Time `json:"actual_start,omitempty"`
|
|
ActualEnd *time.Time `json:"actual_end,omitempty"`
|
|
|
|
// Access control
|
|
JoinCode string `json:"join_code,omitempty"` // Code for participants to join
|
|
RequireAuth bool `json:"require_auth"` // Require authentication to join
|
|
AllowAnonymous bool `json:"allow_anonymous"` // Allow anonymous participation
|
|
|
|
// Settings
|
|
Settings SessionSettings `json:"settings"`
|
|
|
|
// Audit
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
CreatedBy uuid.UUID `json:"created_by"`
|
|
}
|
|
|
|
// SessionSettings contains session configuration
|
|
type SessionSettings struct {
|
|
AllowBackNavigation bool `json:"allow_back_navigation"` // Can go back to previous steps
|
|
RequireAllResponses bool `json:"require_all_responses"` // All questions must be answered
|
|
ShowProgressToAll bool `json:"show_progress_to_all"` // Show progress to all participants
|
|
AllowNotes bool `json:"allow_notes"` // Allow adding notes
|
|
AutoSave bool `json:"auto_save"` // Auto-save responses
|
|
TimeoutMinutes int `json:"timeout_minutes,omitempty"` // Auto-pause after inactivity
|
|
}
|
|
|
|
// Participant represents a participant in a session
|
|
type Participant struct {
|
|
ID uuid.UUID `json:"id"`
|
|
SessionID uuid.UUID `json:"session_id"`
|
|
UserID *uuid.UUID `json:"user_id,omitempty"` // Nil for anonymous
|
|
|
|
// Info
|
|
Name string `json:"name"`
|
|
Email string `json:"email,omitempty"`
|
|
Role ParticipantRole `json:"role"`
|
|
Department string `json:"department,omitempty"`
|
|
|
|
// Status
|
|
IsActive bool `json:"is_active"`
|
|
LastActiveAt *time.Time `json:"last_active_at,omitempty"`
|
|
JoinedAt time.Time `json:"joined_at"`
|
|
LeftAt *time.Time `json:"left_at,omitempty"`
|
|
|
|
// Permissions
|
|
CanEdit bool `json:"can_edit"` // Can modify responses
|
|
CanComment bool `json:"can_comment"` // Can add comments
|
|
CanApprove bool `json:"can_approve"` // Can approve responses
|
|
}
|
|
|
|
// StepProgress tracks progress on a specific wizard step
|
|
type StepProgress struct {
|
|
ID uuid.UUID `json:"id"`
|
|
SessionID uuid.UUID `json:"session_id"`
|
|
StepNumber int `json:"step_number"`
|
|
|
|
// Status
|
|
Status string `json:"status"` // "pending", "in_progress", "completed", "skipped"
|
|
Progress int `json:"progress"` // 0-100
|
|
|
|
// Timestamps
|
|
StartedAt *time.Time `json:"started_at,omitempty"`
|
|
CompletedAt *time.Time `json:"completed_at,omitempty"`
|
|
|
|
// Facilitator notes
|
|
Notes string `json:"notes,omitempty"`
|
|
}
|
|
|
|
// Response represents a response to a wizard question
|
|
type Response struct {
|
|
ID uuid.UUID `json:"id"`
|
|
SessionID uuid.UUID `json:"session_id"`
|
|
ParticipantID uuid.UUID `json:"participant_id"`
|
|
|
|
// Question reference
|
|
StepNumber int `json:"step_number"`
|
|
FieldID string `json:"field_id"` // From wizard schema
|
|
|
|
// Response data
|
|
Value interface{} `json:"value"` // Can be string, bool, array, etc.
|
|
ValueType string `json:"value_type"` // "string", "boolean", "array", "number"
|
|
|
|
// Status
|
|
Status ResponseStatus `json:"status"`
|
|
|
|
// Review
|
|
ReviewedBy *uuid.UUID `json:"reviewed_by,omitempty"`
|
|
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
|
|
ReviewNotes string `json:"review_notes,omitempty"`
|
|
|
|
// Audit
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// Comment represents a comment on a response or step
|
|
type Comment struct {
|
|
ID uuid.UUID `json:"id"`
|
|
SessionID uuid.UUID `json:"session_id"`
|
|
ParticipantID uuid.UUID `json:"participant_id"`
|
|
|
|
// Target
|
|
StepNumber *int `json:"step_number,omitempty"`
|
|
FieldID *string `json:"field_id,omitempty"`
|
|
ResponseID *uuid.UUID `json:"response_id,omitempty"`
|
|
|
|
// Content
|
|
Text string `json:"text"`
|
|
IsResolved bool `json:"is_resolved"`
|
|
|
|
// Audit
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// SessionSummary contains aggregated session information
|
|
type SessionSummary struct {
|
|
Session *Session `json:"session"`
|
|
Participants []Participant `json:"participants"`
|
|
StepProgress []StepProgress `json:"step_progress"`
|
|
TotalResponses int `json:"total_responses"`
|
|
CompletedSteps int `json:"completed_steps"`
|
|
OverallProgress int `json:"overall_progress"` // 0-100
|
|
}
|
|
|
|
// ============================================================================
|
|
// API Request/Response Types
|
|
// ============================================================================
|
|
|
|
// CreateSessionRequest is the API request for creating a session
|
|
type CreateSessionRequest struct {
|
|
Title string `json:"title"`
|
|
Description string `json:"description,omitempty"`
|
|
SessionType string `json:"session_type"`
|
|
WizardSchema string `json:"wizard_schema,omitempty"`
|
|
ScheduledStart *time.Time `json:"scheduled_start,omitempty"`
|
|
ScheduledEnd *time.Time `json:"scheduled_end,omitempty"`
|
|
Settings SessionSettings `json:"settings,omitempty"`
|
|
AssessmentID *uuid.UUID `json:"assessment_id,omitempty"`
|
|
RoadmapID *uuid.UUID `json:"roadmap_id,omitempty"`
|
|
PortfolioID *uuid.UUID `json:"portfolio_id,omitempty"`
|
|
}
|
|
|
|
// CreateSessionResponse is the API response for creating a session
|
|
type CreateSessionResponse struct {
|
|
Session Session `json:"session"`
|
|
JoinURL string `json:"join_url,omitempty"`
|
|
JoinCode string `json:"join_code,omitempty"`
|
|
}
|
|
|
|
// JoinSessionRequest is the API request for joining a session
|
|
type JoinSessionRequest struct {
|
|
Name string `json:"name"`
|
|
Email string `json:"email,omitempty"`
|
|
Role ParticipantRole `json:"role,omitempty"`
|
|
Department string `json:"department,omitempty"`
|
|
}
|
|
|
|
// JoinSessionResponse is the API response for joining a session
|
|
type JoinSessionResponse struct {
|
|
Participant Participant `json:"participant"`
|
|
Session Session `json:"session"`
|
|
Token string `json:"token,omitempty"` // Session-specific token
|
|
}
|
|
|
|
// SubmitResponseRequest is the API request for submitting a response
|
|
type SubmitResponseRequest struct {
|
|
StepNumber int `json:"step_number"`
|
|
FieldID string `json:"field_id"`
|
|
Value interface{} `json:"value"`
|
|
}
|
|
|
|
// AdvanceStepRequest is the API request for advancing to next step
|
|
type AdvanceStepRequest struct {
|
|
Responses []SubmitResponseRequest `json:"responses,omitempty"` // Optional batch submit
|
|
Notes string `json:"notes,omitempty"`
|
|
}
|
|
|
|
// SessionFilters defines filters for listing sessions
|
|
type SessionFilters struct {
|
|
Status SessionStatus
|
|
SessionType string
|
|
AssessmentID *uuid.UUID
|
|
CreatedBy *uuid.UUID
|
|
Limit int
|
|
Offset int
|
|
}
|
|
|
|
// SessionStats contains statistics for a session
|
|
type SessionStats struct {
|
|
ParticipantCount int `json:"participant_count"`
|
|
ActiveParticipants int `json:"active_participants"`
|
|
ResponseCount int `json:"response_count"`
|
|
CommentCount int `json:"comment_count"`
|
|
CompletedSteps int `json:"completed_steps"`
|
|
TotalSteps int `json:"total_steps"`
|
|
AverageProgress int `json:"average_progress"`
|
|
ResponsesByStep map[int]int `json:"responses_by_step"`
|
|
ResponsesByField map[string]int `json:"responses_by_field"`
|
|
}
|
|
|
|
// ExportFormat specifies the export format for session data
|
|
type ExportFormat string
|
|
|
|
const (
|
|
ExportFormatJSON ExportFormat = "json"
|
|
ExportFormatMarkdown ExportFormat = "md"
|
|
ExportFormatPDF ExportFormat = "pdf"
|
|
)
|
|
|
|
// ExportSessionRequest is the API request for exporting session data
|
|
type ExportSessionRequest struct {
|
|
Format ExportFormat `json:"format"`
|
|
IncludeComments bool `json:"include_comments"`
|
|
IncludeHistory bool `json:"include_history"`
|
|
}
|