- Certificate model: serial_number (unique), status (pending/rendering/completed/failed),
pdf_path, pdf_hash (SHA-256), verification_url, render_attempts, training_record FK
- renderer.py: LaTeX template → pdflatex subprocess → PDF; _escape_latex for XSS safety;
compute_pdf_hash for immutable verification metadata
- services.py: issue_certificate() generates serial, creates record, enqueues Celery task
- tasks.py: render_certificate_task (bind=True, autoretry 3x with 60s backoff);
sets RENDERING → COMPLETED with hash; FAILED with error on all retries exhausted
- API: /certificates/ (own list), /certificates/{id}/ (own detail)
- 15 unit + integration tests: hash consistency, LaTeX escaping, mocked render, retry behavior
Co-Authored-By: Paperclip <noreply@paperclip.ing>
0 lines
0 B
Python
0 lines
0 B
Python
The file is empty.