Application reference. This is an illustrative architecture and scope checklist, not a verified customer project or measured deployment. Technologies, integration scope and delivery items are agreed for the actual brief.
Scenario and Constraints
A logistics operator replacing spreadsheet dispatch and manual billing. Two constraints drive the design: drivers work in areas with no reliable signal, and every invoice line must be defensible when a customer disputes it. That pushes the system toward an append-only event log as the source of truth rather than a status column anyone can overwrite.
Architecture
Layers and responsibilities
| Layer | Technology | What it is responsible for |
|---|---|---|
| Operations web | Vue 3 + Element Plus | Order intake, dispatch board, exception handling, billing review. |
| Driver app | Android (Kotlin), offline-capable | Task list, scan, photo, signature and status capture. Everything is written locally first and uploaded when a connection is available. |
| Customer portal | WeChat mini program | Self-service tracking; measure any change in enquiry volume rather than assuming a reduction. |
| API | Go + Gin | Validation, dispatch rules, event ingestion, charge calculation. |
| Storage | MySQL | Consignments, events, settlement. The event table is append-only and is the system of record. |
| Cache / queue | Redis | Dispatch board caching, upload deduplication, background jobs for billing and notifications. |
| Files | Object storage | Proof-of-delivery photos and signatures, referenced by key rather than stored in the database. |
Data Model
The tables below carry the rules that everything else depends on. Getting these wrong is what turns a working demo into a system that cannot be extended.
Core entities
| Entity | Key fields, relations and rules |
|---|---|
| consignment | The shipment record: parties, addresses, service type, time windows, declared weight and volume, and the pricing basis agreed at intake. |
| shipment_event | Append-only, timestamped, with operator, location, event type and payload. Current status is derived from the latest event, not stored separately — this is what makes the timeline defensible in a dispute. |
| task / assignment | Driver and vehicle assignment with stop sequence, plus the reassignment history when a job is handed over. |
| pod_asset | Proof of delivery: photo and signature keys, capture timestamp and device location, kept as the evidence behind billing. |
| charge / invoice | Charge lines generated from rules over recorded events, each carrying the event id that justified it. An invoice line with no traceable event is rejected by design. |
| rate_card | Customer-specific pricing rules by weight, volume, distance, waiting time and surcharge, versioned so historical invoices keep reproducing their original amounts. |
Key Interfaces
Endpoints that carry the business rules
| Endpoint | Purpose and concurrency notes |
|---|---|
| POST /api/v1/consignments | Order intake with address geocoding and rate-card resolution at creation time, so the pricing basis is fixed before the job runs. |
| POST /api/v1/events/batch | Bulk event upload from the driver app after a connectivity gap. Deduplicated on a client event UUID, and stores capture time separately from receipt time so the timeline stays truthful. |
| POST /api/v1/tasks/{id}/pod | Uploads signature and photos with the capture timestamp, returning storage keys that attach to the consignment. |
| POST /api/v1/billing/run | Generates charge lines from events for a period. Idempotent per (customer, period) so a re-run corrects rather than duplicates. |
| GET /api/v1/track/{no} | Public tracking, cached, exposing only the customer-visible subset of events. |
Technical Decisions
- Events as the source of truth, status as a derived value. An editable status column loses the history that dispute handling depends on. Deriving status costs a join and buys a complete, defensible audit trail.
- Capture time and receipt time stored separately. A driver's scan at 14:02 uploaded at 17:30 must show as 14:02 with a known upload delay, otherwise every offline area produces a wrong timeline.
- Client-generated event UUIDs. Retried uploads are normal on poor connections, so deduplication has to happen on an identifier the client owns.
- Rate cards versioned rather than edited. A price change must not silently rewrite last month's invoices, so old versions stay and historical charges keep pointing at them.
- Billing generated but not auto-issued. Rules cover the calculable cases; anything needing human judgement lands in a review queue instead of being forced into automation.
Hypothetical Design Targets
The figures below are hypothetical capacity-planning examples, not measured client results, a validated sizing recommendation or an SLA. Set project-specific acceptance targets after defining the workload, devices, data, hardware and third-party dependencies; verify them through a pilot and load tests before committing to a production target.
Capacity and performance targets
| Target | Value and assumption |
|---|---|
| Event ingestion | Batches of up to a few hundred events per upload, deduplicated, sized for a driver returning from several hours offline. |
| Dispatch board | Renders the active working set in under 1 second, with server-side filtering and pagination rather than loading everything into the browser. |
| Billing run | A month of events for one customer processed as a background job with progress reporting; run time scales with event volume and is measured against your real data during acceptance. |
| Photo upload | Compress and queue locally before upload, retry on failure, and verify retention, acknowledgement and recovery on the actual devices. |
What Delivery Includes
- Operations web source, Go backend source, Android driver app source and mini program source
- Database schema with the event and settlement tables documented, plus migration history
- API documentation including the offline upload and deduplication contract
- Deployment notes, object storage configuration, backup and restore procedure
- Data migration plan from existing spreadsheets, with a reconciliation report after import
Planning This for Your Business
The modules above are a starting point, not a fixed package. We normally cut the first release to one core workflow plus one admin workflow, then extend once real usage shows where the load and the edge cases actually are. Send a scoped brief and we will map it against this architecture and tell you which parts you do not need yet.

