Skip to content

Driver Subscribing

Taxi & Private HireProductsSurge › Driver Subscribing

beta

The driver side of Surge: how a driver opts into a busy cluster, gets sent trips, and earns a share of the pool. Opting in enrols the driver, switches them into open (auto-accept) dispatch for the duration, and starts an arrival commitment — reach the zone by an honest deadline and the drive-in counts toward their share; dawdle and some credit is docked. From then on they bank pool credit for every minute they are genuinely available in the cluster, whether waiting there or carrying a cluster trip out of it. Pool share is a fairness gate, never a bonus: completing more trips never increases it, but ducking a trip the cluster assigned you shrinks it. Drivers can see the clusters they can join and their own current standing.

Opt in, and you're pulled toward demand

A driver joins a surge by subscribing to its zone. That makes them available for trips in the busy area and starts banking their share of the pool. Subscribing is the driver's own choice — it lifts them into the dispatch pool for the cluster, but it never overrides an operator who has switched that driver off, and it lapses automatically when they go offline or the surge ends.

It's availability that's measured — the arrival contract

The pool pays for the scarce thing — being there — not trips served (the trip already pays its own fare). So when you subscribe you take on a light arrival contract: commit to reach the zone by an honest deadline; arrive on time and your drive-in is credited; then you bank compliant minutes for every interval you're actually present — idle in the zone, or serving a trip that started there. Miss the deadline or drop offline and that gap simply earns nothing; it's never back-credited.

1 Declare commit · deadline to arrive 2 Arrive on time drive-in credited 3 Accrue minutes bank while present Close surge ends / leave Present = a live session, available for trips, and in the zone (or serving a trip from it). No presence, no credit for that interval.
Honest, present-gated time — a driver serving a cluster customer out of the zone stays credited, so an idler can't out-earn the one doing the work.

You keep your fares — the pool is the surge, shared by availability

Two separate pots, and they don't mix. Every trip you complete pays its normal fare to you — surge or not, a lucky high-value trip is entirely yours, exactly as it would be without surge. What's pooled is the surge the customer paid on top: it doesn't go to whoever happened to grab the surged trip, it's shared by availability across everyone who was compliantly present. So your pool share is your compliant minutes × your completion rate (trips completed vs assigned) — flat per minute. Doing more trips earns you more fares; it never inflates your pool share. Ducking an assigned trip shrinks it — and only your own cancellations count against you; anyone else's are reversed.

Banked minutes settle through Pooling the Money; the zone comes from Surge Detection.

Fields

FieldTypeDescription
clientId bigint Tenant scope. Every tenant-aware entity carries this; `ClientFilter` enforces row-level isolation on read; the multi-tenancy routing layer (`/client/{clientId}`) sets it at create time. Surfaced only under `admin` / `tripLog` groups — never to end users.
internalKey string Optional client-supplied external reference / idempotency key. When present, lets external systems correlate platform-side records back to their own source-of-truth ids. Not persisted to a column — populated by the request handler when the caller sets it.
__objectType string Discriminator string (entity class short-name) emitted alongside the id in serialized output. Resolved at read time by `getObjectType()`; lets the FE dispatch entity-specific rendering without inspecting the URL.
id bigint Snowflake-style primary key (unsigned BIGINT). Generated by `IdFactory` at create time; surfaced to the FE / API as a `G`-prefixed string and stripped back to plain bigint server-side before Doctrine lookup.
createdDate integer Unix timestamp the row was first persisted. Set in the entity's PrePersist hook; never rewritten on subsequent updates.
updatedDate integer Unix timestamp the row was last touched. Bumped on every commit that hits the Doctrine UoW for this entity; drives FE invalidation + the listing change cursor.
passiveUpdatedDate int Read-through alias for `updatedDate` exposed under different serializer groups. Lets the FE distinguish "real edit" from "background touch" projections without changing the underlying column.
listingUpdatedDate int Listing-projection timestamp surfaced only under the `listMode` group. Driven by `TripCache` and other listing-shape refreshers separately from `updatedDate` so a listing rebuild doesn't trigger detail-page invalidation.