Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
200 lines
6.1 KiB
Go
200 lines
6.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/breakpilot/school-service/internal/models"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// GetCertificateTemplates returns available certificate templates
|
|
func (h *Handler) GetCertificateTemplates(c *gin.Context) {
|
|
templates := h.certificateService.GetAvailableTemplates()
|
|
respondSuccess(c, templates)
|
|
}
|
|
|
|
// GenerateCertificate generates a certificate for a student
|
|
func (h *Handler) GenerateCertificate(c *gin.Context) {
|
|
var req models.GenerateCertificateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
|
|
return
|
|
}
|
|
|
|
certificate, err := h.certificateService.GenerateCertificate(c.Request.Context(), &req)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to generate certificate: "+err.Error())
|
|
return
|
|
}
|
|
|
|
respondCreated(c, certificate)
|
|
}
|
|
|
|
// GetClassCertificates returns certificates for a class
|
|
func (h *Handler) GetClassCertificates(c *gin.Context) {
|
|
classID := c.Param("classId")
|
|
semesterStr := c.DefaultQuery("semester", "1")
|
|
|
|
semester, err := strconv.Atoi(semesterStr)
|
|
if err != nil || semester < 1 || semester > 2 {
|
|
semester = 1
|
|
}
|
|
|
|
certificates, err := h.certificateService.GetCertificates(c.Request.Context(), classID, semester)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to get certificates: "+err.Error())
|
|
return
|
|
}
|
|
|
|
respondSuccess(c, certificates)
|
|
}
|
|
|
|
// GetCertificate returns a single certificate
|
|
func (h *Handler) GetCertificate(c *gin.Context) {
|
|
certificateID := c.Param("id")
|
|
|
|
certificate, err := h.certificateService.GetCertificate(c.Request.Context(), certificateID)
|
|
if err != nil {
|
|
respondError(c, http.StatusNotFound, "Certificate not found")
|
|
return
|
|
}
|
|
|
|
respondSuccess(c, certificate)
|
|
}
|
|
|
|
// UpdateCertificate updates a certificate's remarks
|
|
func (h *Handler) UpdateCertificate(c *gin.Context) {
|
|
certificateID := c.Param("id")
|
|
|
|
var req struct {
|
|
Remarks string `json:"remarks"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
|
|
return
|
|
}
|
|
|
|
certificate, err := h.certificateService.UpdateCertificate(c.Request.Context(), certificateID, req.Remarks)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to update certificate: "+err.Error())
|
|
return
|
|
}
|
|
|
|
respondSuccess(c, certificate)
|
|
}
|
|
|
|
// FinalizeCertificate finalizes a certificate
|
|
func (h *Handler) FinalizeCertificate(c *gin.Context) {
|
|
certificateID := c.Param("id")
|
|
|
|
if err := h.certificateService.FinalizeCertificate(c.Request.Context(), certificateID); err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to finalize certificate: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Certificate finalized"})
|
|
}
|
|
|
|
// GetCertificatePDF returns the PDF for a certificate
|
|
func (h *Handler) GetCertificatePDF(c *gin.Context) {
|
|
certificateID := c.Param("id")
|
|
|
|
pdf, err := h.certificateService.GeneratePDF(c.Request.Context(), certificateID)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to generate PDF: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.Header("Content-Type", "application/pdf")
|
|
c.Header("Content-Disposition", "attachment; filename=zeugnis.pdf")
|
|
c.Data(http.StatusOK, "application/pdf", pdf)
|
|
}
|
|
|
|
// DeleteCertificate deletes a certificate
|
|
func (h *Handler) DeleteCertificate(c *gin.Context) {
|
|
certificateID := c.Param("id")
|
|
|
|
if err := h.certificateService.DeleteCertificate(c.Request.Context(), certificateID); err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to delete certificate: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Certificate deleted"})
|
|
}
|
|
|
|
// BulkGenerateCertificates generates certificates for all students in a class
|
|
func (h *Handler) BulkGenerateCertificates(c *gin.Context) {
|
|
var req struct {
|
|
ClassID string `json:"class_id" binding:"required"`
|
|
SchoolYearID string `json:"school_year_id" binding:"required"`
|
|
Semester int `json:"semester" binding:"required,min=1,max=2"`
|
|
CertificateType models.CertificateType `json:"certificate_type" binding:"required"`
|
|
TemplateName string `json:"template_name"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
|
|
return
|
|
}
|
|
|
|
certificates, err := h.certificateService.BulkGenerateCertificates(c.Request.Context(), req.ClassID, req.SchoolYearID, req.Semester, req.CertificateType, req.TemplateName)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to generate certificates: "+err.Error())
|
|
return
|
|
}
|
|
|
|
respondSuccess(c, gin.H{
|
|
"message": "Certificates generated",
|
|
"count": len(certificates),
|
|
"certificates": certificates,
|
|
})
|
|
}
|
|
|
|
// GenerateGradeFeedback generates AI feedback for a student
|
|
func (h *Handler) GenerateGradeFeedback(c *gin.Context) {
|
|
studentID := c.Param("studentId")
|
|
semesterStr := c.DefaultQuery("semester", "1")
|
|
|
|
semester, err := strconv.Atoi(semesterStr)
|
|
if err != nil || semester < 1 || semester > 2 {
|
|
semester = 1
|
|
}
|
|
|
|
// Get student grades
|
|
grades, err := h.gradeService.GetStudentGrades(c.Request.Context(), studentID)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to get student grades: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Build grades map for the requested semester
|
|
gradeMap := make(map[string]float64)
|
|
var studentName string
|
|
for _, g := range grades {
|
|
if g.Semester == semester && g.FinalGrade != nil {
|
|
gradeMap[g.SubjectName] = *g.FinalGrade
|
|
studentName = g.StudentName
|
|
}
|
|
}
|
|
|
|
if len(gradeMap) == 0 {
|
|
respondError(c, http.StatusNotFound, "No grades found for this semester")
|
|
return
|
|
}
|
|
|
|
// Generate feedback using AI
|
|
feedback, err := h.aiService.GenerateGradeFeedback(c.Request.Context(), studentName, gradeMap, semester)
|
|
if err != nil {
|
|
respondError(c, http.StatusInternalServerError, "Failed to generate feedback: "+err.Error())
|
|
return
|
|
}
|
|
|
|
respondSuccess(c, gin.H{
|
|
"student_id": studentID,
|
|
"student_name": studentName,
|
|
"semester": semester,
|
|
"feedback": feedback,
|
|
})
|
|
}
|