Delivered remotely for a business based in Tampere, Finland. Names withheld by agreement.
Project Overview
Industry: Logistics and transportation services — on-demand collection and delivery dispatch.
Type of solution: A REST API backend with three role-partitioned interfaces, paired with a cross-platform mobile application that presents a different product to each role from a single codebase.
Business context: Dispatch operators sit between two groups who never talk to each other directly. Client organisations need collections to happen; drivers need to know what to do and where. The operator coordinates, and in most small and mid-sized operations that coordination happens verbally. It works until something is disputed — a collection the client says never happened, a count the driver disagrees with, a job nobody remembers assigning. Without a record, those disputes are settled by whoever argues most confidently.
General users: The dispatch operator's administrative team, client organisations raising requests, and field drivers carrying out collections.
General purpose: To replace verbal coordination with a recorded workflow — controlled onboarding, structured requests, explicit assignment, and photographic evidence of completion.
The Business Challenge
Requests arrived through uncontrolled channels. Phone calls and emails meant request details were transcribed by hand, with the inevitable errors, and there was no single queue showing everything currently outstanding.
Assignment was verbal and unrecorded. The operator phoned a driver. If that driver later said they were never told, or two drivers thought a job was theirs, nothing in the system could settle it.
Completion had no evidence. The most common dispute in collection work is whether a collection happened and what was actually collected. Without evidence captured at the point of work, the operator carries the risk of every disagreement.
Onboarding was uncontrolled. New client organisations and new drivers were added ad hoc. There was no gate ensuring that an organisation had been vetted before it could start raising work.
No live view of workload. The operator could not see, at a glance, what was outstanding, what was assigned, and what was finished — which makes balancing work across drivers guesswork.
Three audiences with nothing in common. An operator, a client organisation and a driver need different information, different actions and a different interface. Building and maintaining three separate applications was not economically viable.
Drivers work where connectivity is poor. Any field application has to behave sensibly on a weak connection, and must not lose a completed job's evidence because a signal dropped.
Our Approach
Partition by role at the architectural level, not with conditionals. Rather than one set of endpoints filtering behaviour by user type, we built separate route groups per role, each behind its own authentication guard and prefix. A driver endpoint is not merely forbidden to a client organisation — it is not reachable. This is a structural security property rather than a runtime check that a future change might bypass.
Make evidence the centre of the workflow. Photographic proof at completion was not treated as an optional attachment. It is part of what completing a job means, captured on the device, uploaded to durable cloud storage, and viewable later — including zoomable inspection when a detail is in question.
Design the lifecycle as an auditable timeline. Status alone answers "what is it now". We recorded who assigned the work and when, and when completion occurred, so the record answers "what happened, in what order, and who did it".
Notify the right people at the right moment. Every meaningful lifecycle event — creation, cancellation, assignment, completion — dispatches notifications to the parties that event affects, across both push and email, because the operator and a driver in a vehicle are not reachable the same way.
Tune the database deliberately. As real usage accumulated, we measured listing query behaviour and added targeted indexes across the main tables rather than waiting for the interface to feel slow.
One app, three products. The mobile application resolves the user's role at login and composes an entirely different navigation structure and screen set for each, sharing the networking layer, state management and component library underneath.
The Solution
Controlled onboarding with an approval gate. Client organisations register themselves but gain no operational access until the operator approves them. Drivers are created by the operator, with a record of who created each account. Onboarding becomes a deliberate decision rather than an accident of who found the sign-up screen.
Structured request creation. Client organisations raise requests carrying the on-site contact name and phone number, the item count, full address components, special instructions and a supporting image. What used to be transcribed from a phone call is now entered once, by the party that knows it.
A single live work queue. The operator sees all requests with their current state, and can assign, unassign and cancel. Workload across the fleet becomes visible rather than remembered.
Explicit assignment with attribution. Assigning work to a driver records both the assignment and the person who made it, with a timestamp. Disputes about who was told what have a factual answer.
Driver work queue. Drivers see the jobs assigned to them, open them for full detail including the site contact and special instructions, and mark them complete.
Photographic proof of completion. Drivers capture and upload multiple images at completion, stored durably against the job. Evidence exists at the moment it matters, rather than being reconstructed afterwards.
Evidence review with zoomable inspection. Uploaded images are viewable in the app with zoom, so a detail — a count, a condition, a location — can be examined when a question arises.
Multi-channel notifications. Push notifications keep drivers and operators informed in real time; email notifications provide the durable record and reach people who are not in the app. The operator can also send broadcast notifications when something needs to reach everyone.
Manual driver ordering. The operator maintains their own ordering of drivers, reflecting the practical reality that dispatch priority is a judgement call informed by things the system does not know.
Self-service account management. All three roles can recover passwords and delete their accounts from within the application.
Key Features
Three role-specific experiences in one application Operator, client organisation and driver each get their own navigation, screens and permitted actions, resolved at login — one codebase, three coherent products.
Approval-gated organisation onboarding Organisations register themselves but cannot raise work until approved, so the operator controls who is in the network without managing account creation manually.
Structured collection requests Requests capture site contact, item count, full address, special instructions and a supporting image — entered once by the party who knows the details.
Assignment with full attribution Every assignment records the driver, the person who assigned it and the time, converting a verbal instruction into an auditable fact.
Photographic proof of completion Drivers upload multiple images at completion, stored durably in cloud object storage and linked to the job for later review.
Zoomable evidence review Completion images can be inspected in detail within the app, so disputes are resolved by looking rather than by arguing.
Multi-channel lifecycle notifications Creation, cancellation, assignment and completion each notify the affected parties by push and email, with device token management ensuring messages reach current devices.
Operator broadcast messaging The operator can push a message to the whole user base when something needs to reach everyone at once.
Auditable request timeline Assignment and completion timestamps alongside status give a chronological record of each job rather than only its current state.
Manual driver prioritisation The operator maintains their own driver ordering, supporting dispatch decisions that depend on knowledge the system does not hold.
Technical Architecture
Mobile client. A cross-platform application that resolves the authenticated user's role at login and composes an entirely different navigation structure — stack, tabs and drawer — per role. Screens are organised by role; the networking layer, state store and component library are shared.
API layer. A REST API with route groups partitioned per role, each behind its own authentication guard and URL prefix. Token-based OAuth2 authentication governs access, and listing endpoints follow a consistent, standards-conformant pagination scheme.
Application layer. Controllers organised by concern rather than by entity — registration, authentication, account security, request creation, request listing, per-role management, notifications and content — over an abstract base controller providing shared response handling, with a global helper module for cross-cutting functions.
Domain and data layer. A compact, tightly constrained relational model covering administrators, client organisations, drivers, requests, completion images and device tokens. Foreign key constraints enforce integrity at the database level, soft deletes preserve history, and targeted indexes support the high-traffic listing queries.
Media and evidence storage. Completion images are uploaded to cloud object storage rather than application servers, so evidence is durable and application instances remain stateless.
Notification layer. Push notification delivery through a cloud messaging service with a per-device token registry, alongside transactional email for the durable record.
Observability. Crash and error monitoring on the mobile client; log inspection tooling on the server.
Delivery. Continuous integration with automated deployment, so releases to a live operational system are repeatable.
Flow: Mobile app (role-resolved) → Role-partitioned REST API → Controllers & domain logic → Relational database (indexed, constrained) → Cloud object storage for evidence → Push & email notification to affected roles
Technology Stack
| Category | Technology |
|---|---|
| Backend language | PHP 8.3 |
| Backend framework | Laravel 12 |
| Database | MySQL with explicit index tuning, foreign key constraints and soft deletes |
| API authentication | Laravel Passport (OAuth2) and Sanctum |
| API conventions | JSON:API-conformant pagination |
| Object storage | Google Cloud Storage |
| Push notifications | Firebase Cloud Messaging with native iOS push handling |
| Laravel Mail over SMTP | |
| Mobile framework | React Native with React 19 |
| Mobile state | Redux Toolkit, React Redux |
| Mobile navigation | React Navigation (stack, bottom tabs, drawer), composed per role |
| Mobile networking | Axios with a dedicated network layer |
| Mobile monitoring | Sentry |
| Device capabilities | Geolocation, connectivity detection, camera/image capture with cropping, runtime permissions |
| Media viewing | Zoomable image viewer |
| Diagnostics | Server-side log viewer |
| Testing & quality | PHPUnit, Faker factories, Mockery, automated code style checks |
| CI/CD | CircleCI with Capistrano deployment |
Technical Challenges & Solutions
| Challenge | Our Approach |
|---|---|
| Three roles with entirely different permitted actions and data visibility | Route groups partitioned per role, each behind its own guard and prefix, so cross-role access is structurally impossible rather than prevented by a conditional check that a later change might weaken. |
| Disputes over whether work was completed and what was collected | Photographic proof captured at the point of completion, uploaded to durable cloud storage, linked to the job, and viewable later with zoom — evidence created at the moment it matters. |
| A status field that could not answer "what happened and when" | Assignment and completion timestamps recorded alongside status, plus attribution of who performed each assignment, giving each job an auditable timeline. |
| Reaching three different audiences at the right moment | Lifecycle events dispatch notifications to the specific parties affected, across push for immediacy and email for the durable record, with a per-device token registry keeping delivery targeted. |
| Uncontrolled onboarding of client organisations | Self-registration combined with an approval gate: an unapproved organisation can authenticate but has no operational capability until the operator approves it. |
| Listing performance as request volume accumulated | Targeted database indexes added across the high-traffic tables based on observed query behaviour, alongside consistent pagination on every listing endpoint. |
| Drivers working in areas with unreliable connectivity | Connectivity awareness in the mobile client so the application behaves predictably on weak networks, with uploads and actions handled accordingly rather than failing silently. |
| Preserving operational history while allowing removal | Soft deletion applied across the model — including device tokens — combined with database-level foreign key constraints, so records can be withdrawn without destroying the history that references them. |
| Building three products on one budget | A single mobile codebase composing a different navigation tree and screen set per role over a shared networking, state and component foundation. |
Security & Reliability
Authentication. Token-based OAuth2 authentication with separate login surfaces per role and password recovery flows for each.
Structural authorisation. Role separation enforced by partitioned route groups with independent guards, rather than by conditional logic inside shared endpoints — the difference between an endpoint a user may not call and one a user cannot reach.
Access gating. Newly registered client organisations hold an unapproved state in which authentication succeeds but operational capability is withheld until the operator approves them.
Data integrity. Foreign key constraints enforced at the database level so relationships cannot be orphaned by application-layer mistakes.
Auditability. Assignment attribution, lifecycle timestamps and soft deletion together preserve a defensible record of what happened to each job and who acted on it.
Evidence durability. Completion images are stored in cloud object storage, independent of application server lifecycle.
Device token hygiene. Push tokens are registered per device and withdrawn through soft deletion, so notifications follow active devices and stop reaching removed ones.
Observability. Mobile crash and error monitoring plus server-side log inspection give visibility of real-world failures across a distributed field user base.
Repeatable releases. Automated continuous integration and deployment so changes reach a live operational system through a controlled, repeatable process.
Scalability & Performance
Indexed query paths. Indexes were added deliberately across the main tables based on how the listing endpoints actually query them, rather than assumed at design time.
Consistent pagination. Every listing endpoint follows a standards-conformant paging scheme, so no endpoint returns an unbounded result set as history accumulates.
Naturally scoped result sets. Because endpoints are partitioned by role, a client organisation's queries are inherently limited to its own requests and a driver's to their own assignments.
Stateless application tier. With evidence in cloud object storage and token-based authentication, application instances hold no local state and can be scaled horizontally.
Efficient media handling. Images are captured and processed on the device before upload, keeping payloads small on mobile connections and avoiding server-side processing overhead.
Non-destructive data growth. Soft deletes preserve history without the fragmentation and referential problems that hard deletion causes in an audit-sensitive dataset.
Business Outcomes
- Requests arrive complete and structured, entered by the party who knows the details rather than transcribed from a phone call.
- The operator has a live view of all work, making it possible to balance load across drivers instead of relying on memory.
- Assignment is a recorded fact, with attribution and timestamps replacing verbal instruction.
- Completion disputes have evidence behind them, because photographic proof is captured as part of finishing the job.
- Onboarding is controlled, with organisations vetted before they can raise work and drivers created deliberately by the operator.
- All three parties stay informed automatically, through push and email notification at each lifecycle event.
- History is preserved, with soft deletion and lifecycle timestamps supporting after-the-fact review.
- One development effort serves three audiences, keeping the platform economically sustainable for a mid-sized operator.
Why it worked
Multi-role operational platforms fail in predictable ways. Role separation gets implemented as a series of conditional checks that erode with every new feature. Evidence capture gets treated as an optional attachment and turns out to be missing exactly when it is needed. Listing screens are fast in testing and slow after eighteen months of real data.
Our team builds against those specific failure modes. We partition roles structurally so cross-role access is impossible rather than merely disallowed. We make evidence part of what completing work means, stored durably and independently of the application. We record attribution and timestamps because "what is the status" and "what happened" are different questions, and operators eventually need the second one. And we measure query behaviour against real data, then index deliberately.
Our teams work across modern PHP and Laravel, REST API design, cross-platform mobile development, cloud storage and messaging integration, and automated deployment — and, importantly, across the operational domains where these systems live. The difference between a dispatch platform that gets used and one that gets abandoned is usually not the feature list; it is whether the people doing the work find it faster than the phone call it replaced.
Final Summary
Dispatch and collection operators run a coordination business, and coordination conducted verbally leaves no trace. Requests arrive by phone and get transcribed. Assignments are made by call and remembered rather than recorded. Completion is asserted rather than evidenced. It works until it is questioned — and when it is questioned, the operator has nothing but recollection to offer.
Our team built a platform that gives that coordination a record. Client organisations raise structured requests directly, with contact details, counts, addresses and instructions captured once by the party that knows them. The operator sees one live queue, approves who joins the network, and assigns work with attribution and timestamps. Drivers see their own queue and complete jobs with photographic proof uploaded from the field to durable cloud storage. Every lifecycle event notifies the parties it affects through both push and email.
The engineering emphasis was on the properties an operational system needs to be trusted: role separation enforced structurally rather than conditionally, evidence captured at the moment of work and stored independently of the application, an auditable timeline rather than a bare status field, and database indexes tuned against real query behaviour. Delivered as one API and one mobile codebase serving three distinct audiences, it is the kind of platform that replaces a phone call without asking anyone to work harder.