Add background PDF generation for published document versions

Move PDF generation from synchronous publish flow to a background polling
job. Published versions with file_id IS NULL are picked up by the job,
which generates the PDF, uploads to S3, and links the file. Export PDF
now serves stored files for published versions (with optional signature
page and watermark) and generates on the fly for drafts.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-04-17 08:15:57 +02:00
parent ff175e3d0d
commit 25c590ffe6
13 changed files with 795 additions and 70 deletions

View File

@@ -44,6 +44,9 @@ var (
//go:embed transfer_impact_assessments_template.html
transferImpactAssessmentsTemplateContent string
//go:embed signature_page_template.html
signaturePageTemplateContent string
templateFuncs = template.FuncMap{
"now": func() time.Time { return time.Now() },
"eq": func(a, b any) bool { return a == b },
@@ -183,6 +186,8 @@ var (
dataProtectionImpactAssessmentsTemplate = template.Must(template.New("dataProtectionImpactAssessments").Funcs(templateFuncs).Parse(dataProtectionImpactAssessmentsTemplateContent))
transferImpactAssessmentsTemplate = template.Must(template.New("transferImpactAssessments").Funcs(templateFuncs).Parse(transferImpactAssessmentsTemplateContent))
signaturePageTemplate = template.Must(template.New("signaturePage").Funcs(templateFuncs).Parse(signaturePageTemplateContent))
)
type (
@@ -210,6 +215,11 @@ type (
RequestedAt time.Time
}
SignaturePageData struct {
Signatures []SignatureData
Landscape bool
}
ProcessingActivityTableData struct {
CompanyName string
CompanyHorizontalLogoBase64 string
@@ -399,6 +409,15 @@ func RenderHTML(data DocumentData) ([]byte, error) {
return buf.Bytes(), nil
}
func RenderSignaturePageHTML(data SignaturePageData) ([]byte, error) {
var buf bytes.Buffer
if err := signaturePageTemplate.Execute(&buf, data); err != nil {
return nil, fmt.Errorf("cannot execute signature page template: %w", err)
}
return buf.Bytes(), nil
}
func RenderProcessingActivitiesTableHTML(data ProcessingActivityTableData) ([]byte, error) {
var buf bytes.Buffer
if err := processingActivitiesTemplate.Execute(&buf, data); err != nil {