Skip to content
← Back to portfolio

Project case study · Web system

Capply

A B2B logistics marketplace connecting shippers and carriers through quotes, waybills, and bookings, backed by a thorough automated test suite.

RemixReactTypeScriptPrismaKafkaAuth0Fly.ioPlaywright
Capply

The challenge

Capply is a B2B logistics marketplace that connects shippers with carriers. It covers freight quotes, waybills, and bookings in a domain with real regulatory and financial stakes. Over roughly 17 months, from 2021 to 2023, the platform grew from an early-stage product into a system with a 27-model Prisma schema and around 226 TSX files. Throughout that growth, it had to remain reliable enough for freight operations that cannot tolerate silent failures.

What we built

We built the platform with Remix and React 18, using Prisma to model shippers, carriers, quotes, bookings, waybills, and the rest of the logistics domain. Auth0 handles authentication. HubSpot provides the CRM integration, while MailerSend delivers transactional email.

Postgres row changes pass through a Debezium CDC pipeline into Kafka, hosted on Aiven. A dedicated Fly.io process consumes those events and keeps HubSpot synchronized with organizations, users, memberships, and shipments. wkhtmltopdf generates waybill PDFs, and Sentry tracks errors in both the web and consumer processes.

Capply shipments list showing draft, active, and delivered freight shipments with loading and delivery locations
Capply requested loads view showing carrier quote requests awaiting response
Capply shipment detail showing schedule, actual weight, and volumetric weight while awaiting carrier quotes
Capply shipment details tab showing full route with loading and delivery addresses and dates

Key features

Quote-to-booking workflow

Shippers request quotes, carriers respond, and accepted quotes become bookings. The 27-model Prisma domain tracks each step in the shipment lifecycle.

Waybill generation

Waybill documents are rendered server-side to PDF using wkhtmltopdf, producing the paperwork carriers and shippers need for each booking.

CDC-driven HubSpot sync

Rather than calling HubSpot inline from request handlers, Capply captures Postgres changes via Debezium CDC and streams them through a Kafka pipeline to a separate consumer process, which pushes organization, user, membership, and shipment updates into HubSpot. Failed messages are retried and, after repeated failure, routed to a dead-letter topic rather than silently dropped. MailerSend delivers transactional email for quotes, bookings, and status changes, with Mailgun kept in the codebase as a fallback driver from an earlier provider migration.

Test pyramid enforced in CI

Capply’s CI pipeline runs Vitest unit tests, Playwright acceptance tests for the full quote-to-booking flow, and Storybook with Chromatic for visual regression. Each suite is a separate required job before code reaches staging or production.

Architecture

Capply architecture: a Remix app on Fly.io backed by PostgreSQL and Prisma emits domain events to Kafka on Aiven; a separate consumer service syncs records into HubSpot CRM with dead-letter-queue retries.
A Remix app on Postgres, emitting domain events through Kafka to a consumer that syncs a CRM.

Frontend: Remix with React 18 provides server-rendered routes and nested data loading for a workflow-heavy B2B app.

Data layer: Prisma models the 27-entity logistics domain in a relational database. Debezium CDC captures row-level changes and streams them through Kafka, hosted on Aiven, to a dedicated HubSpot sync consumer. Failed messages are retried before being sent to a dead-letter queue.

Authentication and integrations: Auth0 handles authentication. HubSpot and MailerSend cover CRM and transactional email.

Infrastructure: The system runs on Fly.io as separate web and consumer processes. wkhtmltopdf generates waybill PDFs server-side, and Sentry captures errors in both processes.

Testing: Vitest runs the unit tests, Playwright handles acceptance testing, and Storybook with Chromatic covers visual regression. CI requires all three jobs.

Capply predates my React Native and Cloudflare work, so neither appears in this project. The 27-model relational domain, event-driven integration pipeline with retry and DLQ handling, and CI-enforced test pyramid show the server-side engineering behind freight operations that cannot fail silently.

Have a project in mind?

Tell me what you're working on and where you need help.