Skip to content

Perfxcel Architecture

System Overview

Perfxcel consists of three services: a public React SPA, an internal admin React SPA, and a shared Express REST API backed by Supabase PostgreSQL.

graph TB
    subgraph Public
        PX[perfxcel.com\nReact 19 / Cloudflare Pages]
    end

    subgraph Admin
        PA[admin.perfxcel.com\nReact 19 / Cloudflare Pages]
    end

    subgraph API
        PXAPI[api.perfxcel.com\nNode.js / Express 5]
        SB[(Supabase PostgreSQL\nperfxcel schema)]
        AUTH[Supabase Auth\nJWT validation]
    end

    PX -->|GET /courses, POST /interests| PXAPI
    PA -->|Bearer JWT — all admin routes| PXAPI
    PXAPI -->|requireAuth + requirePerfxcelTenant| AUTH
    PXAPI -->|supabase client (service role)| SB

Request Flow — Public Learner

Public routes on perfxcel-api require no authentication. The public site calls the API directly.

sequenceDiagram
    participant L as Learner (perfxcel.com)
    participant API as api.perfxcel.com
    participant CF as Cloudflare Turnstile
    participant SB as Supabase PostgreSQL

    L->>API: GET /api/v1/courses
    API->>SB: SELECT * FROM courses WHERE is_published=true AND status='active'
    SB-->>API: Course list
    API-->>L: 200 OK

    L->>CF: Turnstile widget challenge
    CF-->>L: token
    L->>API: POST /api/v1/courses/:id/interest { turnstileToken, ... }
    API->>CF: POST /siteverify (token verification)
    CF-->>API: { success: true }
    API->>SB: INSERT INTO interests (...)
    SB-->>API: Interest created
    API-->>L: 201 Created

Request Flow — Admin Operation

Admin routes require a valid Supabase JWT from the perfxcel tenant.

sequenceDiagram
    participant A as admin.perfxcel.com
    participant API as api.perfxcel.com
    participant SB_AUTH as Supabase Auth
    participant SB_DB as Supabase PostgreSQL

    A->>API: POST /api/v1/courses (Bearer JWT)
    API->>SB_AUTH: supabase.auth.getUser(token)
    SB_AUTH-->>API: { user }
    API->>API: requirePerfxcelTenant — verify user is perfxcel tenant member
    API->>SB_DB: INSERT INTO courses (...)
    SB_DB-->>API: Course created
    API-->>A: 201 Created

Service Responsibilities

perfxcel-app (Public SPA)

  • Course catalog with taxonomy-based filtering (category, city, association, delivery mode)
  • Course detail pages with interest registration form (Cloudflare Turnstile)
  • Certificate verification (/verify)
  • Training plan request form
  • Contact form with Turnstile

perfxcel-admin (Internal Admin SPA)

  • Course management — create, edit, publish, bulk-manage
  • Taxonomy management — categories, cities, associations, delivery modes
  • Interest management — view and convert to enrollments
  • Enrollment management — status tracking
  • Training plan requests — review and act on bulk requests
  • Enquiry management — update status
  • Audit logs — paginated, filterable action log
  • Dashboard — real-time platform metrics (courses, interests, enrollments)

perfxcel-api (REST API)

  • Single Express 5 app, all routes under /api/v1/
  • Two authentication tiers:
  • Public — no auth, rate-limited by globalLimiter
  • Admin — requireAuth + requirePerfxcelTenant middleware chain
  • Cloudflare Turnstile server-side verification on interest/contact submissions
  • Sentry error tracking via @dotevolve/error-utils

API Route Map

Method Path Auth Description
GET /api/v1/courses Public List published active courses
POST /api/v1/courses Admin Create a course
PATCH /api/v1/courses/bulk Admin Bulk update course status/visibility
GET /api/v1/courses/:id Public Get a single course
PUT /api/v1/courses/:id Admin Update a course
DELETE /api/v1/courses/:id Admin Soft-delete a course
POST /api/v1/courses/:id/interest Public Register learner interest
GET /api/v1/taxonomies Public List all taxonomy items
POST /api/v1/taxonomies Admin Create a taxonomy item
PUT /api/v1/taxonomies/:id Admin Update a taxonomy item
DELETE /api/v1/taxonomies/:id Admin Delete a taxonomy item
GET /api/v1/interests Admin List interest submissions
PATCH /api/v1/interests/:id Admin Update interest status
GET /api/v1/enrollments Admin List enrollments
POST /api/v1/enrollments Admin Create enrollment
PATCH /api/v1/enrollments/:id Admin Update enrollment status
GET /api/v1/enquiries Admin List enquiries
PATCH /api/v1/enquiries/:id Admin Update enquiry status
POST /api/v1/contact Public Submit contact form (Turnstile)
GET /api/v1/verify Public Verify a certificate number
GET /api/v1/metrics Admin Platform metrics (dashboard)
GET /api/v1/audit-logs Admin Paginated audit log
GET /api/v1/training-plan Admin List training plan requests
POST /api/v1/training-plan Public Submit training plan request

Technology Stack

Concern Choice
API runtime Node.js 24 / Express 5 / TypeScript 5.9
Database Supabase PostgreSQL (perfxcel schema)
Auth Supabase Auth (service role key on API)
Bot protection Cloudflare Turnstile
Error tracking @dotevolve/error-utils (Sentry)
Frontend build Vite 8 / React 19 / Tailwind CSS 4
Deployment Cloudflare Pages (frontends), OCI (API)
Testing Vitest 4 (frontends), Jest 30 (API)