feat(academy): add PDF certificate generation and download endpoint
Add gofpdf-based certificate PDF generation for the Compliance Academy. Landscape A4 certificates with company branding, course details, and verification URL. New route: GET /sdk/v1/academy/certificates/:id/pdf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -585,3 +585,48 @@ func (h *AcademyHandlers) GetStatistics(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, stats)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Certificate PDF Download
|
||||
// ============================================================================
|
||||
|
||||
// DownloadCertificatePDF generates and downloads a certificate as PDF
|
||||
// GET /sdk/v1/academy/certificates/:id/pdf
|
||||
func (h *AcademyHandlers) DownloadCertificatePDF(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid certificate ID"})
|
||||
return
|
||||
}
|
||||
|
||||
cert, err := h.store.GetCertificate(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if cert == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "certificate not found"})
|
||||
return
|
||||
}
|
||||
|
||||
validUntil := time.Now().UTC().AddDate(1, 0, 0)
|
||||
if cert.ValidUntil != nil {
|
||||
validUntil = *cert.ValidUntil
|
||||
}
|
||||
|
||||
pdfBytes, err := academy.GenerateCertificatePDF(academy.CertificateData{
|
||||
CertificateID: cert.ID.String(),
|
||||
UserName: cert.UserName,
|
||||
CourseName: cert.CourseTitle,
|
||||
IssuedAt: cert.IssuedAt,
|
||||
ValidUntil: validUntil,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate PDF: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
shortID := cert.ID.String()[:8]
|
||||
c.Header("Content-Disposition", "attachment; filename=zertifikat-"+shortID+".pdf")
|
||||
c.Data(http.StatusOK, "application/pdf", pdfBytes)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user