Back to Case Studies

Five surfaces for a trading-education platform

Courses, third-party bot subscriptions, broker affiliate tracking and gated channels behind one API, delivered across five surfaces including a headless CMS.

Sector
Trading-education platform
Engagement
July 2025 – March 2026
  • Node
  • Express
  • MongoDB
  • Next.js
  • React
  • Flutter
  • Strapi

Context

The education half of this platform is the ordinary half: courses, chapters, sessions, progress. What made it awkward is that the same account also carries subscriptions to third-party trading bots, an affiliate relationship with a broker, and access to paid private channels — four unrelated entitlements hanging off one user record, with money leaving through withdrawals as well as arriving through payments. Five surfaces then have to agree, at any moment, on what a given account is entitled to.

What we built

  • Backend API

    REST API owning accounts, entitlements, payments and withdrawals.

  • Web app

    Separate route groups for learners, affiliates and administrators.

  • Admin panel

    Content, account and subscription administration.

  • Mobile app

    Learner app on Android and iOS, with video lessons and in-app browsing.

  • Headless CMS

    Marketing content edited without a deploy.

Architecture

One Express and MongoDB API — 29 route modules, 29 controllers and 31 data models — sits behind everything. The web app and the admin panel are both Next.js; the mobile app is Flutter with GetX and an HTTP interceptor handling token refresh; a Strapi instance holds marketing content. That last split is the decision worth naming: the platform API is REST and owns identity, entitlements and money, the CMS is GraphQL and owns copy, and the web app reads from both, so blog posts and banners change without a deploy and without touching the system that moves money. Payments run through Stripe, course media through S3 with presigned uploads, and documents are rendered server-side with a headless browser. The admin panel began from a generated scaffold rather than a hand-built one.

Stack

Backend API
  • Node
  • Express
  • MongoDB
Web app
  • Next.js 16
  • React 19
  • Tailwind CSS 4
Admin panel
  • Next.js 16
  • React 18
  • generated scaffold
Mobile app
  • Flutter (Dart)
  • GetX
Headless CMS
  • Strapi 5
  • read over GraphQL
Integrations
  • Stripe for subscription and one-off payments
  • Amazon S3 with presigned uploads for course media
  • Strapi as a headless CMS, read from the web app over GraphQL
  • Firebase on the web client
  • Socket.IO for real-time updates
  • A headless browser for server-side document rendering

Scale

Counts that can be re-derived from the same repositories. Nothing here is a business result — a repository cannot evidence one.

  • Five delivered surfaces: backend API, web app, admin panel, mobile app, headless CMS.
  • 385 commits across the five repositories.
  • 29 route modules, 29 controllers and 31 data models in the API.
  • 42 mobile dependencies, on Dart SDK ^3.6.0.
  • The headless CMS is Strapi 5.

Where the evidence stops

  • How any of it is priced, ranked or executed is the client's competitive edge and is not described here.
  • The admin panel began from a generated scaffold rather than a hand-built one.
  • The repositories prove five surfaces were built, not that anyone subscribed.

Evidence

Each statement above, and the artefact it was read from. The client cannot be named, so the sources are given instead.

  • 5 surfaces delivered — backend API, web app, admin panel, mobile app, headless CMS.

    SourceOne repository per surface, each carrying application code (the admin panel's on its master branch)

  • 385 commits across the five repositories.

    SourceSum of history.totalCount on each repository's default branch (GitHub GraphQL)

  • The API carries 29 route modules, 29 controllers and 31 data models.

    Sourceroutes/, controllers/ and models/ directory listings on the backend repository

  • 42 mobile dependencies, on Dart SDK ^3.6.0.

    Sourcepubspec.yaml on the mobile repository

  • The headless CMS is Strapi 5.

    Sourcepackage.json on the CMS repository (@strapi/strapi ^5.23.0)

  • Engagement span: 30 July 2025 to 27 March 2026.

    SourceFirst and last commit dates on the default branches

Related capability

Fintech software development