An electrical protection company that needed more than a brochure
Protesa is an electrical protection and technology company in Costa Rica. The engagement started as a corporate website — services, company story, and a product catalog backed by a Strapi CMS with filtering, search, and pagination.
It didn't stay a website. As trust built, the scope grew: first a full brand redesign, then an entire private learning platform for training on electrical protection — designed, built, and shipped inside the same codebase.
From generic to industrial-tech
The original site read as template-built: lime gradients, glassmorphism cards, floating particles — and structural problems underneath. No real font ever loaded, the brand green didn't match the logo, and the HTML declared English on a fully Spanish site.
The redesign rebuilt the foundation as a design system: CSS design tokens, the true logo green (#588e19) with its yellow bolt accent as precise solids instead of gradients, Space Grotesk and Inter loaded via next/font, a “power-on” loading animation, and motion only where it adds meaning. Clean industrial-tech — the way a B2B engineering company should feel.
A private learning platform inside the site
Protesa Academy is an invite-only, Udemy-style LMS living at /academia. Instructors publish video courses and configurable tests, students take randomly assembled evaluations and track their grades, and a super-admin manages accounts and platform settings. All UI in Spanish, shipped only when complete.
Video courses & lessons
Instructors publish courses of video classes through a two-pane editor — content on the left, settings on the right — with readiness badges showing what a course still needs before publishing.
Randomized evaluations
Each course has a shared question bank. Every attempt assembles a fresh random test with configurable question counts, time limits, and retry rules.
Three portals, invite-only
Admin, instructor, and student portals in one app. Public signup is disabled — accounts exist only through email invites with password setup.
Grades & attempt history
Students review their own grades and past attempts; instructors and admins get per-course results dashboards.
One frontend, two backends
The Academy runs on Supabase — Auth, Postgres with Row Level Security, and Storage — while the product catalog stayed on the existing Strapi CMS. Pages are guarded server-side, and Next.js API routes holding the service-role key exist only for admin operations, always gated on the caller's role.
Four decisions worth talking about
The LMS security model was the interesting problem. These were the decisions that mattered.
Students must never see correct answers, other students’ data, or bypass timers and retry limits. That is enforced in Postgres — RLS policies plus SECURITY DEFINER functions — not in untrusted browser code.
Supabase public signup is disabled entirely. Roles are read exclusively from server-controlled app_metadata, so a public caller can never choose their own role.
Tests are assembled at attempt time by a Postgres RPC that draws from the per-course question bank — each attempt gets a different test, with per-test question counts set by the instructor.
The product catalog stayed on the existing Strapi CMS while the Academy was built on Supabase alongside it. Each system owns its domain; nothing was rewritten.
Shipped through real UAT cycles
The Academy was delivered iteratively against real client feedback — multiple UAT fix batches, instructor-authoring UX revisions, and auth-flow hardening — and is live in production for a real company, alongside the redesigned site and catalog.