Skip to content

Apply vehicle-type-specific thresholds across all demo pipelines when region or vehicle type changes #33

@sfc-gh-obielov

Description

@sfc-gh-obielov

Background / Context

The ORS Control App exposes a region picker and a vehicle-type switcher. Changing the vehicle type currently updates the CONFIG.VEHICLE_TYPE column in six skill schemas, which only filters the projection views over SYNTHETIC_DATASETS.UNIFIED. Downstream analytical thresholds (SLA, geofence, route deviation, H3 granularity, speeding) remain hardcoded and vehicle-agnostic, producing unrealistic demo results (e.g. an HGV loading dock judged against the same SLA as an e-bike restaurant pickup).

The data generation engine (server/studio/profiles.ts) already encodes realistic per-vehicle parameters, but none of these values are reflected in the SQL pipelines that analyze the generated data.

User Story

As a demo presenter
I want vehicle-type selection to automatically apply realistic per-vehicle thresholds across every demo
So that switching from taxi to e-bike to HGV produces operationally plausible SLA alerts, geofence behaviour, deviation flags, and congestion heatmaps.

Acceptance Criteria

AC-1: Vehicle-aware threshold reference table exists

  • A new table VEHICLE_THRESHOLDS is created in every skill schema that currently has a CONFIG table (6 schemas: DWELL_ANALYSIS, ROUTE_DEVIATION, FLEET_INTELLIGENCE_TAXIS, FLEET_INTELLIGENCE_FOOD_DELIVERY, RETAIL_CATCHMENT, ROUTE_OPTIMIZATION).
  • The table is pre-seeded for all supported vehicle types (car, ebike, hgv) so no row-level mutations are required when the vehicle type changes.
  • All objects include the required COMMENT tracking tag per AGENTS.md.

AC-2: Dwell analysis uses vehicle-aware SLA thresholds

  • DT_SLA_ALERTS joins VEHICLE_THRESHOLDS on VEHICLE_TYPE = (SELECT VEHICLE_TYPE FROM CONFIG LIMIT 1) AND LOCATION_TYPE.
  • Switching vehicle type in the UI changes the warning/critical minute thresholds applied to open dwell sessions (verified via reading DT_SLA_ALERTS before and after the switch).

AC-3: Dwell analysis uses vehicle-aware geofence radii

  • GEOFENCE_POLYGONS CTAS uses the GEOFENCE_RADIUS_M column from VEHICLE_THRESHOLDS instead of the current hardcoded IFF(LOCATION_TYPE = 'WAREHOUSE', 200, 100) logic.
  • HGV gets larger buffers than e-bike (per values in the Threshold Matrix below).

AC-4: Route deviation threshold is vehicle-aware

  • route-deviation/references/seed-data.sql hardcoded 20% deviation check is replaced by a lookup against VEHICLE_THRESHOLDS.DEVIATION_PCT.
  • HGV deviation flag fires at 10% while e-bike deviation flag fires at 25%.

AC-5: Live Operations UI reads threshold from DB

  • .cortex/skills/build-routing-solution/openrouteservice_app/services/ors_control_app/src/components/dwell/LiveOperations.tsx no longer hardcodes 30 minutes.
  • The SLA threshold used in the live dashboard comes from VEHICLE_THRESHOLDS for the currently active vehicle type.

AC-6: Vehicle-type switch endpoint works end-to-end

  • POST /api/fleet-config/vehicle-type updates CONFIG.VEHICLE_TYPE in all 6 skill schemas (existing behaviour preserved).
  • After the call completes, downstream DTs refresh with thresholds appropriate to the new vehicle type (within one DT refresh cycle: 5-10 minutes).
  • A new endpoint GET /api/fleet-config/thresholds returns the currently active vehicle's threshold values for display in the UI.

AC-7: Documentation and cleanup

  • Each affected skill's SKILL.md has a ## Thresholds section documenting the per-vehicle-type values.
  • AGENTS.md is updated to note the new VEHICLE_THRESHOLDS pattern.
  • Cleanup sections in affected skills include DROP TABLE VEHICLE_THRESHOLDS.

Proposed Data Model

CREATE TABLE VEHICLE_THRESHOLDS (
    VEHICLE_TYPE        VARCHAR NOT NULL,          -- 'car' | 'ebike' | 'hgv'
    LOCATION_TYPE       VARCHAR NOT NULL,          -- 'WAREHOUSE' | 'DESTINATION' | 'REST_STOP' | 'STORE' | 'DETOUR' | '*'
    SLA_WARNING_MIN     NUMBER,
    SLA_CRITICAL_MIN    NUMBER,
    GEOFENCE_RADIUS_M   NUMBER,
    DEVIATION_PCT       NUMBER(5,2),
    SPEED_LIMIT_FACTOR  NUMBER(3,2),
    H3_RESOLUTION       NUMBER(2),
    PRIMARY KEY (VEHICLE_TYPE, LOCATION_TYPE)
) COMMENT = '{"origin":"sf_sit-is-fleet", ...}';

Threshold Matrix (Required Seed Values)

SLA Thresholds (minutes: WARNING / CRITICAL)

Location Type Car E-Bike HGV
WAREHOUSE 8 / 20 5 / 12 30 / 90
DESTINATION 5 / 15 3 / 8 20 / 60
REST_STOP 10 / 25 5 / 15 45 / 90
STORE 3 / 10 2 / 6 15 / 45
DETOUR 3 / 8 2 / 5 5 / 15

Geofence Radii (meters)

Location Type Car E-Bike HGV
WAREHOUSE 150 80 300
DESTINATION 80 50 200
REST_STOP 120 60 250
STORE 80 40 200
DETOUR 80 50 200

Global Vehicle-Level Thresholds (LOCATION_TYPE = '*')

Parameter Car E-Bike HGV
Deviation % 15 25 10
Speed limit factor 1.10 1.05 1.05
H3 resolution 8 9 7

Files to Modify

# File Change
1 .cortex/skills/dwell-analysis/references/seed-data.sql Add VEHICLE_THRESHOLDS DDL + inserts for all vehicle types
2 .cortex/skills/dwell-analysis/references/sql-pipeline.sql GEOFENCE_POLYGONS and DT_SLA_ALERTS JOIN VEHICLE_THRESHOLDS
3 .cortex/skills/route-deviation/references/seed-data.sql Add table, replace hardcoded 20% with lookup
4 .cortex/skills/fleet-intelligence-taxis/references/seed-data.sql Add table (speed factor)
5 .cortex/skills/fleet-intelligence-food-delivery/references/seed-data.sql Add table (speed + delivery SLA)
6 .cortex/skills/retail-catchment/references/seed-data.sql Add table (stub, future use)
7 .cortex/skills/route-optimization/references/seed-data.sql Add table (stub, future use)
8 openrouteservice_app/services/ors_control_app/src/components/dwell/LiveOperations.tsx Replace hardcoded 30 with DB lookup
9 openrouteservice_app/services/ors_control_app/server/index.ts Add GET /api/fleet-config/thresholds endpoint
10 .cortex/skills/dwell-analysis/SKILL.md Document Thresholds section
11 .cortex/skills/route-deviation/SKILL.md Document Thresholds section
12 AGENTS.md Document VEHICLE_THRESHOLDS pattern

Out of Scope

  • H3 resolution per vehicle type is deferred. Dynamic Tables cannot use subqueries inside H3_POINT_TO_CELL_STRING(). Implement a fixed compromise (R8) for now; parameterize in a follow-up ticket once a stored-procedure DT rebuild pattern is agreed.
  • Region-specific overrides (e.g. London vs rural region): tracked in a separate ticket.
  • escooter vehicle type is referenced in the UI but has no profiles.ts template; threshold seeding for it is deferred until the profile exists.
  • Auto-sync between profiles.ts and VEHICLE_THRESHOLDS: manual for now.

Test Plan

  • Deploy dwell-analysis skill, verify VEHICLE_THRESHOLDS exists with rows for car/ebike/hgv.
  • Switch vehicle type to HGV in UI; verify DT_SLA_ALERTS uses HGV thresholds (warehouse warning = 30 min, not 5 min).
  • Switch vehicle type to E-Bike; verify GEOFENCE_POLYGONS uses 80m warehouse buffer (not 200m).
  • Switch to HGV; verify route-deviation flags trips with >10% deviation (not >20%).
  • Verify LiveOperations.tsx SLA count changes when vehicle type changes.
  • Verify GET /api/fleet-config/thresholds returns the current vehicle's values.
  • Run python3 .cortex/skills/evals/run_evals.py to confirm no skill eval regressions.
  • Run cleanup workflow; verify VEHICLE_THRESHOLDS tables are dropped.

Open Questions

  1. Should escooter ship with a best-guess threshold set or be explicitly unsupported until a profiles.ts template exists?
  2. Should thresholds be region-aware in this iteration, or strictly vehicle-aware?
  3. Should UI show a "Thresholds in use" panel so demo presenters can see what changed?

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions