← All projects
Case study · Marketplace · Client work · Web

A trilingual car marketplace for Algeria: rentals, sales and wedding cortèges, with a subscription engine the database enforces.

Biggo lets rental agencies, private sellers and showrooms list cars for rent or sale, lets buyers reach them in one tap, and gives the client's team an admin console with packages, feature flags, granular permissions and an audit trail. Built solo as billed agency work through Barmjli.
RoleFull-stack developer, database design, admin tooling
TimelineJune → August 2026, in production
PlatformResponsive web app, French, Arabic and English
StackReact 18, TypeScript, Vite, Supabase Postgres with RLS
www.biggoway.com/
Biggo home page
3
languages, RTL included
48
routes, 18 tables, 19 migrations
5
roles plus 10 admin permission keys
0
custom servers: Postgres is the backend

Overview.

Who it is for, what was broken, what shipped.
The client

An Algerian automotive marketplace

A client of the Barmjli agency building a national platform for car rental, car sales and wedding cortèges, selling visibility packages to agencies and showrooms across 48 wilayas.

The problem

Fleets sit idle, and the market runs on Facebook

Rental agencies and dealers list on social media with no search, no verification and no way to pay for placement. Buyers call around. Nobody can tell a verified agency from a scammer.

The product

A marketplace with paid placement the client can operate alone

Public search across rentals, sales and cortèges, three supplier account types with dashboards, and an admin panel where staff sell packages, toggle perks, verify documents and see every change in an audit log.

Walkthrough.

Desktop captures from the live site, page by page.
01 · Home

Rent, buy or sell from one search box

The home page has to serve three intents at once. A single search with a rent, buy, sell toggle sits above city and brand browsing, live listings and the pitch to owners.

www.biggoway.com/
Browse by city and by brand
Cities and brands with a call-to-action for owners
www.biggoway.com/
Active listings on the home page
Live listing cards with call and WhatsApp actions
  • 1
    Three intents, one inputRent, buy and sell tabs over one search. Category shortcuts cover luxury, sport, SUV, monthly, cheap, supercars, convertibles, wedding cortèges, yachts and motorbikes.
  • 2
    Cities and brandsWilaya cards for Algiers, Oran, Constantine, Annaba, Sétif, Tlemcen, Blida and Batna, plus a brand grid with dedicated brand pages.
  • 3
    Contact in one tapEvery card exposes a call button and a WhatsApp deep link. There is no in-app checkout yet, so the platform's job is to make the handoff instant.
02 · Search

Filters built for how Algerians shop for cars

The search page is dense on purpose: category chips, a brand row, a location filter and a sort. Listings show daily, weekly and monthly prices with free delivery and insurance flags.

www.biggoway.com/#/search
Rental search with filters
Category and brand chips, location filter and result cards
  • 1
    Category and brand rowsChips for every category and brand, driven by constants so the same lists feed the home page and the search.
  • 2
    Price tiersPer-day, per-week and per-month pricing on each card, with delivery and insurance badges from the listing record.
  • 3
    Public view, not raw tableResults come from a listings_public view that adds verified badges, pinning and priority weight from the owner's active subscription.
03 · Sale and detail pages

A listing page that answers the phone call before it happens

The car page carries the gallery, the rental rates, the full specification sheet, accepted payment methods, the seller's card and the rental conditions.

www.biggoway.com/#/car/…
Car detail page with gallery and rates
Gallery, daily and weekly rates, rental card
www.biggoway.com/#/car/…
Specification sheet
Reference, year, brand, model, engine, gearbox, fuel, doors, seats, category
  • 1
    Watermarked galleryPhotos are watermarked with the Biggo mark on the owner's device before upload, so scraped images still advertise the platform.
  • 2
    Rates and conditionsDaily, weekly and monthly rates, kilometre limits, deposit and the documents the renter must bring.
  • 3
    Seller cardAgency or showroom name, verified badge, rating, address and a link to their public profile with all their listings.
04 · Wedding cortèges

A second marketplace inside the first

Wedding car cortèges are a real market in Algeria. Collections are curated by agencies, priced per night, with or without a chauffeur, and booked over WhatsApp.

www.biggoway.com/#/marriage-cars
Wedding cortège collections
Collections search with chauffeur options
www.biggoway.com/#/marriage-cars/…
A cortège collection page
Collection hero, included vehicles, price per night, booking conditions
  • 1
    Collections, not carsA collection groups several vehicles, a chauffeur option and a decoration option under one price.
  • 2
    Booking rulesReservation only after contract signature, exterior cleaning included, deposit rules and chauffeur formula, listed on the page.
  • 3
    Same trust layerThe agency card, verified badge and Biggo guarantee reuse the rental components.
05 · Onboarding agencies

Turning idle fleets into listings

Supply comes from rental agencies, private sellers and showrooms. The join page sells the platform to them with zero commission, direct bookings and three packages.

www.biggoway.com/#/join
Join page for rental agencies
Pitch to agencies: zero commission, direct bookings, 48 wilayas
www.biggoway.com/#/join
Package tiers on the join page
Starter, Pro and Fleet packages
  • 1
    Three account typesRenter agencies, private sellers and showrooms each get their own signup, setup wizard and dashboard. Showrooms activate instantly.
  • 2
    Packages with real limitsEach package caps listings, photos, ads and edits per month. The caps are enforced by database triggers, not by the UI.
  • 3
    Lead captureThe join form writes to a leads table that the admin team works from the dashboard.
06 · Sign-in and dashboards

Four roles, one build

Sign in leads to a role-specific dashboard: renters manage listings, documents and ads; sellers manage sale listings; showrooms manage inventory; admins run the marketplace.

www.biggoway.com/#/login
Sign-in page
Sign-in with trilingual copy
  • 1
    Renter dashboardStats, listing CRUD with watermarking, document upload for verification, multi-phone profile and a map pin with Leaflet.
  • 2
    Showroom inventoryBulk operations, internal reference and warranty fields, a sold state that archives without deleting, and a public showroom page.
  • 3
    VerificationIdentity and business documents are uploaded and reviewed by admins before the verified badge appears on listings.
07 · Admin panel

An operator's console with an audit trail

The client's staff moderate listings, verify documents, manage accounts, run promotions, edit legal pages and change packages, all with per-person permissions and a full audit log.

  • 1
    Ten permission keysListings, accounts, documents, ads, packages, subscriptions, leads, settings, admins and audit. Stored as JSON on the admin role and enforced in Postgres policies.
  • 2
    Audit log with diffsOne trigger records before and after images for nine admin tables. The viewer shows per-field diffs, paginates server-side and exports to Excel.
  • 3
    Feature matrixVerified badge, premium badge, pinned in search, pinned on home and priority weight, toggled per package with no deploy.
Brand pages
Supplier public profiles
Wilaya browsing
Yachts, jet skis and motorbikes
Ads with click tracking
Legal pages editor
Excel export
Leaflet maps for agencies

Architecture.

No custom server. Business rules live in Postgres.
Client
React 18 + Vite SPA48 routes · shadcn/ui on Radix · Tailwind · i18next with FR, AR and EN inline · react-hook-form + zod · recharts · Leaflet · Excel export
Public site + 4 dashboardsRenter, seller, showroom and admin areas gated by ProtectedRoute, with admin navigation filtered by permission keys
Client-side watermarkingListing photos get the Biggo mark baked in before upload
→
Supabase
Postgres with RLS on every table18 tables: profiles, listings, user_documents, ads, wedding_collections, leads, packages, package_limits, subscriptions, listing_events, features, package_features, audit_log, app_settings, legal_pages, admin_roles…
Functions and triggersis_admin · admin_has_permission · fn_package_limit · fn_audit · admin_activate_subscription · privilege-escalation guard · listings_public view
Auth + StorageEmail/password with profile row created by trigger and role clamped to safe values · listings bucket for watermarked photos
→
External
WhatsAppDeep links for buyer-to-seller contact and bookings
OpenStreetMapAgency locations on Leaflet maps
PaymentsGateway not integrated yet; packages are activated by admins after offline payment

Engineering deep dives.

Six decisions, one production incident.

1. Subscription limits that cannot be bypassed

Problem
Package quotas for listings, photos, ads and monthly edits have to hold even against raw API calls with a stolen token.
Approach
One source of truth, fn_package_limit(user, key), where NULL means unlimited, plus SECURITY DEFINER triggers on listings and ads that reject inserts over the cap. Monthly edits are counted through a listing_events row written on every update.
Trade-off
Database errors are ugly, so the forms pre-check the same limits for a friendly message. Admin ads bypass the cap through an is_admin short-circuit.
Lives in: supabase/migrations/20260802000100_packages_enforcement_triggers.sql

2. Grandfathering with zero data migration

Problem
Existing accounts must not break the day limits go live.
Approach
The rule 'no subscription row means unlimited' is encoded once in fn_package_limit rather than as a backfill. The same absence-as-privilege pattern covers admins with no role row.
Trade-off
Absence as privilege is dangerous. It is why the admin role foreign key restricts deletes instead of setting null, which would have silently escalated everyone holding a deleted role.
Lives in: fn_package_limit, admin_has_permission

3. Feature flags as data

Problem
Paid perks such as badges, pinning and ranking had to be togglable by the client without a deploy.
Approach
A features catalog joined to packages through package_features. The listings_public view computes badge_verified, is_pinned and priority_weight per row from the owner's active subscription, and every public surface reads the view.
Trade-off
The view fans out on every public read. Acceptable at current scale, and the first thing to cache when it is not.
Lives in: 20260807000000_feature_flags.sql, AdminPackages.tsx

4. Granular admin permissions retrofitted onto live RLS

Problem
One admin role had full power. The client needed restricted staff accounts without disrupting production.
Approach
A permissions JSON on admin_roles, an admin_has_permission function, and fifteen existing policies altered by exact name rather than dropped. A trigger blocks self-role changes and admin grants without the manage_admins key.
Trade-off
Navigation gating in the client is only for UX. The database is the gate.
Lives in: 20260813110000 to 20260813113000 migrations, AdminTeam.tsx

5. A generic audit log from one trigger

Problem
The client wanted a billable record of who changed what across nine admin tables.
Approach
A single fn_audit AFTER trigger stores before and after row images as JSON, skips no-op updates and tolerates text and UUID primary keys. The table has admin-only read policies and no insert policy at all, so writes only happen through the trigger.
Trade-off
Row images grow without bound. There is no retention policy yet.
Lives in: fn_audit, AdminAuditLog.tsx

6. The incident: RLS runs as the querying role

Problem
After revoking function execution from the anonymous role for hygiene, the public site showed zero cars. Every listing policy called admin_has_permission, which anonymous readers could no longer execute.
Approach
Diagnosed by simulating the anonymous role in SQL, fixed with a targeted migration, and written up as a convention: grants on functions referenced by policies are part of the public API surface.
Trade-off
A one-line grant took the site down. Security hygiene needs the same testing as features.
Lives in: 20260826100000_fix_anon_listings_visibility.sql, BIGGO_ROADMAP.md

Business model.

Zero commission for buyers, packages for suppliers, modules for the client.
Starter
Get listed
  • A handful of active listings
  • Monthly refresh quota
  • Standard placement
Pro Most popular
Grow the fleet
  • More listings, photos and ads
  • Verified and premium badges
  • Pinned in search
Fleet
Whole inventory
  • Highest caps
  • Pinned on home
  • Top priority weight
Renter agency
  • Rental listings and cortèges
  • Documents and verification
  • Ads and usage meters
Private seller
  • Sale listings
  • Seller dashboard
Showroom
  • Instant activation
  • Inventory with bulk ops
  • Public showroom page
Admin and staff
  • Permission-scoped console
  • Packages and subscriptions
  • Audit log
Delivered as quoted modules through Barmjli: showroom profile, packages and subscriptions, dynamic feature flags, admin core, then global settings and multi-admin permissions. Each root module leaves the platform working on its own, so the client could stop at any step.

Results.

What shipped, and what it changed for the client.
Delivery

Five quoted modules, live in three months

Showroom accounts, packages and subscriptions, feature flags, the admin core, and multi-admin permissions with an audit log, each shipped as a migration-backed release on a live database.

Operations

The client runs it without a developer

Packages, perks, legal pages, settings and staff permissions are all data. Turning a badge on for a tier or restricting a staff account needs no deploy.

Early stage

Supply onboarding is underway

Renter agencies, private sellers and showrooms are onboarding across the first wilayas. Traffic numbers are the client's to share, so this page sticks to what the code shows.