Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,26 @@ All endpoints live under the backend at `/api`. Auth-protected routes require a

---

Made with <3 by [euan](https://github.com/EDRipper) , give it a ⭐
## Certificates

This repository includes a certificates feature used to generate, persist and verify participation/fulfilment certificates.

- Generation: certificates are created server-side when an order is fulfilled (idempotent per order).
- Storage: certificates are persisted in the database with a unique `certificate_number` (format `CERT-<YEAR>-<random-id>`), `recipient_name`, `approved_hours`, `award_item`, and `certificate_text`.
- PDF: certificates are rendered server-side from HTML to PDF (Puppeteer) in landscape A4.

Key files and routes:
- Backend service: `backend/src/certificates/certificate.service.ts` (generation, HTML/PDF renderer, `syncCertificatesForUser`).
- Backend controller: `backend/src/certificates/certificate.controller.ts` — public verify endpoint `GET /api/certificates/verify/:certificateNumber` and authenticated sync `POST /api/certificates/sync`.
- Frontend verify page: `frontend/src/routes/verify/+page.svelte` and proxy `frontend/src/routes/api/certificates/verify/[certificateNumber]/+server.ts` (public lookup UI).
- Preview template: `frontend/static/example-certificate.html` (visual template used for previewing the certificate design).

How to use locally:
- Fulfil an order via the backend `ShopService` flow to trigger certificate generation. Generation is idempotent (re-running for the same order will not create duplicates).
- To backfill certificates for an existing user, sign in on the frontend; the site layout calls `POST /api/certificates/sync` to create any missing certificates for fulfilled orders.
- Public verification: open the frontend verify page and enter a certificate number, or call the backend `GET /api/certificates/verify/:certificateNumber` directly.

Optional: signature images
- The certificate template and generator support swapping the stylized handwritten signature text for actual signature images. Provide image URLs and I can wire them into `example-certificate.html` and `backend/src/certificates/certificate.service.ts`.

Made with &#60;3 by [euan](https://github.com/EDRipper) , give it a ⭐
5 changes: 4 additions & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
FROM node:22-alpine AS build
ENV PUPPETEER_SKIP_DOWNLOAD=true
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
RUN apk add --no-cache curl
RUN apk add --no-cache curl chromium nss freetype harfbuzz ttf-freefont
ENV PUPPETEER_SKIP_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
Expand Down
Loading
Loading