Training manual
Section 1 of 71: Introduction
This documentation covers how Econ works end to end - for office staff on this web dashboard, field workers on the mobile app, and equipment owners. Use the menu on the left to jump to a specific operation (creating a project, starting a site, scanning QR, approving trip issues, generating reports, and more).
Scope
- How to set up a company, project, site, and field team from zero.
- LINEAR (chainage) vs AREA (map polygon) projects - when to use each.
- All 12 trip process types: standard QR, no-loader, paper QR, offline, exceptions, weighbridge, and more.
- How GPS verification works for loader, driver, and unloader on LINEAR and AREA sites.
- Weighbridge / scale weight capture and how net weight becomes product quantity.
- Inter-company (ICT) partner handoff between sender and receiver companies.
- How to read reports, approve trip issues, and close a site.
Shorter topic pages are also available from the home menu: Platform, Trips, Trip issues, Office dashboard, Roles.
| Term | Meaning |
|---|---|
| Company | Your employer org in Econ. Office users may belong to several and switch in the header. |
| Company worker | Person in the company directory (phone, role). Created in User Management - not the same as project membership. |
| Project member | Company worker assigned to a specific project (drivers often have linked equipment). |
| Project | Construction job - LINEAR (chainage CSV/map) or AREA (closed polygon on map). Contains products, places, sites, members. |
| Project type | LINEAR = alignment + chainage. AREA = map zone + GPS places (requires area_projects feature). |
| Product | Material tracked (DELIVERY or DISPOSAL) with units and target quantities. |
| Product place | LOADING, UNLOADING, or DISPOSAL point - chainage (LINEAR) or lat/lng (AREA). |
| Site | Work zone - chainage segment (LINEAR) or drawn polygon (AREA); dates, products, places. |
| Chainage | Distance along centerline, e.g. 13+800 (km+mmm). LINEAR sites must sit inside project range. |
| boundaryGeoJson | Polygon geometry for AREA project boundary or site zone (GeoJSON). |
| Disposal site | Site flagged isDisposalSite - pickup zone + selected dump destinations. |
| Verification mode | How GPS is checked: CENTERLINE (LINEAR) or polygon rules (AREA). |
| GpsCheckResult | pass / fail / skip per role (loader, driver, unloader). |
| Trip | One load movement: loader → driver → unloader (office can edit and approve issues). |
| QR handoff | Loader shows QR; driver scans in mobile to accept the trip. |
| Report value | Fixed score on approved trip issues: 0, −1, or +1 - affects product totals. |
| Weighbridge / weight type | Product-level scale capture (camera OCR or manual); needs company feature weighbridge_weights. |
| netWeight / quantity | Absolute mass from loader−unloader (or reverse for disposal); quantity converts to product unit. |
| Inter-company trip (ICT) | Partner handoff: sender trip unloaded in A, receiver trip created in B via trip_link. |
| Trade lane | Active inter_company_link: sender site/product → receiver site/product (+ intake mode). |
Office (this website) → ComapySass API → projects, sites, reports, users Field (mobile app) → Field API → trips, QR, offline queues, equipment Both share the same business story: projects consume equipment and record every delivery trip.
| Surface | Who | Main work |
|---|---|---|
| Web dashboard | Engineers, dispatch, HR, management | Projects, sites, KPIs, reports, trip issue approval |
| Mobile app | Loader, driver, unloader, foreman | Work tab, QR, site start, issue report/classify |
| Mobile / web (field) | Equipment owner | List equipment, usage reports |
A typical day
- Morning - office: log in, switch company, check dashboard KPIs, add a site or adjust members.
- Morning - site: foreman opens Work, syncs after poor coverage, starts site or opens loader/driver screens.
- Handoff - loader shows QR; driver scans; unloader completes at destination.
- Evening - office: products/equipment reports; approve trip issues; generate site report.
- Evening - owner: mobile Reports tab for machine trip history.
Econ connects equipment owners, construction companies, and field workers through one trip-tracking story. Work proceeds in phases - skip one and field actions will block with validation errors.
| Phase | Who | What happens | Where | Blocks if skipped |
|---|---|---|---|---|
| 1 | Any user | Phone login via Telegram code | Mobile or web /login | Cannot open dashboard or Work |
| 2 | Equipment owner | Posts equipment listing | Mobile Home / Add Post | No personal trucks in marketplace |
| 3 | System admin | Company registered; feature flags | Ops / admin | No company context / JWT companyId |
| 4 | HR / admin | Workers added to company directory | Web User Management | Login: user not found |
| 5 | Office engineer | Project, products, places, sites, members | Web Projects | Mobile Work empty |
| 6 | Office engineer | Foreman, speed/time rules, site flags | Web site detail | Foreman cannot run site starter |
| 7 | Foreman | Assign teams → Start site → Loading | Mobile Work | Loader sites list empty |
| 8 | Loader / driver / unloader | Daily trips (12 scenario types) | Mobile Work | No trip rows / reports |
| 9 | Office / owner | Reports, GPS check, issues, closure | Web + mobile Reports | Incomplete totals / open sites |
Registration → Company users → Project + site setup → Foreman starts site → Phase 8 trips (QR / no-loader / paper / offline / weighbridge / ICT) → Reports, GPS verification, trip-issue approval, site Done
Registration today means: your phone is already in company_workers (or a platform user record), and you authenticate with a Telegram one-time code. Public /register does not create workers - an admin must add you first (Phase 4).
- 1Open login
Web /login or mobile login. Same phone rules on both surfaces.
- 2Enter phone
Prefer international digits (e.g. 2519…). Mobile normalizes 09… and 9-digit local to 251…; strips spaces and +.
- 3Request code
Backend looks up user by phone (± leading +). Sends 6-digit code via Telegram bot linked to that phone.
- 4Enter code
On success: web stores JWT (company-scoped); mobile stores long-lived session. Land on dashboard or five tabs.
- 5If login fails
“User not found” → phone not in directory. Wrong/expired code → request again. Bot never started → user must open Telegram bot once.
Multi-company workers
The same phone/user may belong to more than one company. On web, switch company in the header after login - JWT is re-issued for the selected company. On mobile Work, project lists are scoped to memberships for that user’s companies.
Equipment owners use the mobile marketplace to list trucks and machines. This is separate from company project work but feeds the pool companies can assign to drivers (alongside company fleet registered on Nearby Equipment).
- 1Home - browse with filters (category, location, type); open detail / contact.
- 2Add Post - 5-step wizard: category → type → specs → up to 4 images → details (phone required). Tab bar hides during wizard.
- 3Account - profile, my equipment, update GPS for nearby features.
- 4Reports - trip history per machine by date range (usage analytics, not favorites).
| Listing type | Created where | companyId | Who sees / assigns |
|---|---|---|---|
| Personal | Mobile Add Post | null (owner userId) | Owner; assignable if linked on project |
| Company fleet | Web Nearby Equipment → Register | active company | Office assigns to drivers |
/hearted placeholder.Phase 3 - Company registration
- Ops / system admin creates the company record (name, settings).
- Attach first owner / admin workers.
- Enable feature flags as needed: area_projects, weighbridge_weights, inter_company_trips, etc.
- Without company context, project creation and company-scoped APIs fail.
Important feature flags
| Flag | Unlocks |
|---|---|
| area_projects | AREA project type (map polygons, GPS places) |
| weighbridge_weights | Weight measurement types, weighbridge UI/APIs |
| inter_company_trips | ICT dashboard, Partner drivers, handoff QR/link APIs |
Phase 4 - Add company workers
Route: /dashboard/CompanyUsers - HR adds people to the company directory. Same person can be added to multiple companies (unique per phone+company / userId+company).
| Mode | When to use | Result | Limits |
|---|---|---|---|
| By phone (Telegram) | User has Telegram | Full role selection (field + office roles) | Must start Telegram bot for codes |
| Without Telegram | No Telegram access | Often loader_load only | Role may not be changeable later - check UI |
Field roles vs dashboard roles
| Type | Examples | Used for |
|---|---|---|
| Field | loader_load, driver, unloader_receive, foreman | Mobile Work, QR, site starter |
| Dashboard | office_engineer, project_manager, site_engineer, owner, product_manager | Projects, reports, trip issue approve, fleet |
Every project has a project type that controls geometry, sites, places, and GPS verification. Choose once at create time - field and office UIs branch on this type.
| Aspect | LINEAR | AREA |
|---|---|---|
| Geometry | Alignment / centerline from CSV or map points → parquet survey | Closed polygon boundaryGeoJson on project |
| Sites | Start/end chainage inside project range | Drawn site polygon inside project boundary |
| Places | Chainage / distance labels along line | Lat/lng + geofence radius (no chainage required) |
| Unload proof | Chainage km+mmm in site range + GPS vs survey point | GPS inside site polygon (or dump place) |
| Feature gate | Always available | Requires area_projects on company |
| Typical use | Roads, corridors, chainage contracts | Yards, borrow pits, polygonal work zones |
- 1Create project with type AREA (company must have area_projects).
- 2Draw or upload the project boundary polygon on the map - this is the outer allowed zone.
- 3Add products (DELIVERY and/or DISPOSAL) with units and targets.
- 4Add product places with latitude/longitude (and optional geofence radius) - LOADING / UNLOADING / DISPOSAL.
- 5Create a site by drawing a site zone polygon that sits inside the project boundary.
- 6Link products/places to the site; assign members; set dates and flags as on LINEAR.
- 7Foreman starts the site on mobile the same way; unloaders confirm GPS inside the zone instead of chainage.
| Failure | Cause | Fix |
|---|---|---|
| Cannot choose AREA | area_projects off | Enable company feature; re-login |
| Site save fails | Polygon outside project boundary | Redraw site inside project map |
| Add place fails | Missing lat/lng (or wrong chainage-only payload) | Enter coordinates; do not rely on chainage |
| Unload GPS fails verification | Worker outside site polygon | Move into zone or fix boundaryGeoJson |
A disposal site (isDisposalSite) models pickup of spoil/waste inside a zone and optional dump destinations.
- 1Create/select a DISPOSAL product and DISPOSAL places (dump destinations with GPS).
- 2Mark the site as disposal; link the pickup zone (often the site polygon on AREA).
- 3Select which dump places are allowed for this site.
- 4Assign unloaders per dump place when destinations must be staffed (disposalPlaceId on personnel).
- 5Field: loaders/drivers work pickup; unloaders complete at selected dump or pickup-only flow.
disposalPlaceId on unloader assignments - one unloader per dump that requires unloading.- 1Open disposal site
Work → project → disposal / loading site marked for disposal products.
- 2Pickup
Loader/driver operate inside the pickup zone (site polygon on AREA). Weighbridge may apply if product has weight type.
- 3Choose dump
When destinations exist, select disposal place before or during unload per site UI.
- 4Complete
Unloader scans/completes with GPS. Verification follows AREA DISPOSAL rules (place vs PASS).
Phase 8 covers every trip process type. Configure the site/product first, then train the matching scenario. Weighbridge (8.1.12) can combine with standard, no-loader, or offline paths.
| # | Scenario | When used | Key roles | First server status |
|---|---|---|---|---|
| 8.1.1 | Standard loader QR → driver → unloader | Default; loader required | Loader, driver, unloader | loading |
| 8.1.2 | Driver creates trip without loader | allowDriverTripWithoutLoader | Driver, unloader | driving |
| 8.1.3 | Paper QR | Printed QR from web site detail | Driver, unloader | driving (create+accept) |
| 8.1.4 | Multi-place / multi-loader | 2+ product places | 2+ loaders, drivers | loading per place |
| 8.1.5 | Verification codes | Poor connectivity / verbal confirm | All field + foreman | same as parent |
| 8.1.6 | Offline queued sync | No network during action | All field roles | queued → sync |
| 8.1.7 | Buffered accept | Driver scans before loader syncs | Loader, driver | buffer then driving |
| 8.1.8 | Reassign driver mid-site | Foreman changes personnel | Foreman, loader, new driver | in-flight unchanged |
| 8.1.9 | Trip exception / issue | Driver reports problem | Driver, foreman, office | issue_reported… |
| 8.1.10 | Office post-trip edit | Correction after field done | Office engineer | edited statuses |
| 8.1.11 | GPS verification | After unloaded | System, office | needs checking → approved |
| 8.1.12 | Weighbridge / scale weight | Product weight measurement type | Loader, unloader | + netWeight/qty |
Standard: loading → driving → unloaded → (needs checking) → approved Exception: ↘ issue_reported → pending_approval → approved | reject→issue_reported Weighbridge: loader gross ↔ unloader gross → netWeight → quantity (product unit) ICT (extra): A unloaded → handoff QR → B driving → B unloaded (separate trip_link)
The default flow when the site does not allow driver-only trips. Every load passes loader → driver → unloader with a QR handoff at load start.
Prerequisites (before first trip)
| # | Requirement | Set by |
|---|---|---|
| 1 | Project has products and product places | Office |
| 2 | Site linked to products/places; allowDriverTripWithoutLoader = off | Office |
| 3 | Loader, driver (+ equipment/plate), unloader are project members | Office |
| 4 | Foreman started site → status Loading | Foreman mobile |
| 5 | Loader assigned to a place; driver on site personnel | Foreman mobile |
[Loader Show QR] [Driver scan] [Unloader complete]
loading → driving → unloaded
↓
needs checking → approved (GPS, optional)Loader - step by step
- 1Work → project → Loader sites (Loading only; Not Started uses Start loading first).
- 2Open Loader site detail - pull to refresh trucks/drivers.
- 3Select driver + product (driver must be on site personnel).
- 4If weighbridge on product: capture loader gross (OCR/manual) + evidence if required.
- 5Tap Show QR - app captures GPS, POST scanQRCode → trip status loading; shows LoaderQRCodeDialog + optional loader verification code.
- 6Driver scans; regenerating QR for same load keeps the same identifier (updates trip, does not duplicate).
Driver - step by step
- 1Work → Driver sites → Scan QR / Accept load.
- 2Camera decrypts payload; optional verify loader code; confirm car/plate if prompted.
- 3POST acceptTrip with driver GPS → status driving.
- 4Transport (no API) until unload.
Unloader - step by step
- 1Work → Unloading sites → Unloader site detail.
- 2Scan QR or pick trip from list.
- 3LINEAR: enter chainage inside site start/end. AREA: confirm GPS in zone / dump place.
- 4If weighbridge: capture unloader gross (+ evidence).
- 5POST completeTrip → unloaded; office reports update.
Loader outcomes
| ID | Trigger | Result | Next |
|---|---|---|---|
| C1 Happy | Online, valid driver/product | QR + code; trip loading | Driver scans |
| C2 Regenerate | Close/reopen QR same load | Same identifier; trip updated | Scan new or same QR |
| C3 Driver busy | Driver already has active trip | UI warning / 403 | Pick another driver |
| C4 No product | Site misconfigured | Error before QR | Office fixes products |
| C5 No place | Loader not on a place | No location assigned | Foreman assigns place |
| C6 GPS denied | Location blocked | Fail or weak coords | Enable location |
| C7 Offline | Network fail | QR shown; Q1 queue | See 8.1.6 |
Driver outcomes
| ID | Trigger | Result |
|---|---|---|
| D1 Happy | Valid QR, online | driving |
| D2 Already accepted | Same driver scans again | alreadyAccepted; no duplicate |
| D3 Wrong driver | Another driver scans active trip | Error; original driver kept |
| D4 Invalid QR | Garbage / wrong code | Decode error |
| D7 Before loader sync | Loader offline, driver online | Error or buffered accept (8.1.7) |
| D8 Offline | No network on accept | Q2 queue |
Unloader outcomes
| ID | Trigger | Result |
|---|---|---|
| E1 Happy | Valid scan + in-range chainage/GPS | unloaded |
| E2 By trip id | Select from list | unloaded |
| E3 Chainage OOR | LINEAR km outside site | Validation error; stays driving |
| E4 Offline | No network | Q4 queue |
Drivers start trips without loader QR when office enabled the site flag and foreman started with supervisor only (no loader teams required). Delivery-oriented path.
Prerequisites
| # | Requirement | Where |
|---|---|---|
| 1 | allowDriverTripWithoutLoader = true | Office Manage Sites / site settings |
| 2 | Supervisor assigned on Site starter | Foreman mobile |
| 3 | Site Started → Loading (supervisor-only start allowed) | Foreman |
| 4 | Driver is project member with equipment/plate | Office project members |
| 5 | For offline create: one prior online session to cache equipment | Driver site |
| Aspect | Standard (8.1.1) | No-loader (8.1.2) |
|---|---|---|
| First server status | loading | driving |
| Loader involved | Yes | No |
| Foreman start | Loaders + supervisor | Supervisor only (if flag on) |
| Driver action | Scan QR | Create trip → product + truck |
| API | scanQRCode + acceptTrip | driverCreateTrip |
| Offline queue | Q1 + Q2 | Q3 |
| Unloader | Same complete | Same complete |
| Weighbridge | split (loader+unloader) | Usually unloader_both |
Field steps
- 1Foreman: Site starter → assign supervisor only → Start site → Loading.
- 2Driver: site detail → Create trip without loader → pick product + equipment → confirm.
- 3Trip goes directly to driving (no loading status from loader).
- 4Transport; unloader completes as in 8.1.1 (chainage/GPS; weighbridge if configured).
Outcomes
| ID | Condition | Result | Recovery |
|---|---|---|---|
| DNL-1 | Online, valid product + truck | driving → unloaded | - |
| DNL-2 | Flag off | Cannot start without loaders | Enable flag or use 8.1.1 |
| DNL-3 | No supervisor | Start site disabled | Assign supervisor |
| DNL-4 | No equipment on driver | Validation error | Link truck on project |
| DNL-5 | Active trip today | 403 / warning | Complete or exception existing |
| DNL-6 | Offline create | Q3 queued | Sync when online |
| DNL-7 | Offline, never cached trucks | Cannot pick equipment | Go online once first |
For yards without phones at the loading point, office generates a printed QR from site detail. Driver scan creates and accepts the trip in one step.
Prerequisites
- Site exists and is Loading (or ready for field).
- Office generated Loader paper QR from site detail (payload includes paper marker).
- QR printed and posted at loading point.
- Driver assigned to site / project.
Office - generate & print
- 1Open site detail → Loader paper QR section.
- 2Generate QR (product/place encoded as configured).
- 3Print and post at the physical loading point.
- 4Rotate / regenerate old prints when products or site change.
Field - driver scan
- 1Driver scans paper QR (no loader phone).
- 2Backend creates new trip + accepts → driving.
- 3Unloader completes as standard (8.1.1 E).
| Phone loader QR | Paper QR | |
|---|---|---|
| Trip creation | Loader scanQRCode first | Created on driver scan |
| Who shows QR | Loader app | Printed sheet |
| First status | loading then driving | driving immediately |
| Offline | Q1 + Q2 | Q2 with encryptedData |
Outcomes
| Issue | Result | Fix |
|---|---|---|
| Stale / wrong print | Reject or wrong product | Regenerate from site detail |
| Site not Loading | Create blocked | Foreman start site |
| Offline scan | Queued accept | Sync Q2 (8.1.6) |
When a site has 2+ product places, each place can have its own loader running parallel independent trips.
- 1Office: site links multiple places per product (or multiple products/places).
- 2Foreman Site starter: assign one loader per place (+ supervisor, drivers, unloaders).
- 3Start site → Loading.
- 4Each loader opens their place context and generates independent QR → separate trip rows.
- 5Drivers must scan the QR from their assigned loader/place (wrong place QR = wrong product/place on trip).
- 6Unloaders complete each trip independently (chainage/GPS as usual).
| Scenario | Result |
|---|---|
| Two loaders online in parallel | Two loading trips; two driver accepts |
| One place offline | That loader’s Q1 only; other place unaffected |
| Foreman changes loader mid-day | New QR uses new loader; in-flight trips keep original |
| Driver scans wrong place QR | Trip tied to that place - train drivers to match |
Numeric codes sit alongside QR for poor connectivity, verbal confirmation, or sites that require a second factor. Codes expire (~2 minutes typical) - regenerate by re-showing QR or re-accepting per safety rules.
| Code | Role | When shown | Typical use |
|---|---|---|---|
| Loader verification code | Loader | After scanQRCode | Driver enters if camera fails |
| Driver verification code | Driver | After acceptTrip | Unloader / foreman confirm |
| Unloader verification code | Unloader | On car row before complete | Foreman / office audit |
When to use codes vs QR only
- QR-only: good connectivity, standard visual handoff (8.1.1).
- Codes: backup when camera fails, bright sun, or process requires spoken confirmation.
- Expired codes: UI shows expired - regenerate; do not reuse old screenshots.
- Deployments may allow skipping codes - then QR-only path applies.
Mobile queues failed mutations locally. When back online, Work → Sync all uploads them in a defined order. Weight fields, evidence URLs, and GPS travel with offline payloads when present.
| Queue | What was offline | API action | Optimistic UI |
|---|---|---|---|
| Q1 - Pending creations | Loader generated QR; scanQRCode never reached server | scanQRCode replay | QR shown / loading local |
| Q2 - Pending accepts | Driver accepted QR offline | acceptTrip replay | Accepted / driving local |
| Q3 - Pending driver trips | Driver created trip without loader offline | driverCreateTrip replay | Loaded card |
| Q4 - Pending completes | Unloader completed offline | completeTrip / closeFromOfflineChain | Unloaded local |
Sync algorithm
- 1User taps sync badge on Work (must be online).
- 2Pass 1: Q1 creations → Q2 accepts → Q3 driver trips → Q4 completes.
- 3Pass 2: retry failures caused by ordering (e.g. accept before create landed) - ties to buffered accept 8.1.7.
- 4Refresh cached site data (up to ~15 sites per project).
- 5If N failed: stay online, sync again, or contact support with timestamp and queue names.
Idempotency & guards
- alreadyAccepted / alreadyCompleted treated as success.
- Duplicate / abuse guards may block or flag repeated offline payloads.
- Unloader-first offline chains can embed loader+driver payloads (closeFromOfflineChain).
- ICT handoff offline uses pendingHandoffLink - sync separately after local trip is ready.
When a driver scans before the loader trip reaches the server (loader offline, driver online), the accept may be stored in pending_offline_events instead of failing permanently.
- 1Loader offline: shows QR locally; trip sits in Q1.
- 2Driver online: scans QR → server may buffer accept (not a second trip).
- 3Loader syncs Q1 → trip created on server.
- 4Next sync/pass applies buffered accept → driving.
- 5Unloader proceeds as usual once driving exists on server.
| Case | Meaning | |
|---|---|---|
| Buffer applied | Normal race - not fraud; trip ends driving | |
| Hard reject | Invalid payload / wrong driver after create | Fix and rescan |
| Offline equivalent | Q1 + Q2 ordering on device (8.1.6) | Same end state |
Foreman or coordinator can change personnel while the site is Loading.
- 1Site detail → remove driver from site personnel or change assignment.
- 2Add new driver from the project member pool (must already be a project member with equipment if required).
- 3Optionally reassign loaders per place the same way.
- 4In-flight trips (loading/driving) keep the original driver until complete or exception.
- 5New loader QR / create-trip flows use only the newly selected driver.
When a delivery goes wrong, the driver flags an issue; the foreman classifies; office approves or rejects. Exception trips are excluded from product totals until approved with a report value.
NONE → issue_reported → pending_approval → approved
↓ (reject)
issue_reported (foreman may re-classify)| Status | Product contribution | Who acts next |
|---|---|---|
| NONE | Normal quantity | - |
| issue_reported | 0 (excluded) | Foreman classifies |
| pending_approval | 0 | Office approves/rejects |
| approved | Snapshotted reportValue (−1, 0, or +1) | Done |
| After reject | Back to issue_reported | Foreman again |
Exception types & report values
| exceptionType | reportValue | Trip status after approve |
|---|---|---|
| returned_to_loading | 0 | Unchanged (e.g. stays driving) |
| wasted_wrong_place | −1 | Unchanged - can reduce product totals |
| reached_intended | +1 | → unloaded (+ endTime if missing) |
| new_useful_location | +1 | → unloaded |
Full loop
- 1Driver reports issue on own trip only (non-drivers forbidden).
- 2Foreman sees banner on site/trip - must match site foremanId for that company.
- 3Foreman POST resolve with exceptionType → pending_approval.
- 4Office (owner, sys_admin, project_manager, product_manager, office_engineer, site_engineer) approves or rejects on web.
- 5Approve applies reportValue; reject clears classification back to issue_reported.
Outcomes
| ID | Scenario | Result |
|---|---|---|
| EX-1 | Approve reached_intended | Trip unloaded; +1 contribution |
| EX-2 | Approve wasted_wrong_place | Status unchanged; −1 contribution |
| EX-3 | Reject | issue_reported; foreman re-classifies |
| EX-4 | Loader tries report | Forbidden |
| EX-5 | Pending on dashboard | Excluded from KPI totals until decided |
| EX-6 | Approve + equipment report | Per-trip equipment report for that calendar day |
Office engineers correct trips and site data after field work without re-running mobile QR flows.
Where to work
| Location | Path | Capabilities |
|---|---|---|
| Site detail | /dashboard/projectsHome/[id]/sites/[siteId] | Trip table, edit trip, stats, generate report |
| Dashboard | /dashboard | KPIs refresh after trip changes |
| Products report | /dashboard/products-report | Material totals after edits |
| Trip issues panel | Site / trip exception UI | Approve/reject 8.1.9 |
Post-trip actions
- 1Refresh site trip table after field complete - unloaded visible.
- 2Edit trip (quantity, times, plate, locations) for data-entry errors.
- 3Change trip status manually if stuck (e.g. driving → unloaded).
- 4View site statistics; Generate site report when segment complete.
- 5Second generate when report exists - handle report-exists messaging.
- 6Mark site Done when work finished.
- 7For material went wrong place: prefer exception approval over silent quantity edits.
| ID | Situation | Office action | Field impact |
|---|---|---|---|
| OE-1 | Wrong tonnage | PATCH quantity | Reports recalculate |
| OE-2 | Stuck driving | PATCH → unloaded | Mobile refresh shows update |
| OE-3 | Exception pending | Approve in panel | Status + reportValue (8.1.9) |
| OE-4 | Edit after report | Edit + may regenerate | Per product rules |
| OE-5 | Stale KPIs | Reload dashboard | Metrics match |
GPS captured at load, accept, and complete feeds automated compliance. Trips may show needs checking until approved. Chainage validation on LINEAR is separate but part of unload compliance.
Capture points
| Event | Role | Typical fields | Purpose |
|---|---|---|---|
| Load start | Loader | loaderLat/Lng in scanQRCode | Prove load location |
| Accept | Driver | driverLat/Lng in acceptTrip | Handoff location |
| Complete | Unloader | unloaderLat/Lng + chainage (LINEAR) | Unload vs site rules |
LINEAR (CENTERLINE)
- Loader: vs loading reference (LOADING place GPS or chainage-derived point).
- Driver unload: vs alignment point at unloadedChainagePoint.
- Unloader: vs same alignment point.
- Typical radius ~100 m (place geofence where configured).
AREA (polygon + places)
| Case | Loader / driver-load | Driver unload / unloader |
|---|---|---|
| AREA + DELIVERY | LOADING place (point + radius) | Inside site polygon |
| AREA + DISPOSAL pickup-only | Inside site polygon | PASS if no dump selected |
| AREA + DISPOSAL with dump | Inside site polygon | DISPOSAL place geofence |
“Site polygon” = site boundary if set, otherwise project boundary. Buffer default ~20 m (meters converted to degrees for WGS84 - never buffer by “20 degrees”).
Statuses & outcomes
| Status / ID | Meaning |
|---|---|
| unloaded | Field complete |
| needs checking | GPS/rule mismatch; office review |
| approved | Passed auto or manual review; compliance reports |
| GPS-1 | All coords valid → may auto-approved |
| GPS-2 | Chainage out of range → complete blocked |
| GPS-3 | Location denied → weak/flagged trip |
| GPS-4 | needs checking on dashboard |
| GPS-5 | Approved trips feed equipment report scores |
- Field: allow location; enter correct chainage (LINEAR); work inside drawn zones (AREA).
- Office: monitor needs checking; use trip tools / cron.
- Deep UI detail: GPS trip verification section under Reports.
Prerequisite: company feature weighbridge_weights. Product must have a weight measurement type (camera OCR, manual scale, ticket OCR, kg or tonnes). Site may have a weighbridge profile (digit layout, decimals, unit, capacity, mismatch %).
With loader - mode split
Loader → WeightCaptureDialog (OCR/manual + evidence if required)
→ QR includes weight fields (s/t/u/v)
→ Driver scans → DRIVING
Unloader → One weighbridge reading + unload evidence
→ complete with unloaderWeight + GPS/chainage
Server → netWeight + quantity; optional weightMismatchFlag- 1Loader selects driver/car → if product weighbridge enabled, open weight dialog before/with QR.
- 2Scan ROI + consensus (camera types) or enter manual; Accept stores gross + optional photo.
- 3Driver transport unchanged.
- 4Unloader after scan: one gross capture → complete.
No loader - mode unloader_both
Driver → Creates trip without loader (8.1.2)
Unloader → First gross → “Load dropped?” confirm → second gross
→ complete with weightCaptureMode=unloader_both
Server → netWeight + quantity; optional mismatch flagServer net & quantity
| Product type | Signed net | Stored netWeight | quantity |
|---|---|---|---|
| DELIVERY | loader − unloader | |signed| (always ≥ 0) | netWeight / weightUnitsPerProductUnit or kg↔t |
| DISPOSAL | unloader − loader | |signed| | same conversion |
- Negative signed net (inverted readings) still stores absolute netWeight and sets weightMismatchFlag.
- Readings beyond site mismatch tolerance % also set weightMismatchFlag.
- quantity is in the product unit (m³, ton, …); scale unit stays on weight fields/profile.
- Reports: if netWeight set → prefer trip quantity; else legacy car size - see Weighbridge & quantity.
- Offline: weight + evidence + confidence travel with complete/sync chain.
Goal: Project exists, materials defined, sites created, people assigned - before field work begins. Do this once per project; adjust sites as segments open.
| Step | Who | Where (web) | Done when |
|---|---|---|---|
| A1 Log in (phone → Telegram code) | Engineer / admin | /login → /dashboard | JWT + company context |
| A2 Switch company if multi-tenant | Admin | Header company dropdown | Correct companyId on token |
| A3 User Management: add workers | HR | /dashboard/CompanyUsers | Phones can log in |
| A4 New project (LINEAR CSV/map · AREA polygon) | Engineer | /dashboard/projectsHome | Project card visible |
| A5 Add Products (DELIVERY / DISPOSAL) | Engineer | Project detail | Units + targets set |
| A5b Optional weighbridge | Engineer | Product weight type + units relation | Weight UI appears in field |
| A6 Product places (chainage or GPS) | Engineer | Product places dialog | Places linked for sites |
| A7 Project members (drivers + equipment) | Engineer | Add/Manage users | Mobile Work lists project |
| A8 Manage Sites - geometry, dates, products, flags | Engineer | Project detail | Sites Not Started |
| A8b Optional ICT lane | Engineer | /dashboard/inter-company | Active trade lane |
| A9 Site detail - foreman, times, paper QR, profile | Engineer | .../sites/[siteId] | Ready for Phase B |
Detailed order for a new LINEAR project
- 1Create project from CSV or map points - verify chainage range on project card.
- 2Add each material as a product with unit and target quantity.
- 3If weighbridge: set weight measurement type + weightUnitsPerProductUnit when unit is not pure mass.
- 4For DELIVERY: add LOADING places along chainage; optional UNLOADING places.
- 5For DISPOSAL: add DISPOSAL dump places; mark disposal sites later.
- 6Assign all field workers as project members; pick truck plate for each driver.
- 7Create sites: chainage must sit inside project range; link products/places; set allowDriverTripWithoutLoader only if agreed.
- 8Site detail: foreman, average speed, loading/unloading times, optional weighbridge profile, paper QR if needed.
Detailed order for a new AREA project
- 1Confirm company has area_projects; re-login after enabling.
- 2Create AREA project - draw closed boundary polygon.
- 3Add products; for each place enter lat/lng + geofence (no chainage).
- 4Assign project members as above.
- 5Manage Sites - draw site polygon inside project boundary (or whole project area).
- 6Verify site area on dashboard map overlay; GPS verification will use polygon + places.
unloader_both capture - train unloaders before go-live.Phase B - Field start (mobile)
| Step | Who | Where (mobile) | Notes |
|---|---|---|---|
| B1 Log in; allow location & camera | All | Login → Passcode → tabs | Required for QR + GPS |
| B2 Work → open project | Coordinator / roles | Work tab | Empty = not a project member |
| B3 Delivery: Site starter - loaders per place + supervisor → Start | Foreman | Sites list | Needs office site + members |
| B3b No-loader site: supervisor only → Start | Foreman | Sites list | Flag must be on |
| B3c Disposal: pickup loaders + dump unloaders → Start | Foreman | Sites list | May omit supervisor per process |
| B4 Loader: Start loading if needed → site detail | Loader | Loader sites | Only Loading sites listed |
Phase C - Daily operations (mobile)
- 1Loader: pick driver + product; capture weighbridge gross if required; show QR (or use paper QR from web).
- 2Driver: scan QR → driving; or Create trip without loader when flag on; transport; report issues if needed.
- 3Unloader: scan/complete with chainage (LINEAR) or GPS (AREA); capture unloader weight / unloader_both if weighbridge.
- 4Foreman: reassign personnel for new trips only; classify trip issues → pending_approval.
- 5ICT: after sender unloaded, generate partner handoff QR; receiver loader/unloader scans per lane intakeMode.
- 6Offline: when back online, Work → sync badge - uploads Q1→Q4 (and handoff queue if used).
| Step | Who | Where | Why |
|---|---|---|---|
| D1 Dashboard KPIs / recent activity | Management | Web /dashboard | Live pulse |
| D2 Site / product reports + Excel | Engineer / QS | Site Products + products-report | Material progress + weight flags |
| D3 Equipment report + Excel | Office | Sidebar Equipment Report | Driver/machine compliance |
| D4 Nearby Equipment activity | Office | Nearby Equipment click | Per-fleet unit trips |
| D5 GPS needs checking | Engineer | Trip details / dashboard | Approve or investigate |
| D6 Approve trip issues | Backoffice | Exception panel | Applies reportValue ±1/0 |
| D7 ICT reconciliation | Office | Inter-company | Compare origin vs destination weights |
| D8 Generate site report / mark Done | Engineer | Site detail | Close segment |
| D9 Owner usage history | Owner | Mobile Reports | Personal machine trips |
- 1Open /login
Enter phone number in international format as your organization standardizes.
- 2Request code
Backend sends a one-time code; user reads it in Telegram.
- 3Enter 6-digit code
App stores JWT and redirects to /dashboard.
- 4Switch company (if applicable)
Header → Company dropdown → pick company → new token for that company → dashboard reloads.
- 5Logout
Sidebar Logout clears session; use on shared PCs.
Quick actions (large tiles)
- Projects → project list
- Products → products report (not in narrow sidebar)
- Users → Company Users
- Account → account settings
What you see on the dashboard
- Overview cards: total cars, users, projects, active sites.
- Material delivery: each product row - planned vs delivered, progress bar; tap row for product analysis.
- Trip statistics: counts by loading, driving, unloading, unloaded, needs checking, approved.
- Site statistics: not started, loading, done, with/without foreman.
- Recent trips, sites, projects - useful for daily standups.
Route: /dashboard/CompanyUsers - used by HR / admin.
Mode A - By phone (Telegram user)
- 1Open Add User → choose By phone.
- 2Enter country code and phone; fetch preview if offered.
- 3Select role from directory → Save under current company.
Mode B - Without Telegram
- 1Choose Without Telegram - read warning: user becomes Loader_load only; role cannot be changed later.
- 2Enter name, phone, optional username → Save.
- 1Sidebar → Projects (/dashboard/projectsHome).
- 2Search filters project names on the current loaded page (10 per page).
- 3+ New project opens creation dialog.
- 4Export CSV downloads Project Name, Cars, Workers, KPI %, Points, Chainage Range for the current filtered page - paginate if you need all projects.
Prerequisite
Login must have an active company. If the dialog says company is missing, re-login or switch company.
Mode A - Upload CSV
- 1Tab Upload CSV → enter project name.
- 2File must end with .csv.
- 3Required columns: chainage, easting, northing, elevation.
- 4Example row: 13+800,500000.0,1200000.0,1500.5
- 5Submit Create - wait for success - page reloads.
Mode B - From map points
- 1Tab From map points → project name.
- 2Set interval in meters (e.g. 50) for derived chainage along the polyline.
- 3Optional starting chainage: 0+000, 13+800, or plain meters; empty = 0+000 at first point.
- 4Enter at least two points per line as longitude,latitude (WGS84), e.g. 38.123456,9.012345.
- 5Optionally click the map to append points.
- 6Submit Create project.
Route: /dashboard/projectsHome/[id]
Recommended order for a new project
- 1Products - create each material (name, unit, targets).
- 2Product places - for each product, define places along chainage.
- 3+ Add / Manage Users - attach company workers; drivers must pick plate/equipment when required.
- 4Manage Sites - create sites (see next section).
- 5Cars dialog - maintain project vehicles as needed.
Assign existing worker to project
- 1Open + Add / Manage Users.
- 2Select worker from available list.
- 3If role is driver - pick equipment / plate before assign.
- 4Assign to project - confirm row in members table.
Invite by phone from project dialog
- 1Enter country code and phone → fetch preview.
- 2Choose role and status → Save (may create company worker then assign).
- 3Tell user to log in on mobile with same phone.
Open Manage Sites from project detail. For LINEAR projects the dialog shows allowed chainage range. For AREA projects use the map-based site dialog - see AREA projects section.
| Field | Rule |
|---|---|
| Site name | Required |
| Start chainage | e.g. 13+800 - inside project range |
| End chainage | After start - inside project range |
| Start date | Required |
| Allow driver trip without loader | Optional - drivers may create trips without loader QR on this site |
| Products | Tick at least one |
| Places per product | For each ticked product, tick at least one place |
After save, open the site from the table for trip management and reports.
Route: .../sites/[siteId]
Trips table
- Monitor statuses: loading, driving, unloading, unloaded, needs checking, approved.
- Trip issue banners show when driver reported an issue or foreman classified - waiting for backoffice.
- Edit trip fields where permissions allow (quantity, times, plates).
Site settings
- Set foreman / supervisor.
- Average car speed, loading time, unloading time - often required before save.
Loader paper QR
Generate printable QR for yards without phones at the loading point (paper QR creates a new trip on driver scan - see QR scenarios).
Generate report
- 1Check whether a report already exists for the site/day.
- 2Click Generate Report when eligible trips are complete - recalculates equipment-per-trip scores for that calendar day.
- 3Approving a trip issue can run the same logic for that single trip only.
Finish site
When work is truly complete, use the action to set site status Done.
NONE → ISSUE_REPORTED → PENDING_APPROVAL → APPROVED
↘ reject → ISSUE_REPORTED (foreman may re-classify)Step by step
- 1Driver reports issue
Mobile - trip owner flags problem. Status: issue_reported. Excluded from product totals.
- 2Foreman classifies
Mobile or dashboard - picks one of four resolution types. Status: pending_approval.
- 3Backoffice approves or rejects
Dashboard Trip Exception panel on site/project - roles: owner, sys_admin, project_manager, office_engineer, site_engineer.
- 4On approve
reportValue snapshotted from classification. Reached intended / new useful location → trip may become unloaded + per-trip equipment report generated.
- 5On reject
Returns to issue_reported; classification cleared; foreman can submit again.
See Trip issues (exceptions) below for classification values and report impact.
- 1Dashboard quick action → Products (/dashboard/products-report).
- 2View aggregates across projects: target vs current, active trips hints.
- 3Use search and filters.
- 4Click a product for Product analysis - charts, progress, logistics views.
- 5Approved trip issues contribute fixed report values; pending issues contribute zero.
- 1Sidebar → Equipment Report.
- 2Choose date range (calendar).
- 3Select project (required); optionally filter by site.
- 4Optional: Show disposal trips report (kind=disposal vs delivery).
- 5Generate Report → expandable driver → project → site → trip tree.
- 6Download Excel - multi-sheet engineer pack (Summary, Drivers, By Project, By Site, Trip Ledger).
- 1Sidebar → Nearby Equipment - list/filter company + marketplace equipment.
- 2Click a card → equipment activity report (period: today / 7d / 4w / 12m).
- 3Work report KPIs: trips, quantity, average performance, average score + trip list.
- 4Register company fleet (office / product_manager) with images - sets companyId.
- 5Assign fleet unit to a driver from company fleet cards only.
- 1Feature inter_company_trips must be on for both companies.
- 2/dashboard/inter-company - partnerships, trade lanes, handoff status.
- 3CompanyUsers → Partner drivers - receivers registering partner drivers from handoffs.
- 4Field: sender generates handoff QR only after trip is unloaded; receiver scans per lane intake mode.
Full rules under Inter-company trips (ICT) below.
- Install from Play Store or internal channel your company provides.
- If forced update modal appears, install latest build from store.
- Grant camera (QR) and location (nearby projects, trip payloads).
Sign in
- 1Enter phone - app normalizes 09… to 2519…, 9-digit local to 251…, keeps 251… as-is.
- 2Send code → read Telegram → enter 6 digits on passcode screen.
- 3Five tabs appear on success.
- 4Logout: Account → Log out on shared phones.
| Tab | Purpose | Typical roles | Offline notes |
|---|---|---|---|
| Home | Marketplace feed - filters, pagination, detail | Owners / browsers | Cached browse may be limited |
| Work | Projects, QR, sync, ICT handoff | All field roles | Core offline queues live here |
| Add Post | 5-step listing wizard (tab bar hidden) | Owners | Needs network to publish |
| Reports | Owner trip history by date - not favorites | Equipment owners | Needs synced trips |
| Account | Profile, my equipment, nearby, logout | Everyone | Logout clears session |
- Title: Projects - subtitle Online or Offline · using saved data.
- Filter chips: All, Active, Upcoming, Completed (from material progress).
- Sync badge (top right): pending queue count; uploads when online.
- Project cards: name, dates, site count, progress - tap into role UI.
- Pull-to-refresh on site screens after sync or teammate actions.
Role priority (multiple hats)
Mixed assignments filter Work in order: Loader → Driver → Unloader → generic coordinator. Multi-hat users must open the correct project/site path even when the shell looks “loader-first”.
- 1Work → project
Sites list with Active / Done / All.
- 2Not Started - Site starter
Loader per place + supervisor (+ drivers/unloaders). Start when validation passes.
- 3No-loader sites
Flag on → Start with supervisor only (no loader teams).
- 4Disposal sites
Pickup loaders + dump unloaders (disposalPlaceId).
- 5Loading / Done - Site detail
Manage teams; reassign for new trips only (8.1.8).
- 6Classify trip issues
Driver reported → pick exceptionType → pending_approval (must match site foremanId).
- 1Work → project
Loader-assigned projects only.
- 2Loader sites
Loading sites (Start loading if still Not Started).
- 3Site detail
Refresh → driver + product → optional weighbridge → Show QR + loader code.
- 4Regenerate QR
Same load identifier - updates trip, does not duplicate (8.1.1 C2).
- 5Offline strip
Network fail at QR → local Q1 until Work sync.
- 6ICT receiver (loader_scan)
On company B, Scan partner handoff when lane intakeMode is loader_scan.
| Blocker | Fix |
|---|---|
| No location assigned | Foreman assigns loader to a place |
| Driver busy | Pick another driver or finish existing trip |
| No products on site | Office links products/places |
| Weight dialog missing | Enable weighbridge_weights + product weight type |
- 1Driver sites
Cards show progress, pending cars, status.
- 2Scan QR
Loader or paper QR → confirm car → driving (no duplicate).
- 3Transport & codes
Follow site verification-code process.
- 4Report issue
Own trips only → issue_reported for foreman.
- 5Create without loader
Flag on → product + equipment; cache trucks with one online visit first.
- 6ICT handoff QR
After unloaded on sender site → Partner handoff QR for active lane.
- 1Unloading sites
My sites list → site detail (incoming vs unloaded).
- 2Scan / select trip
Correct QR or trip row.
- 3LINEAR complete
Chainage inside site range + GPS.
- 4AREA complete
GPS inside zone / dump place (no chainage).
- 5Weighbridge
split: one gross. unloader_both: first → load dropped → second.
- 6ICT no_loader intake
Scan partner handoff when intakeMode is no_loader.
- 7Offline
Complete → Q4; sync from Work.
Full queue semantics are in 8.1.6. This is the field checklist.
| Action while offline | Queue | After sync |
|---|---|---|
| Loader QR not on server | Q1 creations | Trip loading |
| Driver accepted | Q2 accepts | Trip driving |
| Driver created without loader | Q3 driver trips | Trip driving |
| Unloader completed | Q4 completes | Trip unloaded (+ weights) |
| ICT handoff scan | pendingHandoffLink | Receiver trip + trip_link |
Sync all
- 1Online → Work → sync badge.
- 2Order: creations → accepts → driver trips → completes (may repeat for races).
- 3Refresh cached sites (up to ~15 per project).
- 4alreadyAccepted / alreadyCompleted = success.
- 5If failures remain: stay online, sync again, escalate with queue names + time.
Numeric codes sit alongside QR for poor connectivity or verbal confirmation. See also 8.1.5.
- Loader shows loader verification code with expiry after scanQRCode.
- Driver enters/confirms driver code after accept when required.
- Unloader uses unloader code on car row before complete.
- Expired codes: regenerate via re-show QR / re-accept - do not reuse screenshots.
- Some deployments allow skipping codes → QR-only path.
| Status | Phase | Who acts | Notes |
|---|---|---|---|
| loading | At product place | Loader | After scanQRCode; waiting for driver |
| driving | En route | Driver | After accept or driver-create / paper |
| unloading | At destination | Unloader | Optional intermediate in some UIs |
| unloaded | Field complete | - | Triggers GPS verification eligibility |
| needs checking | Compliance | System / office | GPS/rule mismatch |
| approved | Verified closed | Office / auto | Counts in compliance reports |
| issue_reported | Exception | Foreman | Excluded from product totals |
| pending_approval | Exception | Office | After foreman classify |
PHASE 5 - Office: project, products, places, sites, members (+ weighbridge / ICT flags) PHASE 6 - Office: foreman, speed, times, site flags, weighbridge profile, paper QR PHASE 7 - Foreman: Site starter → teams → Start site (Loading) PHASE 8 - Field scenarios 8.1.1–8.1.12 (QR / no-loader / paper / offline / WB / …) PHASE 9 - Office: GPS check, trip issues, Excel reports, site Done ICT extra - A unloaded → handoff QR → B trip → B unloaded
End-to-end journey map
| Journey | Office setup | Field path | Final state |
|---|---|---|---|
| P-01 Standard delivery | Project, site, members, foreman | Loader QR → driver → unloader | unloaded |
| P-02 Paper QR | Generate paper QR on site detail | Driver scan paper → unloader | unloaded |
| P-03 Driver without loader | Enable no-loader flag | Supervisor start → driver create → unloader | unloaded |
| P-04 Multi-place | 2+ places on site | 2 loaders, parallel trips | 2× unloaded |
| P-05 Offline day | Same as P-01 | Queue Q1–Q4 → Sync all | unloaded after sync |
| P-06 Weighbridge | Feature + product weight type | split or unloader_both capture | unloaded + netWeight |
| P-07 Exception loop | - | Report → classify → approve | approved + reportValue |
| P-08 ICT handoff | Partnership + trade lane | A unload → handoff → B complete | two unloaded trips |
| QR type | Behaviour | Trip status after |
|---|---|---|
| Standard loader QR | Decrypt → find trip → acceptTrip | loading → driving |
| Paper QR (r: paper) | Creates trip + accept in one scan | driving immediately |
| Driver without loader | No QR - driverCreateTrip API | driving immediately |
| Legacy QR without identifier j | Fallback: LOADING trip by loader + product | driving |
| QR includes tripId | Updates that specific trip | driving |
| Weighbridge fields s/t/u/v | Loader gross carried in QR payload | driving (+ weights) |
| ICT handoff (t: handoff) | Receiver handoff-link → new trip on B | B driving; A stays unloaded |
| Non-paper loader QR, no trip yet | Error or buffer (8.1.7) - never duplicate create | - |
| Step | Actor | Status after |
|---|---|---|
| Normal trip | - | NONE |
| Driver flags issue | Driver | ISSUE_REPORTED |
| Foreman classifies | Site foreman (project_sites.foremanId) | PENDING_APPROVAL |
| Backoffice approves | Dashboard role | APPROVED + reportValue set |
| Backoffice rejects | Dashboard role | ISSUE_REPORTED (classification cleared) |
ISSUE_REPORTED, PENDING_APPROVAL: excluded from product totals (contribution 0). APPROVED: uses snapshotted reportValue.
| Classification | Report value | Trip status on approve |
|---|---|---|
| Material returned to loading site | 0 | Unchanged |
| Material wasted at wrong place | −1 | Unchanged |
| Material reached intended site | +1 | → unloaded (+ endTime if missing) |
| Material unloaded at new useful location | +1 | → unloaded (+ endTime if missing) |
- On approve for +1 outcomes: per-trip equipment report runs (same logic as Generate Report for that day, that trip only).
- reportGenerated = true on the approved trip.
- Foreman can re-classify until backoffice approves or rejects.
- 1Mobile Reports tab - pick start/end date.
- 2Equipment list with trip counts for range.
- 3Tap equipment → trip list with times, locations, quantity.
- 4Web office uses dashboard + equipment report + site generate-report instead.
Econ runs automatic GPS verification after a trip reaches unloaded. The goal is to confirm that load and unload actions happened in the right place - either along a LINEAR alignment (chainage) or inside an AREA site zone polygon. Scenario framing: 8.1.11 above.
When verification runs
- Runs periodically for trips with status unloaded and not yet checked.
- Writes per-role results to the trip: loader/driver/unloader GPS checks plus an overall tripStatus label.
- Office sees the badges in Trip Details; mobile sees them as informational.
LINEAR projects (alignment / chainage)
LINEAR verification uses the survey parquet (from the project CSV) as the source of truth.
- Loader: loader GPS is compared to the selected LOADING product place (point + radius or chainage-derived point).
- Driver (unload): driver unloading GPS is compared to the survey point at the unloaded chainage.
- Unloader: unloader GPS is compared to the same survey point at the unloaded chainage.
- Typical radius: ~100m (configurable via place geofence where applicable).
AREA projects (closed polygon sites)
AREA verification combines product places (where loading happens) with the site polygon (where unloading must occur).
| Case | Loader + Driver load checked against | Driver unload + Unloader checked against |
|---|---|---|
| AREA + DELIVERY product | LOADING place (point + geofence radius) | Site zone polygon (inside boundary) |
| AREA + DISPOSAL product (pickup-only) | Site zone polygon (pickup must be inside) | PASS when no dump destination is selected |
| AREA + DISPOSAL product (known dump) | Site zone polygon (pickup must be inside) | DISPOSAL dump destination place (point + geofence radius) |
GPS capture points
| Event | Role | Fields captured | Checked against |
|---|---|---|---|
| Load start | Loader | loaderLat, loaderLng | LOADING place or site polygon (by product type) |
| Accept / load | Driver | driverLat, driverLng | Same as loader for AREA DELIVERY |
| Unload complete | Driver | driverUnloadingLat, driverUnloadingLng | Site polygon or chainage point |
| Unload complete | Unloader | unloaderLat, unloaderLng | Site polygon or chainage point |
Per-role outcomes
| Result | Meaning | Office action |
|---|---|---|
| pass | GPS within allowed zone/geofence | No action - informational badge |
| fail | GPS outside expected zone | Trip may show Loader/Driver/Unloader Location Issue |
| skip | No GPS captured for that role | Informational - not treated as pass |
Verification statuses on trip
- unloaded - field work complete.
- needs checking - GPS rule mismatch; awaiting review.
- approved - passed automated or manual review; counts in compliance reports.
- tripStatus labels: verified, loader_red, driver_red, unloader_red, etc.
Spatial buffer (AREA polygons)
Polygon checks use a tolerance buffer (default 20m). DuckDB converts meters to degrees for WGS84 - otherwise far-away points could incorrectly pass.
Company feature weighbridge_weights must be enabled before weight UI and APIs appear. Without it, trips stay on the normal QR path with no weight dialog.
- 1Enable weighbridge_weights on the company (ops / company_feature); re-login so JWT includes the flag.
- 2On each product: choose a weight measurement type - weighbridge camera, manual scale, axle/portable camera, ticket OCR (kg or tonnes variants).
- 3Set weightUnitsPerProductUnit when the product unit is not pure mass (example: 1800 kg per 1 m³). Leave blank for automatic kg↔ton conversion.
- 4On the site: optionally open Weighbridge profile - digit count, decimal places, unit, capacity min/max, mismatch tolerance %.
- 5Train field: split (with loader) vs unloader_both (no-loader sites).
| Config | Effect if missing / wrong |
|---|---|
| Feature off | No weight UI/API - normal trips only |
| No weight type on product | Product treated as non-weighbridge |
| Wrong units relation | quantity conversion wrong in reports |
| Mismatch % too tight | Many weightMismatchFlag trips |
| Migrations not applied | Project/trip API errors on weight columns |
Loader gross ──┐
├── signedNet (by product type) → netWeight = |signedNet|
Unloader gross ┘
→ quantity = convert(netWeight → product unit)
→ weightMismatchFlag if inverted or beyond tolerance %split (loader present)
- 1Loader opens WeightCaptureDialog (OCR ROI consensus or manual entry).
- 2Accept stores loader gross (+ evidence photo when requiresCamera).
- 3QR carries weight fields; driver accepts normally.
- 4Unloader captures one gross + evidence → complete with GPS/chainage.
unloader_both (no-loader sites)
- 1Driver creates trip without loader (site flag on).
- 2Unloader: first gross → confirm “Load dropped?” → second gross.
- 3Complete with weightCaptureMode=unloader_both.
| Product type | Signed net formula | Reporting |
|---|---|---|
| DELIVERY | loader − unloader | Prefer trip quantity when netWeight set |
| DISPOSAL | unloader − loader | Same; IN/OUT reports use product type |
- Inverted readings still store absolute netWeight and set weightMismatchFlag.
- Beyond site mismatch tolerance % also flags the trip for QS follow-up.
- Offline: weight, evidence URLs, and confidence travel with the complete/sync payload.
- Office product reports show weight flags; Excel export includes them.
Move material from Company A (sender) to Company B (receiver) without merging tenants. Each side keeps its own trip; a trip_link ties them after the sender trip is unloaded. Feature key: inter_company_trips.
| Rule | Meaning |
|---|---|
| Two trips | Sender trip stays in A; receiver trip is created in B |
| Sender unloaded first | Handoff QR only valid when sender status is unloaded |
| One-shot link | One sender trip → one receiver trip (unique senderTripId) |
| Feature both sides | inter_company_trips enabled for A and B |
| Active partnership + lane | company_partnership + inter_company_link active |
| Receiver never closes sender | Linking does not change sender unload GPS / endTime |
A: loading → driving → unloaded → handoff QR B: scan handoff → receiver trip DRIVING → unloader completes on B Shared: trip_link (+ optional partner driver on B)
Ops scenario catalog
| ID | Scenario | Outcome |
|---|---|---|
| ICT-01 | Enable feature both companies | Inter-company UI + APIs |
| ICT-02 | Partnership request / approve | company_partnership active |
| ICT-03 | Configure trade lane | Sites/products + intakeMode |
| ICT-04 | Sender completes local trip | A unloaded |
| ICT-05 | Generate handoff QR | Encrypted t=handoff token |
| ICT-06 | Receiver loader_scan | B trip + partner driver auto-registered |
| ICT-07 | Receiver no_loader | B trip; driver may stay external |
| ICT-08 | Rescan already linked | Idempotent same receiver trip |
| ICT-09 | Unloader completes on B | B unloaded |
| ICT-10/11 | Partner drivers UI | List by origin; status active/blocked |
| ICT-12 | Reconciliation | Compare origin vs destination weights |
| ICT-13 | Offline handoff scan | pendingHandoffLink then sync |
| ICT-14 | Guard failures | Clear reject; no partial link |
- 1Enable inter_company_trips on A and B; refresh token so sidebar Inter-company and Users → Partner drivers appear.
- 2A requests partnership with B; B approves → status active (pending / suspended block new links).
- 3Create trade lane (inter_company_link): sender company/site/product → receiver company/site/product.
- 4Set intakeMode: loader_scan (receiver loader scans; preferred) or no_loader (receiver unloader scans).
- 5Optional: weightTolerancePct for reconciliation; handoffTokenTtlHours (default 48h); status active/paused/closed.
- 6Office paths: /dashboard/inter-company; partner drivers under CompanyUsers.
| Lane field | Meaning |
|---|---|
| Sender site / product | Where the load finishes on A |
| Receiver site / product | Where the linked trip is created on B |
| intakeMode | Who on B is allowed to scan the handoff QR |
| weightTolerancePct | Flag when origin vs destination net disagree |
| handoffTokenTtlHours | QR expiry window |
Sender (Company A)
- 1Run a normal local trip to unloaded (any 8.1.x path - GPS/weighbridge/exceptions unchanged).
- 2Driver (or authorized sender field user) opens Partner handoff QR / HandoffQRDialog.
- 3Select active lane (or auto-pick if one); server validates feature, partnership, lane, unloaded, not linked elsewhere.
- 4Show encrypted QR (t: handoff, link id, expiry, plate, sender company name, net weight, …).
Receiver loader_scan (Company B)
- 1Loader on receiver site scans handoff QR + GPS.
- 2Server resolves actor as loader on B (multi-company safe).
- 3Auto-register partner driver on B when resolvable: same userId, role driver, registrationSource=inter_company_handoff, originCompanyId=A; assign site driver + project member.
- 4Create receiver trip DRIVING + trip_link; sender stays unloaded.
- 5Unloader on B completes receiver trip normally.
Receiver no_loader
- 1Unloader on B scans handoff QR.
- 2Receiver trip created DRIVING (driverId may be null).
- 3Complete unload on B as usual.
Failures & guards
| Check | If fail |
|---|---|
| Feature off either side | Reject |
| Partnership / lane inactive | Reject |
| Sender not unloaded | Reject |
| Already linked to other receiver | Reject |
| Already linked to same receiver | Idempotent - return existing trip |
| Wrong actor for intakeMode | Forbidden |
| Token expired | Receiver scan fails |
| Offline scan | Queue pendingHandoffLink; sync later |
On site detail → Products section. Totals prefer weighbridge quantity when netWeight is set; otherwise legacy car size.
| Entry | Contents | Export |
|---|---|---|
| Product tile → detail | KPIs expected/actual/remaining, unloaded details | - |
| View report (product) | Summary, per vehicle, by day, trip ledger, weekly, weight flags | Excel (.xlsx) |
| View products report (section) | All products, weekly, IN vs OUT, per vehicle, by day, ledger, flags | Download Excel |
- IN vs OUT: DISPOSAL product type = OUT; otherwise IN (delivery).
- weightMismatchFlag trips surface in the flags view for QS follow-up.
- Excel: ECON-branded workbook via ExcelJS (navy #002347 + orange #FF8E00), embedded icon, frozen headers, filters.
- Pending trip issues contribute 0 until approved; approved use snapshotted reportValue.
Aggregate engineer compliance: /dashboard/equipment-report. Per-machine activity: Nearby Equipment card click.
- 1Select date range (single day or range).
- 2Select project (required), site (optional).
- 3Optional: Show disposal trips report (kind=disposal vs delivery).
- 4Generate Report → expandable driver → project → site → trip tree (GPS checks, codes, red flags).
- 5Download Excel - multi-sheet engineer pack.
| Excel sheet | Purpose |
|---|---|
| Summary | Period, filters, KPI block (+ disposal totals when applicable) |
| Drivers | Per driver + plate: trips, score, verification breakdown |
| By Project / By Site | Rollups |
| Trip Ledger | Flat review: product, route, GPS, codes, flags, scores |
Nearby Equipment activity dialog
- Periods: Today / last 7 days / last 4 weeks / last 12 months.
- Work report KPIs: trips, quantity, average performance, average score.
- Trip list: product, quantity, times, route, project/site.
- Matching: equipmentId on trip or matching plateNo when fleet plate is set.
Owner / marketplace (mobile & field web)
- 1Home: browse equipment with filters.
- 2Add Post: 5 steps - category, type, specs, up to 4 images, details (phone required).
- 3Account: profile, my equipment, update location for nearby features.
- 4Reports: usage and trips per machine (not the web Hearted placeholder).
| Type | How created | companyId | Assignment |
|---|---|---|---|
| Personal equipment | Driver/mobile Add Post | null - owner userId | Project member link / personal trucks |
| Company fleet | Nearby Equipment → Register (images required) | active company | Assign-to-driver on fleet cards only |
- Nearby click opens equipment activity report - not marketplace-only detail.
- Assignment uses project_driver_equipments (project-scoped).
- Field prefers assigned plate, then personal trucks; unassigned fleet is not shown to all drivers.
- List scope for drivers: personal (companyId null) OR current company fleet.
| Role | Tool | Main tasks |
|---|---|---|
| Office / engineers | This web dashboard | Projects, sites, reports, trip review, user management |
| Foreman | Mobile Work | Start site, assign loaders, classify trip issues |
| Loader | Mobile / field web | Start loading, QR handoff, verification codes |
| Driver | Mobile / field web | Accept trips, transport, report issues |
| Unloader | Mobile / field web | Verify arrival, complete unloading |
| Equipment owner | Mobile / field web | List equipment, usage reports, notify interest |
- Phone + Telegram one-time code for web and mobile.
- Web: JWT in browser storage, company-scoped token, ~24h session guard with refresh.
- Mobile: long-lived session in device storage with refresh on 401.
- RBAC: dashboard areas (users, trip approve, reports) depend on company role keys.
- Multi-company: switch company on web header only.
| Symptom | Likely cause | What to try |
|---|---|---|
| Web login no code | Phone not registered / Telegram bot | Admin checks worker; start bot; retry |
| Cannot create project | Missing companyId on token | Re-login; switch company |
| Site save fails (LINEAR) | Chainage outside range; no places | Fix chainage; add product places |
| Site save fails (AREA) | Polygon outside project boundary | Redraw site inside project map |
| Add place fails (AREA) | chainagePoint required error | Enter lat/lng instead - chainage not used on AREA |
| GPS all pass but wrong location | AREA trip used CENTERLINE mode | Ensure project type AREA; re-run verification |
| Loader pass, unloader fail (AREA) | Unload GPS outside site polygon | Check site boundaryGeoJson matches field location |
| Mobile no projects | Not project member | Office assigns on project |
| Work shows Offline | Network; cached list | Coverage; sync when online |
| Loader list empty | Only Loading sites shown | Foreman must start site |
| Driver cannot create trip | Site flag off | Office enables allow without loader |
| No weight dialog on loader | Feature off or no weight type on product | Enable weighbridge_weights; set product type |
| weightMismatchFlag on trip | Inverted or out-of-tolerance readings | Recheck scale; review in product report flags |
| ICT handoff QR rejected | Sender not unloaded / no lane / feature off | Complete sender; check partnership + lane |
| Sync failures | Bad queued payload | Retry; capture time for support |
| Web Hearted empty | Placeholder route | Use dashboard reports |
Can one person be loader on one project and driver on another?
Yes on server; mobile Work shows loader view if any assignment is loader (see role priority).
Where are favorites on mobile Reports tab?
Reports tab is equipment usage history, not favorites (internal name Hearted).
Who creates the site?
Geometry and products on web; starting site for field work is usually mobile foreman.
Can drivers work without loaders?
Only if office enabled Allow driver to create trip without loader on that site.
What is the difference between LINEAR and AREA?
LINEAR uses chainage along a centerline. AREA uses map polygons and GPS coordinates for places and site zones. See Project types section.
Do I need chainage on AREA projects?
No. Sites show area (m²) instead of chainage. Product places require latitude and longitude.
What happens if GPS verification fails?
Trip shows fail badges per role. Office reviews in Trip Details. Field should allow location permission and work inside the defined site zone or loading place.
When does weighbridge appear on mobile?
Company feature weighbridge_weights must be on, and the product must have a weight measurement type. Without that, trips stay on the normal QR path with no weight dialog.
How do inter-company (partner) trips work?
Sender completes to unloaded, then generates a handoff QR. Receiver scans it to create their own trip. Tenants stay separate - linked by trip_link. Both companies need the feature and an active trade lane.
Web
- /register does not submit - use User Management.
- Main /hearted is not office analytics.
- Projects status filter may be incomplete server-side.
- CSV export is current page only.
Mobile
- Forced update if store version ahead of app check.
- Role priority can confuse loader+driver users.
- Driver-create-trip offline needs one online session to cache equipment list.