[01]  Shipment Tracking SaaS

TrackBison

A production SaaS platform built for a real client, combining shipment discovery, authenticated accounts, usage-based credits, payment infrastructure and a live third-party tracking provider.

Full-stack development, product implementation, database architecture, API integration, billing, localisation, testing and deployment.

[Scroll to explore]

SaaS ProductFull-Stack DevelopmentAPI & Billing

Category

Shipment Tracking SaaS

Status

Live Client Product

Stack

Next.jsReactTypeScriptSupabasePostgreSQLVercelGetTNShip APICopeCart

Project index

01

Role — Full-stack development, product implementation, database architecture, API integration, billing, localisation, testing and deployment.

[01]

Problem

TrackBison needed to turn an external shipment-tracking service into a complete customer-facing SaaS product. That meant more than displaying tracking results — the platform needed authenticated users, controlled usage, purchased credits, billing state, reliable third-party API communication, and a product experience that could operate independently of the underlying tracking provider.

[02]

Solution

Built as a full-stack layer around the shipment-tracking workflow: users create an account, receive trial credits, search for shipment candidates against the live tracking provider, and spend credits through the application.

Account state, credit balances, transactions, purchases and access rules are persisted through PostgreSQL and Supabase rather than held in client state, so what an account is allowed to do is decided by the database and not by the interface.

Payment and membership events from CopeCart are connected to the platform, so purchased access is reflected in the user's account automatically rather than granted by hand.

[03]

What I built

Product

  • Authentication and email confirmation
  • Account onboarding
  • Authenticated dashboard
  • Shipment candidate search
  • Search history and transaction history
  • Credit balance and usage states
  • Billing and membership interfaces
  • Responsive desktop and mobile UI
  • Light and dark theme infrastructure
  • Multilingual interface with right-to-left support

Backend & data

  • Supabase authentication
  • PostgreSQL-backed account data
  • Credit transaction ledger
  • Free-trial credit provisioning
  • Non-expiring purchased credits
  • Membership-access architecture
  • Database migrations and production schema updates
  • Server-side validation around credit-sensitive operations

Integrations

  • GetTNShip shipment-search provider
  • Live candidate retrieval
  • Provider parity checks
  • CopeCart payment and webhook integration
  • Automated purchase and account-state updates

Engineering

  • Vercel production deployment
  • Environment configuration
  • TypeScript validation and ESLint
  • Automated regression testing
  • Internationalisation infrastructure with right-to-left layout handling
  • Persistent theme system

[ Live experience ]

Try the product.

Explore the live TrackBison experience without leaving the case study.

Open full site
trackbison.comLive / Production

Tap to interact · scroll outside to continue

Open TrackBison to login
[04]

Architecture

The authenticated application controls customer-facing product state. GetTNShip provides the shipment data and CopeCart's payment events update access and credit state — so neither external service holds the product's own record of what an account may do.

  1. Frontend

    Next.js + React + TypeScript

    Public surface and authenticated product screens, rendered per locale.

  2. Authentication

    Supabase Auth

    Account identity and email confirmation form the boundary around every credit-sensitive action.

  3. Application

    Search · Credits · History · Billing

    Customer-facing product state: candidate search, credit balance and usage, search and transaction history, membership access.

  4. Database

    PostgreSQL / Supabase

    Accounts, credit transactions, purchases and access rules persist relationally rather than in browser state.

  5. Tracking provider

    GetTNShip API

    Supplies live shipment candidates; TrackBison owns the product experience built around them.

  6. Payments

    CopeCart webhooks

    Purchase and membership events update account access and credit state.

[05]

Backend & data architecture

Supabase is the backend foundation: authentication, relational PostgreSQL data, account state, search history, candidate unlocks, lifecycle events and acquisition attribution.

The database is treated as a security and product boundary rather than as storage. What an account may do is decided by the schema and its policies, so an answer the interface gets wrong cannot become an answer the product acts on.

TrackBison Supabase relational database schema showing profiles, memberships, shipment search history, candidate unlocks and lifecycle events
Relational Supabase / PostgreSQL schema used by TrackBison

Database evolution

Every schema and business-rule change exists as a numbered SQL migration in the repository rather than as an untracked edit to the live database — fourteen of them, from the initial schema through to payment orders.

Trial credits
Two credits are granted at signup by the same trigger that creates the profile, so a new account can search before it has paid for anything.
Candidate unlocks
A masked candidate is unlocked through a TrackBison-owned opaque reference. The provider's own identifier is resolved server-side and is never selectable by the browser.
Purchased credits
Purchased and trial credits follow different lifecycles: trial credits expire, purchased credits do not.
Lifecycle events
Only the events nothing else can prove are written down. The rest stay derivable from the credit ledger rather than being stored a second time, where the two copies could disagree.
Acquisition attribution
UTM and referrer data is stored against the authenticated profile by an independent trigger, so attribution failing cannot take a signup down with it.
TrackBison Supabase SQL migration history for payments, credits, lifecycle events, acquisition tracking and search history
Migration history, init through payment orders
[06]

Technical challenges

Keeping credit usage reliable

Problem

Credits represent paid product usage, so the frontend cannot be the authority on whether an account has enough balance to perform an action.

Cause

A balance held in browser state is client-owned — it can be edited, replayed, or simply out of date by the time a credit-consuming request lands.

Fix

Credit state is persisted in the database and expressed as transactions rather than as a single mutable balance, with server-side validation around the operations that spend credits.

Why this fix

A ledger makes every grant and consumption traceable, which is what free-trial provisioning and non-expiring purchased credits both need. A disputed balance can be reconciled against a list of transactions; it cannot be reconciled against one number.

Matching the upstream tracking provider

Problem

TrackBison sits between its users and an external tracking service, so any divergence between its results and the provider's own could surface an incorrect shipment match.

Cause

Candidate search is the provider's behaviour rather than TrackBison's, so the two sides can drift apart without either looking obviously wrong on its own.

Fix

The integration was tested directly against the provider, and candidate-search behaviour was adjusted to hold parity between TrackBison and the upstream service.

Why this fix

Parity with the provider is the bar a tracking product is actually judged against — a result that looks plausible but disagrees with the carrier's own answer is worse than no result.

Supporting multiple languages and RTL layouts

Problem

Internationalisation affects more than translated text. Right-to-left languages change navigation direction, alignment, page flow and the meaning of directional controls.

Cause

Direction is a document-level property, so handling it component by component leaves part of the interface mirrored and part of it not.

Fix

Locale-aware server rendering, a persisted locale selection, and direction handled at the application level, so the whole interface changes with the selected language.

Why this fix

Setting direction once at the top means a new screen inherits correct RTL behaviour by default, rather than every new component being a fresh chance to get it wrong.

[07]

Technical implementation

TrackBison was built as a client product rather than a portfolio demonstration, so the work included the parts that only start to matter once real accounts exist: schema changes shipped as migrations against a production database, environment configuration per deployment, and access that has to stay correct when a payment event arrives out of band.

Credit-sensitive operations are validated server-side rather than guarded in the interface, and trial credits, purchased credits and membership access are separate concerns in the data model rather than one flag.

The interface carries its own state across sessions — selected theme and selected locale both persist — and desktop and mobile are built as responsive layouts rather than one layout scaled down.

TypeScript validation, ESLint and automated regression tests run over the application, which is deployed to production on Vercel.

[08]

Outcome

TrackBison is a live production SaaS application, used as the customer-facing layer around a real shipment-tracking workflow. I worked across the full application stack: frontend product experience, authentication, PostgreSQL architecture, credit and billing logic, external API integration, localisation, testing and production deployment.