Full-page reloads
Every state change triggered a complete page reload, creating a fragmented experience during high-stakes exam flows.

Canonical Academy is the official certification platform for Ubuntu and Linux professionals. Engineers worldwide use it to purchase exams, schedule them under live proctored conditions, and earn globally recognised Credly badges upon passing.
This was built in-house as part of the Canonical engineering team — not as a client engagement. The platform handles the full certification lifecycle, from payment processing to identity verification to exam delivery to credential issuance.
Every state change triggered a complete page reload, creating a fragmented experience during high-stakes exam flows.
Jinja templates bound the frontend to the backend. UI changes required backend knowledge and were expensive to test.
New team members had to understand the entire Flask monolith before contributing to either layer.
External vendor APIs were embedded in the monolith, making them brittle and difficult to maintain independently.
The rebuild introduced a three-layer architecture — each layer with a clear, bounded responsibility.
The Go backend owns all business-critical infrastructure. The Node BFF handles all external API orchestration. The React frontend owns the user experience entirely.
Keeping the BFF separate from the Go backend meant external vendor changes — Proctor360 API updates, Credly webhook changes — never touched core business logic.
User experience · SPA · State management
External orchestration · Session management
Payments · Exam catalogue · Student records
01 · Layer
Payments, exam creation, student management, banning and compliance. Source of truth for all business logic.
02 · Layer
Proctor360 session creation, webhook handling, Credly badge issuance. All external API contracts live here.
03 · Layer
Migrated from Jinja templates. Client-side state management, no full-page reloads, clean component architecture.
Certification exams require verified identity and a monitored environment. The platform integrates Proctor360 to handle this entirely via API.
The check-in flow is webhook-driven by design — rather than polling P360 for status, the BFF listens for P360's confirmation event. This keeps the exam flow responsive and eliminates unnecessary API calls during a time-sensitive user journey.
User schedules exam
BFF creates session with Proctor360
P360 emails user for environment check-in
User completes check-in on P360's platform
ID verified, environment scanned for flags
P360 fires webhook → BFF confirms check-in
Exam window opens → user takes exam
Pass → Credly badge issued automatically

Exam dashboard showing attempt status and scheduling actions.

Step 01 — Purchase
Select and purchase an exam from the catalogue.

Step 02 — Schedule
Choose country, timezone, date and time slot.

Step 03 — Confirmed
Everything is ready. Reminders sent automatically.
The Go backend owns the entire payment lifecycle — exam pricing, order creation, VAT calculation, and transaction records. The checkout experience is a full two-step flow: billing address collection followed by card payment with live order summary.
Payment processing is handled via Stripe integration within the Go layer, keeping financial data entirely separate from the BFF and frontend.

10,000+
Exams conducted
on the platform
Faster
onboarding
New engineers contribute to both layers independently
Eliminated
Jinja coupling
React migration decoupled UI from backend
Resilient
integrations
Proctor360 and Credly isolated in the BFF