From Word Templates to Verified Credentials in 30 Seconds

Written by, Adnan Khan on March 2, 2026

case-studyfull-stackeducation

A training provider was issuing certificates from Word templates.

Schools emailed requests. Staff tracked them in spreadsheets. Certificates were designed one-by-one in desktop publishing tools. And if an employer wanted to verify a credential? They couldn’t. Anyone with a color printer could forge one.

The whole process took days per certificate. It couldn’t scale, and it offered zero fraud protection.

We replaced it with a platform that does the entire pipeline, from enrollment to request to approval to PDF generation to public QR verification, in under 30 seconds.

The Client

CEOSH (Centre of Excellence for Occupational Safety and Health) runs occupational safety certifications through a network of partner schools across Pakistan. They needed to go from “emails and Excel” to a real platform. Not a WordPress plugin. Not a Google Form. A production-grade system that mirrors how their organization actually works.

That meant multi-tenant architecture. Provider-level oversight. School-level autonomy. And a certificate that employers can verify instantly by scanning a QR code.

What Manual Certificate Issuance Actually Costs You

If you’re still running certificates through Word templates, this is what’s really happening.

Your staff is spending hours on data entry that a database handles in milliseconds. Your certificates have zero verification, which means they have zero credibility. Your partner organizations are emailing requests that get lost, duplicated, or delayed. And your data lives in six different spreadsheets that nobody trusts.

The problem isn’t laziness. The process was never designed to scale past a handful of certificates per month.

CEOSH was growing. More schools, more students, more courses. The manual process was already breaking.

What We Built

CertifyMe is a multi-tenant certificate management platform with two role-based portals.

Providers (CEOSH) manage courses, batches, partner schools, and certificate approvals. They have final authority over every credential issued.

Learning Partners (Schools) manage their own students, submit enrollment records, and request certificates for students who complete courses.

This hierarchy isn’t arbitrary. It mirrors the real organizational structure: schools handle day-to-day operations, CEOSH retains oversight and approval authority. The software enforces the same boundaries that already exist in the real world.

14 database tables. 200 TypeScript files. Around 26,000 lines of code. 3 distinct PDF document types. And a public verification system that works without any authentication.

The Certificate Pipeline

Five steps from enrollment to a verified, downloadable PDF. This is the core of the platform.

Step 1: Enrollment. A school enrolls a student into a specific course and batch. Registration numbers are generated deterministically: 2025-PKSC-001. No manual entry, no duplicates, no guessing.

Step 2: Certificate Request. When a student finishes a course, the school submits a request. One click. The enrollment status moves from pending to requested.

Step 3: Provider Review. CEOSH staff see all pending requests in a filterable, searchable table. For each request, they enter per-subject marks and grades. A grade auto-suggestion algorithm calculates grades from percentages using UK-standard thresholds (90%+ is A+, below 35% is F), but the admin can always override. Then they approve or reject.

This is where the engineering matters. Approving a request requires four simultaneous database changes: update the request status, delete any existing transcript entries, insert new transcript entries, and mark the enrollment as completed. All four must succeed or all four must fail. We execute them in a single atomic batch operation using Neon’s HTTP batch API. No partial state. No orphaned records.

Step 4: PDF Generation. After approval, CEOSH generates three documents with one workflow:

All three are generated server-side, uploaded to cloud storage, and linked in the database. Each can be regenerated independently if needed.

Step 5: Public Verification. Anyone (employers, regulators, other institutions) can verify a certificate by scanning the QR code or visiting /verify-certificate/{number}. No login required. The page shows verification status, student details, course information, and a direct download link to the PDF.

The verification pages generate dynamic SEO metadata too, so search engines can index individual certificates. Your credentials become discoverable.

React PDF: No Puppeteer, No Headless Chrome, No Nonsense

This is one of the engineering decisions I’m most proud of.

Most certificate generation systems spin up a headless Chrome instance, render an HTML page, and screenshot it to PDF. It works. But it’s slow, resource-heavy, and fragile. You’re literally running a browser on a server to generate a document.

We went a different direction.

Every certificate, course card, and transcript is a React component. JSX with custom fonts: Poppins for body text, Pinyon Script for calligraphic student names, Bebas Neue for headers. The components render to PDF buffers entirely server-side using @react-pdf/renderer.

No Puppeteer. No headless browsers. No Chrome instances. No system dependencies. Just React rendering to a buffer.

The result? Fast, deterministic, and easy to maintain. Want to change the certificate layout? Edit a React component. Want to add a new document type? Write a new component. The same mental model you use for UI applies to document generation. It’s honestly a great fit for this kind of work.

Database Resilience: Because Serverless Postgres Has Cold Starts

We run PostgreSQL on Neon’s serverless platform. It scales to zero when idle and handles cold starts gracefully. Most of the time. The entire platform runs on free tiers, by the way. Neon free, Vercel free. Zero hosting cost.

But “most of the time” isn’t good enough for a certificate management system. If an employer is verifying a credential at 3am and the database instance is cold, you can’t show them an error page.

So we built a retry wrapper with smart error classification:

This runs on every critical path. Certificate verification, PDF generation, dashboard stats, enrollment operations. The difference between a flaky app and a reliable one is often just a 15-line retry function with the right error classification.

TanStack DB: Reactive Data Without the Pain

The certificate requests table is the most interactive part of the app. Providers are approving, rejecting, generating PDFs, and filtering results constantly. Full page reloads would kill the workflow.

We used TanStack DB (an experimental reactive data layer) combined with TanStack Query v5 to create live collections:

const collection = createCertificateRequestsCollection(providerId)
const { data: requests } = useLiveQuery((q) => q.from({ req: collection }))

When a mutation completes, we invalidate the query key. TanStack Query refetches. The TanStack DB collection updates automatically. The table re-renders with fresh data.

No manual state management. No optimistic update logic. No stale data bugs. The same pattern powers the schools list, batches table, courses list, and enrollment views.

Multi-Tenant Security: Four Layers Deep

In a multi-tenant system, a data leak between tenants is catastrophic. A school seeing another school’s students. A provider accessing another provider’s data. We prevent this at four separate layers.

Edge Middleware. Every request to /providers/* and /schools/* checks for a session cookie. No cookie, no access. This runs on the edge with zero database hits.

Server Component Authorization. Every page validates that the session’s owner ID matches the URL parameter. Crafting a URL manually won’t get you into someone else’s dashboard.

Query Scoping. Every single database query filters by providerId or learningPartnerId. There’s no code path where one tenant’s data can reach another.

Session Context. The root layout fetches the session server-side and provides it via React context. Client components read it synchronously. No loading states, no race conditions, no client-side API calls to determine who you are.

Bulk Operations: Because Nobody Enrolls One Student at a Time

Schools enroll students in batches. Sometimes dozens at once.

CertifyMe supports CSV bulk upload with client-side parsing, header validation, auto-generated registration numbers, and per-row error reporting. If row 7 fails because of a duplicate email, rows 1 through 6 still succeed. You get a detailed report showing exactly what went wrong and where. No “something went wrong, try again” messages.

What This Means for You

If you run a training organization, a certification body, or any institution that issues credentials, here’s the value equation.

Before: Days per certificate. Zero verification. Spreadsheet chaos. Fraud risk. Manual everything.

After: 30 seconds per certificate. QR-verified. Centralized data. Multi-tenant access control. Three professional document types generated from React components.

The technology choices matter because they determine what’s possible. React PDF means you can iterate on certificate design as fast as you iterate on UI. Atomic batch operations mean your data stays consistent even under load. Serverless Postgres with retry logic means your verification pages work at 3am on a Sunday.

This isn’t about technology for technology’s sake. It’s about building systems that work the way your organization actually operates, and then making them reliable enough that you stop thinking about them.

Start a Conversation

We build platforms like this. If you have a manual process that’s holding your organization back, whether it’s certificate management, document generation, or something else entirely, start a conversation with us.

We’ll tell you honestly whether it’s worth building, and if it is, we’ll ship something that actually works.

elfmachines-ai

$ AI assistant coming soon...

In the meantime, start a conversation with our team.

> Type a message... _