A certificate for every person who sat down to learn.
Registration, attendance and certificates across four services, migrated with zero downtime and backed by 1,700+ tests.
One certificate per person.
Every certificate has its own public page: name, workshop, date and a verifiable identifier. It is what people share on LinkedIn and what an employer opens to check that it exists. Below is that page, re-created: move the pointer over the certificate and try the others in the collection.
The page offers the PDF to download, the link to share on social networks and a button that copies the verification link. The PDF does not live on a disk: it is composed on demand with sharp and pdfkit from the workshop's template, with the name as an SVG layer, in the same step that renders the 1200 × 627 social card.
- composed on demand
- SVG
- the name, as a layer over the template
- 1200 × 627
- social card per certificate


Congratulations, Diego. Here is your achievement.
Your new achievementMaster Search Console to boost your WordPress site's SEO

Sign up without an account, check in with one click.
Registration landing, Cloud brand
- 2
- brands, one landing page per workshop
- 0
- accounts required
Every workshop has its own registration landing page under the brand it belongs to: DonWeb Cloud or DonWeb's official brand. People leave a name and an e-mail, get the confirmation by e-mail and never create an account: the e-mail is the identity.
On the day, attendance is one more page: the person confirms they were there, the system marks them present and the certificate is ready to be issued. Confirmation, reminder and certificate e-mails go out through Customer.io with each registration's data.
The 2023 URLs are still alive.
The first certificate URLs carried the course id and the person's e-mail in plain sight: /72/72_persona@mail.com. Thousands of those links were already on LinkedIn and could not break. Today every certificate lives at /cloud/certificado/{uuid}, and the old URL still resolves: Caddy and a Next rewrite hand it to a resolver that answers 307 towards the new one.
The June 2026 migration moved 121,087 registrations and 205 programs without losing a record, and replaced 43 GB of PDFs stored on disk with certificates composed when requested. The nginx to Caddy cutover took about 17 seconds; the service never stopped.
- 121,087
- registrations migrated
- 205
- programs, nothing lost
- ~17 s
- nginx → Caddy cutover
The same certificate, two generations.
On the left, my own certificate from August 2024 as the original pipeline rendered it: a static image, composed on the server and stored on disk. On the right, the same certificate on the 2026 public page: verifiable, downloadable, with the person's whole collection underneath.
The format, the identifier and the way it is generated changed. Not one published link did.


May 2023: one service, one person.
Demo of the first version, 2023
I built the first version alone, in May 2023: Next 13 and Express, certificates composed with sharp and pdfkit, e-mail through Envialo Simple. A single service that registered, checked in and issued.
That version issued the first certificates and defined what the system had to preserve: the public URL as proof and the e-mail as identity. The 2026 renewal inherited those two decisions and replaced everything else.
Four services and a three-minute deploy.
The 2026 version is four services: the API on Node 22 and Fastify with a hexagonal architecture (domain, application, infrastructure), the public web on Next 15, the operations panel on Next 16 and the infrastructure on Docker Compose and Caddy, which handles TLS with a wildcard certificate. Directus sits on top of the legacy MySQL database, so the team edits the historic data without moving it to another engine.
Every change runs 2,180 test cases on Vitest. When they pass, GitHub Actions builds the image, publishes it to GHCR and promotes the immutable SHA to production: about three minutes from merge to production. Rolling back is promoting the previous SHA.
- 2,180
- test cases in 128 files
- ~3 min
- from merge to production
- 4
- services: api, web, panel, infra
A panel for the team that runs the workshops.
The operations panel creates the workshops, schedules the YouTube Live broadcasts through the Google API, follows registrations in real time and triggers the confirmation, reminder and certificate e-mails through Customer.io.
On a live-event day, errors per hour went from 5,718 to 8 after the renewal. The team operates from the panel; day-to-day support and the infrastructure remain with me.
- 5,718 → 8
- errors per hour on a live-event day
- −99.86%
- errors

1,700+ automated tests and a zero-downtime migration.
Operations panel figures as of July 2026.







