Skip to content
All work
Live in production
Multi-vertical marketplace
2026

Abaqwa

Six booking verticals, one platform

A Cameroon-first super-app putting hotels, ride-hailing, parcel delivery, intercity bus, car rental and errands into one customer app — with a driver app, hotel-staff app and a large admin console behind them.

Role

Lead developer

Client

Private client · Cameroon

Status

Live in production

Year

2026

1,276

Python tests

874

API endpoints

3

Flutter apps

186

DB tables

404k

Lines of code

6

Verticals

The hardest problem

Keeping six unrelated booking verticals on one schema without either duplicating the platform six times or collapsing them into an unusable generic abstraction. A hotel booking, a taxi ride, a parcel, a bus seat, a rental and an errand have different pricing inputs, state machines, cancellation rules and parties.

What I did about it

01

Each vertical got its own tables and its own state machine — bookings, rides, parcel_shipments, bus_bookings, car_rental_bookings, errand_tasks — each first-class, each with its own pricing rules.

02

Unification happens only where the business genuinely is unified: transactions, wallets, commission_rules, users, notifications and support_tickets are shared across all six.

03

A global_bookings projection sits over the six for the admin console's cross-vertical views, so the UI never needs a switch statement per column.

04

Domain-package organisation reinforces the boundary — the code layout makes it obvious when someone is about to reach across a vertical they shouldn't.

What I rejected, and why

The cost is real: 186 tables, and adding a seventh vertical is genuine work rather than a config row. The generic type column plus JSON blob alternative has been tried repeatedly in the industry and produces a system where 'why did this booking charge the wrong commission' is unanswerable. Here commission logic lives in one shared place with per-vertical overrides, pinned by a test.

What I’d change

The coverage gate sits at 50% across a 186-table schema. That number is honest but low for a system moving commission payments, and I would raise the gate on the money and commission modules specifically rather than averaging across six verticals.

Built with

FastAPISQLAlchemy 2 asyncPostgreSQLRedisNext.js 16MapLibre GLFlutterRiverpodsystemdGitHub Actions

Next case study

QuataFood

Food delivery, three apps, one backend