This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/school-service/internal/handlers/gradebook_handlers.go
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
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>
2026-02-09 09:51:32 +01:00

210 lines
5.7 KiB
Go

package handlers
import (
"net/http"
"time"
"github.com/breakpilot/school-service/internal/models"
"github.com/gin-gonic/gin"
)
// Attendance Handlers
// CreateAttendance creates an attendance record
func (h *Handler) CreateAttendance(c *gin.Context) {
var req models.CreateAttendanceRequest
if err := c.ShouldBindJSON(&req); err != nil {
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
return
}
attendance, err := h.gradebookService.CreateAttendance(c.Request.Context(), &req)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error())
return
}
respondCreated(c, attendance)
}
// GetClassAttendance returns attendance for a class
func (h *Handler) GetClassAttendance(c *gin.Context) {
classID := c.Param("classId")
startDateStr := c.Query("start_date")
endDateStr := c.Query("end_date")
var startDate, endDate *time.Time
if startDateStr != "" {
t, err := time.Parse("2006-01-02", startDateStr)
if err == nil {
startDate = &t
}
}
if endDateStr != "" {
t, err := time.Parse("2006-01-02", endDateStr)
if err == nil {
endDate = &t
}
}
attendance, err := h.gradebookService.GetClassAttendance(c.Request.Context(), classID, startDate, endDate)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error())
return
}
respondSuccess(c, attendance)
}
// GetStudentAttendance returns attendance for a student
func (h *Handler) GetStudentAttendance(c *gin.Context) {
studentID := c.Param("studentId")
attendance, err := h.gradebookService.GetStudentAttendance(c.Request.Context(), studentID)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error())
return
}
respondSuccess(c, attendance)
}
// DeleteAttendance deletes an attendance record
func (h *Handler) DeleteAttendance(c *gin.Context) {
attendanceID := c.Param("id")
if err := h.gradebookService.DeleteAttendance(c.Request.Context(), attendanceID); err != nil {
respondError(c, http.StatusInternalServerError, "Failed to delete attendance: "+err.Error())
return
}
c.JSON(http.StatusOK, gin.H{"message": "Attendance deleted"})
}
// BulkCreateAttendance creates attendance for multiple students
func (h *Handler) BulkCreateAttendance(c *gin.Context) {
classID := c.Param("classId")
var req struct {
Date string `json:"date" binding:"required"`
Records []struct {
StudentID string `json:"student_id" binding:"required"`
Status models.AttendanceStatus `json:"status" binding:"required"`
Periods int `json:"periods"`
Reason string `json:"reason"`
} `json:"records" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
return
}
records := make([]struct {
StudentID string
Status models.AttendanceStatus
Periods int
Reason string
}, len(req.Records))
for i, r := range req.Records {
records[i] = struct {
StudentID string
Status models.AttendanceStatus
Periods int
Reason string
}{
StudentID: r.StudentID,
Status: r.Status,
Periods: r.Periods,
Reason: r.Reason,
}
}
if err := h.gradebookService.BulkCreateAttendance(c.Request.Context(), classID, req.Date, records); err != nil {
respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error())
return
}
c.JSON(http.StatusOK, gin.H{"message": "Attendance created"})
}
// Gradebook Entry Handlers
// CreateGradebookEntry creates a gradebook entry
func (h *Handler) CreateGradebookEntry(c *gin.Context) {
var req models.CreateGradebookEntryRequest
if err := c.ShouldBindJSON(&req); err != nil {
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
return
}
entry, err := h.gradebookService.CreateGradebookEntry(c.Request.Context(), &req)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to create entry: "+err.Error())
return
}
respondCreated(c, entry)
}
// GetGradebookEntries returns entries for a class
func (h *Handler) GetGradebookEntries(c *gin.Context) {
classID := c.Param("classId")
entryTypeStr := c.Query("entry_type")
startDateStr := c.Query("start_date")
endDateStr := c.Query("end_date")
var entryType *string
if entryTypeStr != "" {
entryType = &entryTypeStr
}
var startDate, endDate *time.Time
if startDateStr != "" {
t, err := time.Parse("2006-01-02", startDateStr)
if err == nil {
startDate = &t
}
}
if endDateStr != "" {
t, err := time.Parse("2006-01-02", endDateStr)
if err == nil {
endDate = &t
}
}
entries, err := h.gradebookService.GetGradebookEntries(c.Request.Context(), classID, entryType, startDate, endDate)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error())
return
}
respondSuccess(c, entries)
}
// GetStudentEntries returns gradebook entries for a student
func (h *Handler) GetStudentEntries(c *gin.Context) {
studentID := c.Param("studentId")
entries, err := h.gradebookService.GetStudentEntries(c.Request.Context(), studentID)
if err != nil {
respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error())
return
}
respondSuccess(c, entries)
}
// DeleteGradebookEntry deletes a gradebook entry
func (h *Handler) DeleteGradebookEntry(c *gin.Context) {
entryID := c.Param("id")
if err := h.gradebookService.DeleteGradebookEntry(c.Request.Context(), entryID); err != nil {
respondError(c, http.StatusInternalServerError, "Failed to delete entry: "+err.Error())
return
}
c.JSON(http.StatusOK, gin.H{"message": "Entry deleted"})
}