HOS Segment Architecture

packages/orion-hos · orion-amqp-events · orion-public-api

HOS Segment Architecture

How a duty-status event captured on the ELD tablet becomes an HosEventLog row, and how that row fans out into timers, violations, AMQP broadcasts, and the externally-built “segment” that powers the driver recap UI.

Read first

There is no Segment or HosSegment table or Eloquent model anywhere in this repo. The system of record is hos_event_log. A “segment” (a continuous span of one duty status) is a derived projection built outside Orion: HosSegmentDispatchSqsListener publishes just {guid, recordStatus} to an SQS queue, and an external, Elasticsearch-backed denormalizer service looks up the full event and builds the segment.

A second, unrelated meaning of “segment” also exists in this codebase: the FMCSA/CCMTA compliant export file is assembled from named file sections — headerSegment(), eldEventListSegment(), driverCertificationSegment(), etc., in FileOutput.php. Same word, different concept — called out on the diagram.

Data flow & architecture

Solid arrows are write/event flow; dashed arrows are read paths, a synchronous direct call, or a terminology note (labelled individually).

SOURCES INGESTION SYSTEM OF RECORD FAN-OUT QUEUES / DERIVED STORES EXTERNAL DENORMALIZER CONSUMING SURFACES ELD Tablet device-auth routes on-device calc Driver / Co-driver App user-auth routes events, annotations, UDT Back Office Portal orion-clientweb event.store Tenant Manager external system admin OAuth scope Not a “Segment” FileOutput.php builds the FMCSA/CCMTA export from its own file "segments" (header, event list, certification…) — unrelated concept. HosEventRepository::save() resolves driver/co-driver/tablet/cvd · validates edits · inserts event packages/orion-hos/src/app/Repositories/HosEventRepository.php HosTimersController POST .../timers (tablet- computed, on-device calc) tablet on-device calc HosEventLog — hos_event_log duty status · GPS lat/lng · odometer · engine hours · power_unit_number · vin user/co_user/terminal/carrier/tablet/cvd ids · malfunction & diagnostic codes guid · origin_guid · record_status · record_origin · certified_utc · checksum one row per event · a “segment” is a continuous span of duty-status rows, computed downstream packages/orion-hos/src/app/Models/HosEventLog.php hos_daily_timers legacy, tablet-computed recap (pre-segment path) via HosDailyTimerJob HosEventLogCreated · HosImportedLogCreated · AnnotationCreated · HosEventLogFixed HosSegmentDispatchSqsListener Listeners/ · publishes {guid, recordStatus} BroadcastHosEventLog Listeners/ · only Active, or edited duty status EntityStateSearch Observer Observers/ · upserts user entity-state on every save HosTimerJob Jobs/ · sync call, not a listener · Tenant Mgr path only SQS: hos-segment queue denormalizer-queue-url (SSM) AMQP topics hos_event_log · hos_timers ES entity-state index USER_TYPE hos_timers via Kotlin HOS Calculator hos_violations pivot: hos_timers_hos_violations External Segment Denormalizer outside orion-hos · looks up the event by guid, Elasticsearch-backed “Segment” derived · continuous duty-status span keyed by event guid Recap UI driver page · <hos-recap-table> Fleet / Asset views current duty status, last vehicle Enterprise systems AMQP consumers Back-office reporting Service API · ES search repos · violations Tablet / app reads Public API v2 · events, logs, timers, status POST /hos/device/v2/event POST /hos/event, /v2/event event.store POST /hos/duty_status insert HosEventLog row HosDailyTimerJob {guid, recordStatus} hos_event_log key duty_status, last_vehicle Kotlin calculator violation detection lookup event by guid build / index recap table data violation dashboards reads: Service API / ES search reads: Public API v2
The amber lane (HosEventLog → SQS → external denormalizer → “Segment” → Recap UI) is the path this diagram exists to explain: everything a “segment” is built from lives in this repo, but the segment itself does not. The dashed red box calls out a same-word, different-concept usage in the ELD export job. Dashed grey lines are reads or a synchronous (non-listener) call, each labelled.

What's captured on an HosEventLog event

Every write funnelled through HosEventRepository::save() carries this shape — it's the raw material the external denormalizer reads to build a segment.

Identity & provenance

guid / origin_guidevent identity; edits chain back via origin_guid
sequenceordering within a day
record_statusdraft · active · changed · change-requested · change-rejected
record_originELD-recorded · edited-by-driver · edited-by-office · unidentified-driver
event_type / event_codeduty status, intermediate log, certification, engine, diagnostic…
certified_utc / checksumcertification back-fill target · ELD integrity check

Who & where

user_id / co_user_iddriver & co-driver
terminal_id / carrier_idLocation records
tablet_id / cvd_idDevice records
latitude / longitudeplus location_description/city/state/country
timestampsevent time in UTC, terminal-local, and offset

Vehicle & hours

power_unit_number / vinthe truck
odometer_total(_decimal) / elapsedplus distance & unit_of_measure
engine_hours_total / elapsedengine runtime
malfunction_code / diagnostic_codeELD self-monitoring

Duty status

duty_status.code/namemachine_name + duration_seconds
driver_indicationdriver-asserted status
edit_reasonrequired on office/driver edits
activities[] / annotations[]hasMany HosActivityLog / HosAnnotation

File reference

Where each box on the diagram lives in the repo.

HosEventLogpackages/orion-hos/src/app/Models/HosEventLog.php
HosEventRepository::save()packages/orion-hos/src/app/Repositories/HosEventRepository.php
HosSegmentDispatchSqsListenerpackages/orion-hos/src/app/Listeners/HosSegmentDispatchSqsListener.php
HosSegmentForceDeleteSqsClientpackages/orion-hos/src/app/Clients/HosSegmentForceDeleteSqsClient.php
HosTimerJobpackages/orion-hos/src/app/Jobs/HosTimerJob.php
EntityStateSearchUpsertHosEventLogClientpackages/orion-hos/src/app/Clients/EntityStateSearchUpsertHosEventLogClient.php
HosEventLogBroadcasterpackages/orion-amqp-events/src/app/Broadcasters/HosEventLogBroadcaster.php
HosViolationpackages/orion-hos/src/app/Models/HosViolation.php
FileOutput (ELD export “segments”)packages/orion-hos/src/app/Jobs/ELD/FileOutput.php