Install LOC guardrails (check-loc.sh, architecture.md, pre-commit hook) and split all 44 files exceeding 500 LOC into domain-focused modules: - consent-service (Go): models, handlers, services, database splits - backend-core (Python): security_api, rbac_api, pdf_service, auth splits - admin-core (TypeScript): 5 page.tsx + sidebar extractions - pitch-deck (TypeScript): 6 slides, 3 UI components, engine.ts splits - voice-service (Python): enhanced_task_orchestrator split Result: 0 violations, 36 exempted (pipeline, tests, pure-data files). Go build verified clean. No behavior changes — pure structural splits. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
188 lines
8.3 KiB
Go
188 lines
8.3 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// SchoolRole defines roles within the school system
|
|
const (
|
|
SchoolRoleTeacher = "teacher"
|
|
SchoolRoleClassTeacher = "class_teacher"
|
|
SchoolRoleParent = "parent"
|
|
SchoolRoleParentRep = "parent_representative"
|
|
SchoolRoleStudent = "student"
|
|
SchoolRoleAdmin = "school_admin"
|
|
SchoolRolePrincipal = "principal"
|
|
SchoolRoleSecretary = "secretary"
|
|
)
|
|
|
|
// AttendanceStatus defines the status of student attendance
|
|
const (
|
|
AttendancePresent = "present"
|
|
AttendanceAbsent = "absent"
|
|
AttendanceAbsentExcused = "excused"
|
|
AttendanceAbsentUnexcused = "unexcused"
|
|
AttendanceLate = "late"
|
|
AttendanceLateExcused = "late_excused"
|
|
AttendancePending = "pending_confirmation"
|
|
)
|
|
|
|
// GradeType defines the type of grade
|
|
const (
|
|
GradeTypeExam = "exam" // Klassenarbeit/Klausur
|
|
GradeTypeTest = "test" // Test/Kurzarbeit
|
|
GradeTypeOral = "oral" // Mündlich
|
|
GradeTypeHomework = "homework" // Hausaufgabe
|
|
GradeTypeProject = "project" // Projekt
|
|
GradeTypeParticipation = "participation" // Mitarbeit
|
|
GradeTypeSemester = "semester" // Halbjahres-/Semesternote
|
|
GradeTypeFinal = "final" // Endnote/Zeugnisnote
|
|
)
|
|
|
|
// School represents a school/educational institution
|
|
type School struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
Name string `json:"name" db:"name"`
|
|
ShortName *string `json:"short_name,omitempty" db:"short_name"`
|
|
Type string `json:"type" db:"type"` // 'grundschule', 'hauptschule', 'realschule', 'gymnasium', 'gesamtschule', 'berufsschule'
|
|
Address *string `json:"address,omitempty" db:"address"`
|
|
City *string `json:"city,omitempty" db:"city"`
|
|
PostalCode *string `json:"postal_code,omitempty" db:"postal_code"`
|
|
State *string `json:"state,omitempty" db:"state"` // Bundesland
|
|
Country string `json:"country" db:"country"` // Default: DE
|
|
Phone *string `json:"phone,omitempty" db:"phone"`
|
|
Email *string `json:"email,omitempty" db:"email"`
|
|
Website *string `json:"website,omitempty" db:"website"`
|
|
MatrixServerName *string `json:"matrix_server_name,omitempty" db:"matrix_server_name"`
|
|
LogoURL *string `json:"logo_url,omitempty" db:"logo_url"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
}
|
|
|
|
// SchoolYear represents an academic year
|
|
type SchoolYear struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
SchoolID uuid.UUID `json:"school_id" db:"school_id"`
|
|
Name string `json:"name" db:"name"` // e.g., "2024/2025"
|
|
StartDate time.Time `json:"start_date" db:"start_date"`
|
|
EndDate time.Time `json:"end_date" db:"end_date"`
|
|
IsCurrent bool `json:"is_current" db:"is_current"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// Class represents a school class
|
|
type Class struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
SchoolID uuid.UUID `json:"school_id" db:"school_id"`
|
|
SchoolYearID uuid.UUID `json:"school_year_id" db:"school_year_id"`
|
|
Name string `json:"name" db:"name"` // e.g., "5a", "10b"
|
|
Grade int `json:"grade" db:"grade"` // Klassenstufe: 1-13
|
|
Section *string `json:"section,omitempty" db:"section"`
|
|
Room *string `json:"room,omitempty" db:"room"`
|
|
MatrixInfoRoom *string `json:"matrix_info_room,omitempty" db:"matrix_info_room"`
|
|
MatrixRepRoom *string `json:"matrix_rep_room,omitempty" db:"matrix_rep_room"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
}
|
|
|
|
// Subject represents a school subject
|
|
type Subject struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
SchoolID uuid.UUID `json:"school_id" db:"school_id"`
|
|
Name string `json:"name" db:"name"` // e.g., "Mathematik", "Deutsch"
|
|
ShortName string `json:"short_name" db:"short_name"` // e.g., "Ma", "De"
|
|
Color *string `json:"color,omitempty" db:"color"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// Student represents a student
|
|
type Student struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
SchoolID uuid.UUID `json:"school_id" db:"school_id"`
|
|
ClassID uuid.UUID `json:"class_id" db:"class_id"`
|
|
UserID *uuid.UUID `json:"user_id,omitempty" db:"user_id"`
|
|
StudentNumber *string `json:"student_number,omitempty" db:"student_number"`
|
|
FirstName string `json:"first_name" db:"first_name"`
|
|
LastName string `json:"last_name" db:"last_name"`
|
|
DateOfBirth *time.Time `json:"date_of_birth,omitempty" db:"date_of_birth"`
|
|
Gender *string `json:"gender,omitempty" db:"gender"`
|
|
MatrixUserID *string `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
|
|
MatrixDMRoom *string `json:"matrix_dm_room,omitempty" db:"matrix_dm_room"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
}
|
|
|
|
// Teacher represents a teacher
|
|
type Teacher struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
SchoolID uuid.UUID `json:"school_id" db:"school_id"`
|
|
UserID uuid.UUID `json:"user_id" db:"user_id"`
|
|
TeacherCode *string `json:"teacher_code,omitempty" db:"teacher_code"`
|
|
Title *string `json:"title,omitempty" db:"title"`
|
|
FirstName string `json:"first_name" db:"first_name"`
|
|
LastName string `json:"last_name" db:"last_name"`
|
|
MatrixUserID *string `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
}
|
|
|
|
// ClassTeacher assigns teachers to classes (Klassenlehrer)
|
|
type ClassTeacher struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
ClassID uuid.UUID `json:"class_id" db:"class_id"`
|
|
TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
|
|
IsPrimary bool `json:"is_primary" db:"is_primary"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// TeacherSubject assigns subjects to teachers
|
|
type TeacherSubject struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
|
|
SubjectID uuid.UUID `json:"subject_id" db:"subject_id"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// Parent represents a parent/guardian
|
|
type Parent struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
UserID uuid.UUID `json:"user_id" db:"user_id"`
|
|
MatrixUserID *string `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
|
|
FirstName string `json:"first_name" db:"first_name"`
|
|
LastName string `json:"last_name" db:"last_name"`
|
|
Phone *string `json:"phone,omitempty" db:"phone"`
|
|
EmergencyContact bool `json:"emergency_contact" db:"emergency_contact"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
}
|
|
|
|
// StudentParent links students to their parents
|
|
type StudentParent struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
StudentID uuid.UUID `json:"student_id" db:"student_id"`
|
|
ParentID uuid.UUID `json:"parent_id" db:"parent_id"`
|
|
Relationship string `json:"relationship" db:"relationship"`
|
|
IsPrimary bool `json:"is_primary" db:"is_primary"`
|
|
HasCustody bool `json:"has_custody" db:"has_custody"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// ParentRepresentative assigns parent representatives to classes
|
|
type ParentRepresentative struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
ClassID uuid.UUID `json:"class_id" db:"class_id"`
|
|
ParentID uuid.UUID `json:"parent_id" db:"parent_id"`
|
|
Role string `json:"role" db:"role"` // 'first_rep', 'second_rep', 'substitute'
|
|
ElectedAt time.Time `json:"elected_at" db:"elected_at"`
|
|
ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"`
|
|
IsActive bool `json:"is_active" db:"is_active"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|