DiegoBarrionuevo
← Selected workP/02Production

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.

Development and technical leadership2023 — 2026
Node.jsFastifyTypeScriptReactPostgreSQLDirectusDockerCI/CD
The certificate

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.

PDF
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 achievement

Master Search Console to boost your WordPress site's SEO

Download
Certificate of attendance: Master Search Console to boost your WordPress site's SEO
Registration and attendance

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.

Migration

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
2023 → 2026

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.

Diego Barrionuevo's certificate from August 2024, rendered by the 2023 pipeline
2024, original pipeline render
The same certificate on the certificados.donweb.com public page in 2026
2026, public page
First version

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.

Platform

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
Operations

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
The sign-in screen of the workshops operations panel
Operations panel
As of July 2026
218courses, workshops and webinars
138,109registrations
123,253certificates issued

1,700+ automated tests and a zero-downtime migration.

Operations panel figures as of July 2026.
Next projectAda13 — Web platformThe web platform for Programmer's Day 2023 in Buenos Aires: registrations, transactional e-mail and support during the event.