Flagship case study
BioHubNet Training Platform · 2025

One platform for an entire biomanufacturing career.

Five products in one codebase — learning, hiring, funding, events, and a grounded AI career assistant that can't make things up. I designed and built it end to end.

Role
Full-stack engineering · Product design · DX
Year
2025 — ongoing
Stack
Next.js 16 · React 19 · Postgres / Prisma · Cloudflare AI
Scale
5 products · 9 roles · 8 languages
Scroll to see it work
The brief

One platform where a career in biomanufacturing actually happens.

Most organizations stitch together separate tools for training, hiring, funding, and events — none of which talk to each other. BioHubNet brings them together: a learner's whole journey and an employer's whole hiring process live in one connected system. The hard part wasn't any single feature — it was making five products feel like one, and making an AI assistant people could actually trust.

5
products in one codebase
169
data models, one database
0
facts the AI can fabricate
8
languages, incl. right-to-left
See it work

Three features, running.

Re-created here as live, animated mockups of the real product — the same flows, the same interface.

01 · The differentiator

AI Job-Tailoring, grounded in fact.

Paste a job posting. The assistant reads it, compares it to your recorded achievements, and rewrites your résumé to match — using only facts it can trace to your real record.

  • Gap analysis: what you have, partly have, and lack
  • Every number is fact-checked; unverifiable claims are blocked
  • A person always reviews — it never submits on its own
bhn‑training‑platform.app/tailor
linkedin.com/jobs/process-scientist-ii
Tailor
12 have 4 partial 2 gap
Scaled upstream process from 2 L to 200 L, lifting titer 38%.
Led tech-transfer of 3 cell lines into GMP manufacturing.
Cut batch deviations 21% with a new in-process control plan.
Fact-checked · 0 fabricated
02 · Learning

A path people actually finish.

Guided learning pathways with progress that's always visible, modules that check themselves off, and a certificate at the end — onboarding that explains itself on day one.

  • Multi-course pathways with cohorts and waitlists
  • SCORM courses, assessments, and issued certificates
  • Guided onboarding tours for every new flow
bhn‑training‑platform.app/learn/upstream-essentials
0%
Upstream Process Essentials
Pathway · 4 modules · cohort of 28
Cell culture fundamentals
12 min · quiz
Bioreactor operation
18 min · lab sim
In-process control
15 min · quiz
Scale-up & tech transfer
20 min · capstone
Certificate earned
Upstream Process Essentials · verified
03 · Hiring

A real hiring system, not a job board.

Employers move candidates through a full pipeline — applied, screen, interview, offer — with rubric scorecards, scheduling, and one source of truth shared with the rest of the platform.

  • Drag-through pipeline with activity audit
  • Interview scheduling + rubric scorecards
  • Funnel, time-to-fill, and cost-per-hire reporting
bhn‑training‑platform.app/employer/pipeline
Applied 7
RK
R. Khan
Process Sci II
JD
J. Diaz
QC Analyst
Screen 3
MO
M. Osei
Upstream
Interview 2
Offer 1
AL
A. Lindqvist
Process Scientist II
Offer sent to A. Lindqvist
Under the hood

The complete technical breakdown.

No summaries. This is the full engineering dossier — exactly how I'd walk a technical reviewer through what the platform is built on, layer by layer.

THE 30-SECOND PITCH

A suite, not a CRUD app.

“It's a full-stack Next.js 16 / React 19 app in TypeScript (strict), deployed serverless on Vercel, backed by PostgreSQL via Prisma with pgvector for semantic search. One codebase serves five products. The AI layer is the interesting part — dual-provider, behind a reliability wrapper that retries, validates structured output, and blocks fabrication, all gated by an offline eval suite that fails CI if quality regresses. Access control is enforced in the application with a 9-role model, MFA, and a documented 21 CFR Part 11 / GDPR posture.”

This brief was generated from a static read of the live codebase — versions, model IDs, and counts are cited from package.json, prisma/schema.prisma, and src/lib/**. Figures are “as of this build.”

ARCHITECTURE

One codebase, stateless edge, durable core.

A single Next.js App-Router codebase renders the UI (Server Components with selective client islands) and serves the API (route handlers). Everything is stateless and serverless; durable state lives in Postgres and Cloudflare, and AI work is isolated behind typed modules so it can fail safely.

Fig. 01Request & data flow
Browser RSC + client islands · i18n VERCEL · SERVERLESS Next.js 16 App Router Server Components · pages API route handlers lib/ai reliability wrapper Neon PostgreSQL Prisma 6 · pgvector(384) Cloudflare Workers AI · R2 · Turnstile Gemini 2.0 Flash AI fallback provider INTEGRATIONS SMTP Stripe Inngest Leaflet · OSM Mailchimp Twilio Jina Reader SCORM
Compute (Vercel) Database (Neon) Cloudflare AI fallback Reliability layer
01 — FRAMEWORK & RUNTIME

Next.js 16 App Router, fully typed.

Server-first rendering with React Server Components, selective "use client" islands for interactivity, and route handlers for the API — one TypeScript codebase, deployed to Vercel.

Fig. 02The stack, layer by layera request flows top → bottom; durable state at the base
EXTERNAL SERVICES Cloudflare Workers AI Cloudflare R2 storage Gemini (AI fallback) SMTP · Mailchimp Stripe · Twilio Inngest (durable agents) Jina Reader (URL → text) Turnstile (CAPTCHA) Leaflet · OpenStreetMap ClientReact 19 · Server Components + client islands · Tailwind 4 Next.js 16 · App RouterServer-rendered pages · API route handlers · middleware Domain libraries (typed)lib/ai · lib/tailoring · lib/resume · lib/auth · lib/matching · lib/scripts Prisma 6generated, fully-typed query client · Zod at every boundary PostgreSQL · Neonrelational tables + pgvector(384) embeddings
Framework
Next.js 16.2.4 · App Router (no Pages Router). Server Components by default; client components only where interactive.
UI runtime
React 19.2 + react-dom 19.2.
Language
TypeScript 5, strict, target ES2017. Build is type-checked + ESLint 9.
Styling
Tailwind CSS 4 with design tokens via CSS variables.
Validation
Zod 4 validates every API boundary and all AI structured output.
Build pipeline
prisma generate && prisma migrate deploy && next build — migrations are part of the deploy, so schema and code ship together.
Hardening
OWASP headers in next.config.ts: nosniff, SAMEORIGIN, Referrer-Policy, and a Permissions-Policy (camera off, mic self-only for voice interviews, geolocation off).
02 — DATA LAYER

Postgres + Prisma, with pgvector for AI.

A single relational source of truth on Neon Postgres, modeled with Prisma. The schema is large — it backs five products — and evolves through additive, never-destructive migrations. Five entities carry vector embeddings for semantic search.

Fig. 03169 models, six domains, one identity core
User identity · RBAC ENGAGE · learning Course ✦ · Pathway ✦ · Module ✦ · Enrollment EQUIP · grants EquipApplication · Deadline · HQP committee Outreach · CRM Contact · Campaign · Touch · EditableCopy EXPERIENCE · hiring / ATS Posting · Application · Interview · Offer Events BhnEvent · Workshop · Registration · Q&A Coaching · résumés Resume · MasterBullet ✦ · TailoringRun ✦ = pgvector(384) embedding · the Skill ontology is embedded too
Engine
PostgreSQL on Neon (serverless). Prisma uses a pooled URL for queries and a direct URL for migrations.
ORM
Prisma 6.19 — the schema is the source of truth; the typed client is generated at build.
Scale
169 models across six domains: hiring, learning, grants, events, outreach, and coaching/résumés.
Vector search
5 models store vector(384) embeddings for cosine similarity, written via raw SQL (Prisma can't type the vector column).
Grounding model
MasterBullet stores decomposed “career facts” (metric, mechanism, canonical phrasing, confidence, source) — so AI tailoring cites auditable facts, never invents them.
Migrations
~125 timestamped raw-SQL migrations, additive only — new tables and columns, legacy fields kept for fallback.
03 — AI / ML STACK the differentiator

Dual-provider AI behind a reliability layer.

The model is treated like any unreliable dependency: wrapped, retried, validated, measured, and gated by tests. Generation runs on open models with a frontier fallback, and anti-hallucination is structural — retrieve-only grounding plus a deterministic fabrication check, not a prompt.

Fig. 04Model routing — one wrapper, many models
Any feature — tutor · tailor · triage · translate · mock interview Reliability wrapper callText · callStructured retry · timeout · Zod validate never throws → {ok:false} AIInteraction telemetry provider · model · tokens · cost · latency · validation Chat · Llama-3.3-70B@cf/meta · Cloudflare Workers AI Gemini 2.0 Flashfallback Embeddings · BGE-small (384-d) → pgvector cosine retrieval Whisper · speech-to-text (mock interviews) SDXL-Lightning · images (thumbnails) m2m100 · translation (8 locales, cached)
Fig. 05Every call is fail-safe
repair-retry ×3 · backoff 250 → 500 → 1000 ms Request Call model ValidateZod schema return {ok:true, data} fail-safe → {ok:false, error}feature degrades · still logged
Fig. 06The job-tailoring pipeline — grounded, gated, never auto-submitted
1 Retrievepgvector facts 2 Gap analysisHave/Partial/Gap 3 Grounded draftfacts only 4 QA gatefabrication block 5 ScorecardStrong/Partial/Gap Human reviews never auto-submits
Chat / generation
Primary @cf/meta/llama-3.3-70b-instruct-fp8-fast; automatic fallback to gemini-2.0-flash on failure.
Embeddings
@cf/baai/bge-small-en-v1.5 (384-dim); pgvector cosine, lexical fallback if the embed call fails.
Reliability wrapper
callText / callStructured: retries with exponential backoff, per-call timeout, Zod validation with a one-shot repair-retry, prompt-version pinning. Never throws.
Telemetry
Every call logged to AIInteraction: provider, model, tokens, computed cost, latency, validation result, confidence. Dashboard aggregates p50/p95 latency, error rate, per-feature cost.
Fabrication check
A pure function extracts every number in the draft and requires each to appear in a grounded fact; unverified numbers block the output. No AI judging AI.
Autonomous agent
A triage agent (Inngest, every 6h) classifies flagged answers and proposes actions — it never resolves on its own; a human acts in the review queue. Kill-switch defaults off.
Eval gate
An offline eval suite (recall@3, precision@3, MRR, groundedness) fails the PR if any metric drops >0.05 vs baseline. Same prompts run in evals and production.
04 — AUTH & SECURITY

RBAC, MFA, and a documented compliance posture.

Authentication is NextAuth with credentials, passwordless email codes, and optional TOTP. Authorization is enforced in application code, not database RLS. Because the audience is regulated, the platform documents a 21 CFR Part 11 / GDPR / PIPEDA / CASL posture.

Fig. 079 roles, 4 rank tiers
superadmin · rank 3 admin · rank 2 staff — instructor · EQUIP reviewer · HQP advisor · rank 1 learners — trainee · evaluating · employer · hr · industrial mentor · rank 0
Auth
NextAuth 4.24 + Prisma adapter, JWT sessions. Credentials and passwordless 6-digit email codes (bcrypt-hashed, single-use).
MFA
Opt-in TOTP (authenticator-app compatible), verified at sign-in.
Authorization
Application-layer row scoping — every query filters by owner/role; admins bypass for moderation. No Postgres RLS (a deliberate, documented trade-off).
Account protection
Brute-force lockout (5 fails → 30-min freeze, audit-logged); password policy rejects breached and self-referential passwords; bcrypt cost 12.
Bot / abuse
Cloudflare Turnstile on signup. Email verification is idempotent, so corporate “Safe Links” scanners can't burn the token before the user clicks.
Compliance
Aligned to 21 CFR Part 11 (audit trails, e-signatures), GDPR (right-to-access export), CASL (double-opt-in), PIPEDA / Quebec Law 25 — with version-controlled policy docs surfaced live to admins.
05 — PRODUCT SURFACE

Five products in one codebase.

Breadth is the headline. Each area has its own data model, admin surface, and user journey — unified by one auth, AI, and internationalization core.

Learning (LMS)
SCORM 1.2/2004 courses, modules, assessments, certificates, and multi-course Pathways with cohorts, waitlists, and progress tracking.
Employer hiring / ATS
Postings, applicant pipeline, interview scheduling + rubric scorecards, offers, team roles, activity audit, and reporting (funnel, time-to-fill, cost-per-hire, DEI).
EQUIP funding
Commercialization grants — VentureConnect (≤$5K) and VentureLift (≤$25K) — with deadline windows, threaded review, and a committee workflow.
Events engine
Symposium + workshops: bookable slots, guest (no-login) registration, capacity/waitlist, Stripe ticketing, live Q&A and polls.
AI Job Tailor + Bullet Bank
Paste a job URL → ATS detection → gap analysis → grounded résumé/cover → QA gate → per-ATS exports, backed by a reusable accomplishment library.
Collaborative video scripts
A shadow-DOM contentEditable editor with anchored comments, revision history with one-click revert, and no-login share links with live presence.
Simulator + mock interview
A 12-week career role-play and a voice-or-text mock interview with per-answer scoring.
Matching & mentorship
A skill-ontology matching engine (embeddings + weighted subscores), an approved talent directory, learning-buddy pairs, and mentor résumé review.

Plus a facilities map (Leaflet / OpenStreetMap), a credits system, an outreach CRM, a lightweight CMS, and an admin analytics suite — across eight UI locales including Arabic (RTL).

06 — INFRASTRUCTURE

Serverless core, first-party services.

The stack favors managed, cost-efficient services and degrades gracefully when an integration is unconfigured — so preview and dev deploys work without secrets.

Compute / DB
Vercel serverless + Neon Postgres (pooled). Playwright E2E runs against preview deploys.
Storage
Cloudflare R2 via the S3 SDK — SCORM packages, certificates, uploads.
Email / SMS
Nodemailer over SMTP, optional Twilio SMS, Mailchimp double-opt-in for newsletter.
Payments
Stripe for event ticketing — on-the-fly products/prices, webhook-verified, free path if unconfigured.
Agents / jobs
Inngest for durable, retried, concurrency-controlled background work — the AI triage agent runs on a 6-hour cron.
Content extraction
Jina Reader turns a posting URL into clean text; résumé parsing via unpdf + mammoth; generation via docx + jsPDF.
07 — ENGINEERING PRACTICES

Shipping safely, fast.

The codebase is built to change continuously without regressions: typed end-to-end, gated by three kinds of CI, with versioned prompts and a fail-safe AI philosophy.

Fig. 08Three gates stand between a PR and production
Pull Request ① Eval regressionfails if AI quality drops ② CodeQL (security)IDOR · SSRF · broken auth ③ Playwright E2Eone project per role · vs preview Merge→ main Vercel buildmigrate deploy+ next build Prod
CI gates (×3)
Eval regression (fails if AI metrics drop), CodeQL security-extended, and Playwright E2E per-PR against the Vercel preview.
Migrations
Additive-only raw SQL with design-rationale comments. No destructive forward migrations.
Prompt management
Prompts are versioned in one module and imported by both runtime and evals, so tests exercise exactly what ships.
Fail-safe AI
Core rule: AI failures return structured errors, never throw — feature code degrades gracefully, and the failure is logged.
Release hygiene
In-app changelog stamped with the deploy commit SHA; versioned “what's new” tours; a per-user feature-preference registry.

Companion piece

The parts that don’t screenshot.

This dossier covers how the platform is built. The design work it can’t show — the end-to-end flows, the permission models, and what the product does when things go wrong — is documented separately.

EQUIP grant relay
Six steps across four actor types — two of whom never hold an account — each with its own designed failure state: edge, gate, auth, undo, drift, revoke. See the flow →
System maps
Five products resolving onto one identity, design-system and data spine — plus the deadline reconciler: source → derive → reconcile → enforce. See the maps →
Permission models
Three real models — the role ladder (requireRole), committee membership (requireCommitteeOrAdmin) and capability tokens (/share/<token>) — with the access matrix and the fail-closed rule. See the models →
Recovery states
Six states mocked in-app: tiered confirm, revert-don’t-lie, blank-merge-field guard, disabled-with-reason, expired vs revoked, and a composed empty state. See the states →
BHN Training Platform — engineering dossier. Next.js 16 · React 19 · TypeScript · PostgreSQL / Prisma · Cloudflare Workers AI · Vercel.

Generated from a static read of the codebase. Figures are “as of this build”; confirm exact versions in package.json before quoting them verbatim.

In one line

BHN replaces a stack of disconnected tools with one platform — and the AI assistant inside it is one you can actually trust.