fix(build-routing-solution): warning banner separate from build-failed error#116
Merged
Conversation
…rquet
Adds simplified region polygons (~100m tolerance) and ISO 3166-1/-2 codes
to REGION_CATALOG so downstream consumers (function tester, synthetic data
generators, H3 matrix builder, control-app map) can replace bbox sampling
with real-shape ST_WITHIN filtering and stop hitting water / out-of-graph
points.
- New build_boundaries.py bakes all 460 catalog rows in one pass:
* 222 Geofabrik rows resolve their .poly clip mask (the EXACT polygon
used to cut each .osm.pbf extract -> 1:1 match with the ORS routing
graph). ~32s wall-clock, cached locally for re-runs.
* 238 BBBike rows use bbox-as-polygon (BBBike clips PBFs rectangularly,
so bbox is the true boundary).
* Coverage: 460/460 boundaries, mean 97 vertices/region post-simplify.
- New columns on REGION_CATALOG: LOOKUP_NAME, ISO_COUNTRY_A2,
ISO_COUNTRY_A3, ISO_SUBDIVISION, UN_M49, BOUNDARY (GEOGRAPHY),
BOUNDARY_SOURCE, BOUNDARY_VERTICES, BOUNDARY_AREA_KM2, BOUNDARY_BAKED_AT.
All nullable -> server-side dynamic catalog refresh keeps working.
- LOAD_SEED_CATALOG COPY transform extended with TRY_TO_GEOGRAPHY of the
WKB hex column.
- New REGION_REGISTRY_V view joins REGION_REGISTRY -> REGION_CATALOG via
ORS_REGION_KEY and exposes BOUNDARY + ISO codes; falls back to bbox when
no catalog row exists for a manually-added region.
- manual_iso_overrides.json provides an escape hatch for regions whose
country / subdivision name doesn't auto-resolve via pycountry.
Parquet size: 6 KB -> 1.05 MB. ISO country coverage: 196/460 (covers all
single-country Geofabrik rows; BBBike cities + multi-country Geofabrik
aggregates remain null and can be filled via overrides as needed).
…, and helper UDFs SQL-only changes that consume the BOUNDARY column shipped in the previous commit (REGION_CATALOG seed parquet). No service rebuilds needed. Matrix pipeline (05_matrix_pipeline.sql) - BUILD_HEXAGONS: enumerate H3 cells inside REGION_CATALOG.BOUNDARY instead of the bbox rectangle. Drops water cells before any ORS Matrix call. Falls back to bbox polygon when no catalog row is found. - BUILD_HEXAGONS_ROAD_AWARE: keep the Overture native bbox prefilter (it's a partition prune; removing it would scan the global table) but refine via ST_INTERSECTS against the actual region polygon, dropping foreign-country road segments that bleed across the bbox. Final hex centroid clip uses ST_WITHIN(centroid, BOUNDARY) instead of bbox BETWEEN. Multi-country bboxes (Israel-Palestine, Germany-Austria-Switzerland, Malaysia-Singapore-Brunei) see 25-30% null hex rate drop to <5% with this change. Routing functions (02_routing_functions.sql) - New REGION_FOR_POINT(lon, lat) UDF returns OBJECT with the smallest containing region (region_name, ISO codes, area). Enables auto-pick from user-pasted lat/lon, fact-table region tagging, cross-region drift detection, and LLM-coordinate validation. - New POINT_IN_REGION(lon, lat, region) BOOLEAN UDF for binary checks. - New ISOCHRONES_CLIPPED(method, lon, lat, range, region) returns isochrone polygons clipped to BOUNDARY via ST_INTERSECTION so retail catchment zones and address-density estimates don't claim foreign territory or water. - New SAMPLE_ADDRESSES_FOR_REGION(region) returns MAP_CONFIG.sample_addresses filtered to those inside the region's actual boundary (catches curated addresses that drifted out of region). Retail catchment seed (retail-catchment/references/seed-data.sql) - RETAIL_POIS Overture POI loader: keep bbox prefilter, add polygon refine via subquery against REGION_CATALOG.BOUNDARY. - REGIONAL_ADDRESSES loader: same pattern. All new functions/queries fall through gracefully when REGION_CATALOG has no boundary for a region (use bbox or skip the filter).
…er, and fallbacks Frontend + server-side consumers of the BOUNDARY column shipped earlier. Code-only - control-app Docker image rebuild is required for the frontend changes to take effect at runtime, but no SQL/data changes are needed. Frontend (control app) - src/hooks/useRegion.ts: extend RegionInfo + RegionContextValue with BOUNDARY_GEOJSON, BOUNDARY_SOURCE, BOUNDARY_BAKED_AT, BOUNDARY_CENTROID_*, ISO_COUNTRY_*. Default map center now prefers boundary centroid (always on land) over CENTER_LAT/LON. Boundary cache-bust uses BOUNDARY_BAKED_AT. - src/components/function-tester/samplePoints.ts: new randomPointInBoundary() rejection sampling using a JS point-in-polygon implementation (handles Polygon + MultiPolygon, holes). Threaded through sampleOne, sampleWith Separation, sampleDirections/Isochrones/Matrix/MatrixTabular/Optimization, and the entry point samplePoints(). Falls back to bbox after 50 attempts. - src/components/FunctionTester.tsx: pass region.boundaryGeoJson to samplePoints(). - src/components/FleetDataStudio.tsx: keep hard-coded SF/Germany bbox as last-resort default with a comment pointing at REGION_CATALOG.BOUNDARY. Server (control app) - server/index.ts /api/regions: LEFT JOIN REGION_CATALOG via ORS_REGION_KEY -> LOOKUP_NAME and project ST_ASGEOJSON(BOUNDARY) + ISO codes + centroid. - server/studio/engine.ts loadPOIs: keep bbox prefilter (partition prune), add ST_INTERSECTS(GEOMETRY, rc.BOUNDARY) refine. Falls through (TRUE) when catalog has no boundary for the region. - server/studio/routes.ts: replace hard-coded SF bbox fallback with COALESCE cascade: REGION_REGISTRY -> REGION_CATALOG -> SF default. Routing agent (deploy-agent.sql + agent-definitions.md) - TOOL_DIRECTIONS: validate every LLM-extracted coord via REGION_FOR_POINT before calling DIRECTIONS. Returns detected_regions + out_of_region_count in the failure path so the agent can produce friendly errors like "Cambridge geocoded to Cambridge MA, did you mean Cambridge UK?" instead of a silent ORS RouteNotFound. - TOOL_ISOCHRONE: same validation + uses ISOCHRONES_CLIPPED so the isochrone polygon is trimmed to the detected region's boundary. - agent-definitions.md: short summary, point at deploy-agent.sql for canon. Docs (available-functions.md) - New "Region Boundary Helpers" section showing the new UDFs/UDTFs (REGION_FOR_POINT, POINT_IN_REGION, ISOCHRONES_CLIPPED) plus example patterns for filtering Overture POIs and H3 hexagon coverage by polygon.
- build_boundaries.py docstring: when to re-run + commit workflow - server/index.ts parseBBBikePoly: inline comment pointing at the offline bake script for full polygon support; bbbike rows are bbox by design
Re-running 05_matrix_pipeline.sql against an account where the four filter columns (ROAD_FILTER, HEXAGONS_BEFORE_FILTER, HEXAGONS_AFTER_FILTER, FILTER_DURATION_SECONDS) already exist aborted with: SQL compilation error: ambiguous column name 'ROAD_FILTER' at the standalone ALTER TABLE ... ADD COLUMN IF NOT EXISTS statement (line 24). This is a Snowflake bug: ADD COLUMN IF NOT EXISTS + DEFAULT clause does not reliably no-op when the column exists; it raises a compile-time error. Aborting line 24 also blocked every downstream proc creation (BUILD_HEXAGONS, BUILD_HEXAGONS_ROAD_AWARE, BUILD_MATRIX_JOB_WRAPPER, etc.) which is why the boundary-aware matrix changes from the previous PR could not be applied via snow sql -f and required direct CREATE PROCEDURE calls. Fix: - Move the four columns into the canonical CREATE TABLE IF NOT EXISTS block so fresh installs never run the buggy ALTER path. - Replace the four standalone ALTERs with EXCEPTION-wrapped anonymous blocks via EXECUTE IMMEDIATE, which swallow the compile error so legacy tables (created before the columns were canonical) still get backfilled, and re-runs against modern tables proceed silently. Verified end-to-end: snow sql -f re-runs cleanly twice in a row. Confirmed 21 columns on MATRIX_BUILD_JOBS and both boundary-aware procs intact.
…+ LEFT JOIN Snowflake error 002031 (Unsupported subquery type) was thrown because the loadPOIs query used a correlated scalar subquery passing the outer table's GEOMETRY column into ST_INTERSECTS(). Rewrite as a CTE that pre-fetches the region boundary once, then LEFT JOIN + plain predicate. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…mpletion The header region/vehicle-type switcher always showed "San Francisco" even after Data Studio generated datasets for other regions (Germany, California), because the generation flow only wrote to SYNTHETIC_DATASETS.UNIFIED.* and never propagated the new region into REGION_REGISTRY or the per-skill CONFIG tables. Changes: - jobs.ts: After a job COMPLETED, MERGE the new region into REGION_REGISTRY using REGION_CATALOG.BOUNDARY (Geofabrik polygon) when available, falling back to a telemetry-derived bbox polygon. Center/bbox derived via ST_CENTROID / ST_XMIN / ST_YMAX so maps pan to a real on-land centroid instead of (0, 0). Then call SET_ACTIVE_REGION and update all 6 CONFIG schemas so projection views immediately filter to the freshly generated (region, vehicleType). - index.ts: Replace the synthetic-region 0,0 fallback in /api/regions with a catalog-aware query that resolves geometry from REGION_CATALOG (preferred) or telemetry bbox (fallback). Add BOUNDARY_GEOJSON to the synthetic path for parity with the main query. - index.ts: On server boot, hydrate activeRegionOverride from REGION_REGISTRY.IS_DEFAULT so the user's last selection survives container restarts (previously it reset to null and fell back to the seeded default). - index.ts: Wire setRegionActivatedHandler so Data Studio completion can refresh the in-memory override without waiting for the next /api/regions call. - ors_control_app_service.yaml: Bump image to v1.0.181. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
Move build_boundaries.py and manual_iso_overrides.json from datasets/region_catalog/ to scripts/region_catalog/. Datasets folder now only holds installer-consumed seed artifacts; helper/maintainer scripts live under scripts/. - Add scripts/README.md documenting the convention - Update docstring path reference inside build_boundaries.py - Update comment in ors_control_app/server/index.ts PARQUET_PATH still resolves correctly (parents[2] = repo root). No installer or runtime path is affected.
…tion The header region/vehicle-type dropdowns each filtered options by the OTHER axis using datasetPairs. When the only valid pair for both axes was the current selection (e.g. CONFIG=(ebike, SanFrancisco) but FACT_TRIPS also has (hgv, California) and (hgv, Germany)), the user was deadlocked: the region dropdown showed only SanFrancisco, the vehicle dropdown showed only ebike, and there was no path to the other 2 datasets. Changes: - RegionSwitcher.tsx: stop hard-filtering. Render every region in data.regions; compute validRegions only for visual styling. On click, auto-switch vehicleType to a valid one for the picked region first. - VehicleTypeSwitcher.tsx: same pattern. Render every type in availableTypes; compute validTypes only for visual styling. On click, auto-switch region to a valid one for the picked type first. - index.html: add CSS for .region-option--no-data (dimmed) and .region-tag.autoswitch (warm-color tag showing the auto-switch target). - ors_control_app_service.yaml: bump image to v1.0.182. UX: hovering a "no-data" option shows a tooltip "Switches vehicle type to HGV" so the auto-switch is signaled before the click. Clicking still works and lands on a valid (region, vehicleType) pair. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…erage Closes the silent bbox-fallback gap that affected California (and any other region missing from REGION_CATALOG). The catalog now contains: - 555 Geofabrik regions (full tree: continents, countries, sub-regions, sub-sub-regions) - up from 222 - 4,401 Natural Earth admin-1 polygons (every US state, BR/IN/MX state, every admin-1 globally) - new SOURCE='natural-earth' - 238 BBBike cities (unchanged) Total: 5,194 rows, all with non-null BOUNDARY (was 460). Critical insight: Geofabrik does NOT split US/Brazil/India into states, so California, Texas, SaoPaulo, etc. previously fell through the COALESCE in BUILD_HEXAGONS to bbox - leaking hexes across NV/OR/Pacific. Natural Earth admin-1 supplement closes that gap. BUILD_HEXAGONS and BUILD_HEXAGONS_ROAD_AWARE now log to TRAVEL_MATRIX.MATRIX_BBOX_FALLBACK_WARNINGS whenever no catalog row matches P_REGION, replacing the silent fallback. REGION_CATALOG.PBF_URL relaxed to nullable (NE rows have no PBF). New scripts in scripts/region_catalog/: - expand_geofabrik_subregions.py - crawls live index-v1.json - supplement_natural_earth.py - admin-1 from NE GeoJSON - build_boundaries.py - now also derives bbox from polygon .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
When switching from Germany to California (or other regions), demo pages
sometimes appeared not to refresh. Investigation showed the API call did
reach the server (CONFIG was correctly updated), so the issue is either
React state propagation or a visual data-quality illusion (California's
synthetic dataset has SF coordinates).
Changes:
- App.tsx: Add `?debug=1` status pill in header showing live regionName,
vehicleType, and center. Lets users (and us) see in real-time whether
context state is actually changing.
- App.tsx: Add `key={regionName|vehicleType}` to demo components
(FleetTaxis, FleetDelivery, DwellAnalysis, RouteDeviation, RouteOptimization,
RetailCatchment). React fully remounts the component on region/vehicleType
change - sidesteps any subtle context-update edge cases (stale closures,
throttled re-renders, ref-equality memos).
- RegionSwitcher.tsx / VehicleTypeSwitcher.tsx: Add pulsing animation +
"..." suffix while a switch is in flight, so users get immediate visual
confirmation that the click was received.
- index.html: Add @Keyframes pulse-glow for the trigger button.
- FleetOverview.tsx / DeliveryDashboard.tsx: Stop auto-panning the map to
the data centroid after a fetch. The boundary-based center from useRegion
is authoritative; auto-panning to data masked region mismatches (e.g.
California-tagged points landing in SF).
- ors_control_app_service.yaml: Bump image to v1.0.183.
Note: The boundary-based ST_WITHIN filter on projection views is held back
to a future iteration. The debug pill will tell us in 30s whether the
remount fix is sufficient (state propagation issue) or whether we also
need the boundary filter (data quality illusion).
.... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code)
Co-Authored-By: Cortex Code <noreply@snowflake.com>
…mator Polygon-aware cost estimator changes (server cost-estimate endpoint, /api/matrix/regions, MatrixBuilder.tsx, types.ts) landed in 8769605. This commit aligns the deployed image tag with the redeployed service in Snowflake (built + pushed + suspend/alter/resume completed). Estimator now reads REGION_CATALOG.BOUNDARY_AREA_KM2 and uses the actual polygon (not the bbox rectangle) for hex/pair/credit estimates, so previews match what BUILD_HEXAGONS will produce. California estimate drops from ~580k km^2 (bbox) to ~410k km^2 (polygon). .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
… dropdowns
The two separate region and vehicle-type header dropdowns were confusing:
cross-filter deadlock locked users into the current combo, and region
names didn't map to what the user generated in Data Studio (e.g.
"California" showed SF-area data because the synthetic dataset was
generated with SF bounding box).
Replace both dropdowns with a single DatasetPicker that shows completed
Data Studio generation jobs (presets) directly. Each entry displays:
- Preset name (e.g. "DE - HGV Logistics")
- Region + ORS profile as secondary labels
- Trip count
- Active indicator
Clicking an entry atomically sets both region and vehicle type in all 6
CONFIG schemas + REGION_REGISTRY, then the key={dataKey} remount fires
to refresh all demo pages.
Changes:
- server/index.ts: New GET /api/datasets endpoint returning completed
GENERATION_JOBS joined with REGION_REGISTRY for display names, with
ORS profile -> vehicle type resolution and active flag.
- src/shared/DatasetPicker.tsx: New unified dropdown component.
- src/App.tsx: Replace <VehicleTypeSwitcher /> + <RegionSwitcher /> with
<DatasetPicker /> in header.
- ors_control_app_service.yaml: Bump to v1.0.184.
.... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code)
Co-Authored-By: Cortex Code <noreply@snowflake.com>
…m errors in MatrixBuilder
Server returns {status:'launched', warning:'...'} when implied pairs exceed
625M (recommends LARGE/XLARGE warehouse). Previously the client treated
data.warning identically to data.error and showed it under a red
'Build failed:' banner, even though the build had successfully launched.
Add a separate buildWarning state and a yellow .warning-banner component
labeled 'Heads up:'. Only data.error now sets buildError.
Ships the warning vs error separation in MatrixBuilder. Image built and pushed to OPENROUTESERVICE_APP image registry; service redeployed via suspend -> spec update -> resume.
Data Studio's checkOrsReadiness() called ORS_STATUS() with no argument,
which always queries the default ors-service. When the user picks a region
whose dedicated ORS service is running (e.g. ors-service-california) but
the default service is suspended, generation aborted with "ORS service is
not running" before even attempting to start.
Fix: pass the region from GenerationConfig and use the 1-arg
ORS_STATUS('<region>') overload so the gateway routes the status check to
the correct per-region service. Mirrors the same fix already applied in
engine.ts and jobs.ts:waitForOrsReady (data-studio-region-arg-fix-2026-05-13).
Bump image to v1.0.185.
.... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code)
Co-Authored-By: Cortex Code <noreply@snowflake.com>
…_PROFILE GET /api/datasets was deriving vehicleType from ORS_PROFILE_TO_VEHICLE_TYPE map (driving-car -> car), ignoring the job's stored CONFIG:vehicleType. This caused the DatasetPicker to write VEHICLE_TYPE='car' to CONFIG tables when the actual FACT_TRIPS data had VEHICLE_TYPE='hgv', resulting in 0 trips shown in Fleet Taxis for California. Now reads CONFIG:vehicleType::STRING from GENERATION_JOBS first, falling back to ORS_PROFILE derivation for legacy jobs without the field. Deployed as ors_control_app:v1.0.186. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…STRY Centralizes bbox resolution in routes.ts:resolveRegionBbox so any registered region (California, France, Spain, ...) gets the correct full boundary, regardless of preset_id vs rawConfig path or what the client sends. Removes hardcoded Germany/SF fallbacks in FleetDataStudio.tsx and the SF default in routes.ts. Throws a clear error if region isn't in REGION_REGISTRY/CATALOG. Previously, picking a built-in template (HGV Logistics, City Taxis, etc.) with a non-Germany region sent rawConfig with a hardcoded SF bbox, causing data to be generated within SF only. California is the most visible victim but every region except Germany was affected. Deployed as ors_control_app:v1.0.187. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
Route Deviation pages were stuck showing the original SF e-bike data because the 3 ETL output tables (TRIP_DEVIATION_ANALYSIS, DRIVER_DEVIATION_SUMMARY, DAILY_DEVIATION_TRENDS) were created as static base tables. Switching CONFIG region/vehicle_type had no effect because the static tables never refreshed. Convert all 3 to Dynamic Tables (lag=5min, refresh_mode=AUTO, warehouse=ROUTING_ANALYTICS) matching the dwell-analysis pattern, so they auto-refresh whenever CONFIG or upstream FACT_TRIPS change. Update SKILL.md, references/seed-data.sql, and references/sql-pipeline.md. In-place migration on the live system: dropped the 3 stale tables and recreated as DTs. Verified showing 665 California rows under the active CONFIG (hgv/California). .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…ith 10 jobs and 3 vehicles
Add three thin views (VW_IDLE_TRAILERS, VW_LANE_DEMAND, VW_TRAILER_COST_OF_IDLENESS) reusing dwell-analysis DTs to detect non-moving trailers, score cost of idleness, and surface demand terminals for repositioning. Brand-neutral framing applies to long-haul carriers, container lines, leasing operators, cold-chain 3PLs, and rail intermodal.
…e and VROOM repositioning New /asset-velocity page renders idle-trailer KPIs, deck.gl map, sortable Action Alerts table, and modal AI rationale via SNOWFLAKE.CORTEX.COMPLETE (claude-sonnet-4-5). Optimize Repositioning button calls OPENROUTESERVICE_APP.CORE.OPTIMIZATION (driving-hgv profile) to compute reposition routes from idle trailers to top demand terminals. Page guards on missing dwell-analysis DT and renders an empty-state pointer if not deployed.
…a engine Adds an optional ghost_trailer config block (default 10% of HGV fleet, 5-7 day window starting in the first 2 days of generation). Tagged vehicles skip trip + per-day idle emission inside the window and emit a single multi-day IDLE dwell at their home POI with sparse 5-15 min ping cadence. The dwell sessionizer rolls these into one continuous session, populating VW_IDLE_TRAILERS with realistic >7d idle entries so the Asset Velocity demo can run at the production 168h threshold.
New demo skill that solves trailer-to-load assignment as a fleet-wide VRP via OPENROUTESERVICE_APP.CORE.OPTIMIZATION. Internal-first priority encoded as VROOM priority, ADR via skills, direction-to-home via vehicle end. Includes deterministic Python codegen for demo data, AISQL notebook, schema contract, productisation notes, and Cortex Agent YAML. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
Adds the Backload Matching React component (live data from FLEET_INTELLIGENCE.BACKLOAD_MATCHING.* views, OPTIMIZATION call, DIRECTIONS for empty legs with cache, Cortex rationale card, PROPOSAL_DECISIONS write-back, inline Decisions Audit panel). Sidebar entry under Solution Accelerators next to Asset Velocity. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…ter matrix build The auto-resize block in BUILD_MATRIX_JOB_WRAPPER bumped ROUTING_ANALYTICS to LARGE/X-LARGE for hex_count > 5000/25000 and was supposed to restore the captured original size after BUILD_WORK_QUEUE. The captured-size block silently swallowed errors by setting original_wh_size := NULL, and both restore paths were guarded by IF (original_wh_size IS NOT NULL), so any failure inside the capture block (or a stale captured size from a previous un-restored run) guaranteed the restore would be skipped and the warehouse stranded at the bumped size. Confirmed in account wgb26798 on 2026-05-15: warehouse stuck at X-Large for ~24h after a matrix build. Changes: - Default original_wh_size to 'SMALL' (steady-state) instead of NULL so the restore is always a no-op-or-shrink, never a no-op leaving the warehouse bumped. - Reject LARGE/X-LARGE/2X-LARGE/etc. as a captured "original" (treat as drift from a prior un-restored run and replace with the steady-state default). - Replace null-guard restore with an explicit did_bump BOOLEAN flag so we only restore when we actually changed the size, but original_wh_size always has a sensible value.
…onciler Idempotent safety net for ROUTING_ANALYTICS size drift. Mirrors the existing RECONCILE_AUTO_SUSPEND pattern: if no matrix job is currently PENDING/RUNNING, shrinks ROUTING_ANALYTICS back to the SMALL steady-state. Wired into SUSPEND_ALL_SERVICES so it self-heals on every suspend cycle. Catches the case where a matrix build bumped the warehouse to LARGE/X-LARGE and the in-procedure restore was skipped (e.g. session killed, unhandled exception, parallel matrix jobs racing). Tested in account wgb26798: returns 'already at steady-state: Small' when at SMALL, and 'reconciled: Large -> SMALL' when at LARGE with no active jobs.
Documents the resize of ROUTING_ANALYTICS from X-Large to SMALL, the hardening of the auto-resize block in 05_matrix_pipeline.sql, and the new RECONCILE_WAREHOUSE_SIZE safety reconciler in 04_service_lifecycle.sql.
…ATION call OPTIMIZATION returns 0 rows for Germany coords (server-side VROOM routing issue). Pivoted seed to California cities (OPERATING_COUNTRY='US') where OPTIMIZATION is verified working. Changes: - gen_demo_data.py: US cities (LA, SF, San Diego, etc.) + West-Coast home depots - BackloadMatching.tsx: import useRegion(); sync viewState to preset center; pass regionName as 2nd arg to OPTIMIZATION + 4th to DIRECTIONS; country filter on VW_TRAILERS; drop time_windows; add Solver Log - productisation.md: document Germany OPTIMIZATION known issue .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
The view filtered STATUS LIKE 'DWELL%', silently dropping the multi-day ghost-trailer IDLE sessions emitted by the data engine. As a result the Asset Velocity page showed zero ghost trailers for California (and any region with realistic 5-7d idle synthetic data); only sub-1h DWELL_* sessions made it through, all below the page's default 1h threshold. - VW_IDLE_TRAILERS: WHERE (STATUS LIKE 'DWELL%' OR STATUS = 'IDLE') - AssetVelocity.tsx: default idle threshold 1h -> 72h (matches WATCH band) - Helper subtitle: explain severity bands instead of generic note - Image bumped to v1.0.199, deployed
Replaces the static seed file with a CONFIG-driven projection view pattern matching food-delivery / dwell-analysis / route-deviation. Backload data follows whichever preset the user selects in DatasetPicker. Data Studio changes: - New SYNTHETIC_DATASETS.UNIFIED.FACT_FREIGHT_OFFERS table - engine.ts generateFreightOffers + sourceLabelsForRegion (DAT/Truckstop in US, Timocom/WTransnet in EU) - jobs.ts insertFactFreightOffers, ensureTables DDL, truncate list - jobs.ts FLEET_CONFIG_SCHEMAS includes BACKLOAD_MATCHING - server/index.ts runtime CONFIG_SCHEMAS includes BACKLOAD_MATCHING Backload-matching skill: - references/bootstrap.sql: CONFIG + 3 views (VW_TRAILERS, VW_INTERNAL_VOLUMES, VW_EXTERNAL_OFFERS) filtered by CONFIG row - references/backfill-freight-offers.sql: one-time backfill for existing presets - BackloadMatching.tsx: drop hardcoded OPERATING_COUNTRY filter (CONFIG handles it) - Archived load-demo-data.sql and gen_demo_data.py Verified: California-HGV preset = 27 trailers / 120 internal / 300 external; switching to SanFrancisco-ebike yields 50 trailers (per-preset views work). Deployed v1.0.199. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
Removed orphaned objects that no longer match the live (CONFIG-driven projection-view) architecture: - EXTERNAL_OFFERS_ENRICHED Dynamic Table (source table no longer exists) - SP_SOLVE_REGION_BACKLOAD stored procedure (React builds VRP inline) - TASK_BACKLOAD_RESCAN scheduled task (called the dropped SP) - BACKLOAD_PLAN_HISTORY table (write target of the dead task) Doc updates: - SKILL.md Cleanup section: drop TRAILERS/INTERNAL_VOLUMES/EXTERNAL_OFFERS refs, list only the live views + CONFIG + PROPOSAL_DECISIONS - productisation.md section 3: reposition TASK_BACKLOAD_RESCAN as a future enhancement instead of a shipped fact - agent YAML: replace dropped solve_backload tool with view-reading tools (list_idle_trailers, list_internal_volumes, list_offers, savings_report, explain_decision) No service redeploy required. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…matching The build-routing-solution seed loader populates DIM_POIS / DIM_FLEET / FACT_TRIPS but did not produce FACT_FREIGHT_OFFERS. New customers running load-seed-data.sql got an empty VW_EXTERNAL_OFFERS in backload-matching. Splice a deterministic 300-offers-per-region INSERT after the timestamp offset section (which runs after DIM_POIS is fully loaded) and before LOAD_SEED_MATRIX. Same pattern as the standalone backfill-freight-offers.sql already verified working. Idempotent via WHERE region NOT IN (existing) so re-running the loader is safe. Smoke-tested on fleet_test_evals: 0 rows inserted (both regions already populated). New regions added by Data Studio jobs after v1.0.199 populate this table natively. SKILL.md verification block now lists FREIGHT_OFFERS=300 in the expected counts. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
The full-width container has overflow:hidden, which clipped the Action Alerts table below the 420px map. Asset Velocity uses a normal flow layout (like Route Optimizer, which is not full-width and works fine), so it should use the standard scrollable .app-main container. Image bumped to v1.0.200, deployed.
- Add selectedVehicleId state, reset on region change - focusTrailer callback: setViewState (zoom 14) + scrollIntoView on map - Row onClick wired with cursor:pointer + light blue highlight - AI Rationale button uses stopPropagation - Selected trailer pops on map via wider line stroke + accent color Image v1.0.201, deployed.
VRP hardcoded profile=driving-hgv, but California region only provisioned the driving-car graph. ORS returned rows with empty GEOJSON, so the page silently rendered no routes. - Read ORS_PROFILE from GENERATION_JOBS for the active region - Use that profile in vrpVehicles - Surface "profile: ..." label next to Optimize Repositioning button - Show a warning info-box when solver returns no routable paths Image v1.0.202 deployed.
The Backload Matching page was returning empty optimization results when the underlying ORS routing services were auto-suspended after 4h of inactivity. Adds: - Required-services status pill (N/M ready/warming/suspended) polling SHOW SERVICES every 30s with a green/amber/red dot. - "Wake up ORS" button that resumes any suspended service in parallel and polls until all are RUNNING with target instances (90s budget). - Auto-warm in solve(): if any required service is not RUNNING when the user clicks Solve, the wake-up routine runs first so a user never gets a silent-empty result. Required services tracked: VROOM_SERVICE, ROUTING_GATEWAY_SERVICE, ORS_SERVICE, and ORS_SERVICE_<active region>. The denominator uses the actual number of services found, so presets that use the default ORS_SERVICE (e.g. SanFrancisco) display correctly as 3/3 rather than showing a missing region-specific service as red. Service yaml bumped to v1.0.203 and redeployed. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…ofile, cap dot pixel size - Sync FLEET_INTELLIGENCE.BACKLOAD_MATCHING.CONFIG.REGION from useRegion() on mount/region change so VW_TRAILERS/VW_INTERNAL_VOLUMES/VW_EXTERNAL_OFFERS return data for the active preset (was stuck on SanFrancisco even when app showed California). - Read VEHICLE_TYPE from CONFIG and map ebike->cycling-electric, hgv->driving-hgv, car->driving-car for both VRP profile and empty-leg DIRECTIONS calls (was hardcoded 'driving-hgv'). - Add radiusMaxPixels caps to all three ScatterplotLayer calls so dots no longer become huge meter-radii circles when zoomed in. - Surface red banner when OPTIMIZATION returns 0 rows with diagnostic hints (services suspended, region/profile mismatch). - Bump ors_control_app to v1.0.203.
…, dashes, data quality - Query REGION_PROVISION_JOBS.PROFILES at refetch time to use the actually provisioned ORS profile (e.g. driving-car for California) instead of naively mapping from VEHICLE_TYPE (which would send driving-hgv to a region that only has driving-car graphs). - Fix audit query: CONFIG has flat columns (VEHICLE_TYPE, REGION), not KEY/VALUE rows. Replace broken subquery with EUR_PER_EMPTY_KM constant. - Remove dead CONFIG reads (INTERNAL_PRIORITY, EXTERNAL_PRIORITY, etc.) that silently failed since those columns don't exist. - Add PathStyleExtension import for dashed empty-leg lines (getDashArray was silently ignored without it). - Use r.DURATION instead of r.COST (OPTIMIZATION returns DURATION, not COST). - Remove ORS_SERVICE from requiredServices (only region-specific service needed). - Remove 130 lines of dead German mock data (MOCK_TRAILERS, DE_CITIES, etc). - Recreate VW_INTERNAL_VOLUMES with diversified PRODUCT (5 categories) and some HAZMAT=true rows. - Recreate VW_TRAILERS: strip POI quote chars, vary CURRENT_LOAD (6 cargo types), HAZMAT_CERT (20% true), MAX_PAYLOAD_KG (18-24k range). - Bump ors_control_app to v1.0.204.
…IMIZATION Generic per-region VROOM architecture so OPTIMIZATION works for any provisioned region (California, Germany, USA, future) without hardcoding or per-region code. VROOM image (vroom-docker:v1.0.3): - config.yml templated with __ORS_HOST__ placeholder for all 8 ORS profiles - New docker-entrypoint-region.sh runs sed substitution from $ORS_HOST env var at container startup (defaults to 'ors-service' if unset for backward compat) - Same image serves any region; ORS_HOST env per-service points it at ors-service-<region>. SQL (03_region_management.sql): - BUILD_VROOM_SERVICE_SPEC(P_REGION) function generates the per-region spec. - create_region_vroom_service(P_REGION) procedure mirrors create_region_ors_service: CREATE SERVICE VROOM_SERVICE_<REGION> in ORS_POOL_<REGION> with ORS_HOST env. - drop_region_vroom(P_REGION) for symmetric teardown; called by drop_region_ors. - Wired into PROVISION_REGION_WRAPPER (post-service-ready), REBUILD_REGION_GRAPHS, and the rescue-task path so any region provisioning auto-deploys VROOM. Gateway (routing_reverse_proxy:v1.0.5): - resolve_vroom_host(region) -> vroom-service-<normalized-region>. - get_vroom_response(payload, vroom_host=None) routes per-region; falls back to global VROOM_HOST on connection error. - _handle_optimization_tabular and post_optimization pass vroom_host through. - _remap_indices keeps location/start/end alongside *_index keys so VROOM's internal ORS geometry call has coords (the per-region ORS supports them). App (ors_control_app:v1.0.205): - BackloadMatching.tsx requiredServices now depends on VROOM_SERVICE_<REGION> + ORS_SERVICE_<REGION> + ROUTING_GATEWAY_SERVICE. The base global services are no longer required for solving. Bootstrap: VROOM_SERVICE_CALIFORNIA created and verified end-to-end with statewide OPTIMIZATION (San Diego -> LA -> SF, 4341-point GEOJSON, 32481s). AGENTS.md: documented per-region VROOM lifecycle alongside ORS.
…puted matrices VROOM's vroom-express config had limit:'1mb' which rejected pre-computed distance matrices >1MB. At app scale (27 vehicles + 420 jobs in California Backload Matching) the matrix JSON is ~2.4MB, causing Python requests to surface a ConnectionError, gateway returning connection_failed, and the OPTIMIZATION SQL function flattening 0 rows. Bumping the limit to 50mb safely covers any realistic VRP (VROOM hard caps at 1000 locations -> ~12MB matrix). No memory or runtime impact. Bumped to vroom-docker:v1.0.4 and updated BUILD_VROOM_SERVICE_SPEC. VROOM_SERVICE_CALIFORNIA recreated; verified 27 rows for the full app-scale payload.
…i-region path) After the per-region VROOM architecture, every OPTIMIZATION caller must pass the region as the second argument so the gateway routes to VROOM_SERVICE_<REGION> + ORS_SERVICE_<REGION>. Without it, requests fall through to the legacy global VROOM with the SF-only base ORS graph and fail for any non-SF data. Updated callers: - RouteOptimization.tsx: pass regionName from useRegion() - AssetVelocity.tsx: pass regionName from useRegion() - routing-agent TOOL_ROUTE_OPTIMIZATION: add REGION VARCHAR DEFAULT 'California' parameter, switch to OBJECT_CONSTRUCT(jobs,vehicles)::VARIANT form, expose region in the agent tool descriptor (input_schema). Re-deployed in account. - backload-matching-aisql.ipynb: append 'Germany' arg, fix COST -> DURATION. - route-optimization routing_functions_aisql.ipynb: replace NULL region with 'California' in both _OPTIMIZATION_TABULAR_RAW cells. Updated docs: - AGENTS.md: explicit warning that region is required + body-limit note. - backload-matching SKILL.md, optimization-vrp-mapping.md: 2-arg signature. - build-routing-solution available-functions.md: IMPORTANT note on region arg. ors_control_app bumped to v1.0.206 and redeployed. TOOL_ROUTE_OPTIMIZATION verified end-to-end with California test (SF + Oakland + San Jose, depot Berkeley) -> SUCCESS with 2 routes.
Add a hover tooltip and a yellow info-box that explain the precondition for enabling the green Optimize Routes button: - if no centerCoords: 'Search a location first (enter address and click Go)' - if places=0 after geocode: 'No places found for region <region>...' Root cause for the user's report: PLACES, LOOKUP, and JOB_TEMPLATE tables are only seeded for REGION='SanFrancisco'. When the app region picker is California (or anywhere else), loadPlaces() returns 0 rows and the button stays disabled with no hint why. Bumped ors_control_app to v1.0.207 and redeployed.
…n-aware suspended warning Move "Wake up ORS" out of Backload Matching into a shared OrsWakeButton component mounted in the app header next to DatasetPicker. Shows green dot when all services are running, red pill + Resume button when region's ORS is suspended, amber spinner while warming. DatasetPicker dispatches ors-region-switched event for immediate re-check. Auto-warm logic inside BackloadMatching.solve() preserved for race-condition safety. Deployed as v1.0.208. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…y active region The Route Optimization page already used useRegion() dynamically, but its underlying tables only had data for SanFrancisco. This adds a stored procedure SEED_ROUTE_OPTIMIZATION_REGION that pulls POI data from Overture Maps for any region's bbox, and wires it into the server's region-switch endpoint so data is seeded automatically when the user picks a new preset. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
Two latent bugs were preventing the universal ORS status indicator from working: 1. RESULT_SCAN(LAST_QUERY_ID()) doesn't work across /api/query calls — the server uses Snowflake's stateless REST /api/v2/statements API, so each call gets a new session. The two-call SHOW SERVICES + RESULT_SCAN pattern returned 0 rows, leaving svcStatus.length === 0 forever (grey "ORS checking..." stuck). Fix: single SHOW SERVICES IN DATABASE + JS-side filter. 2. /api/query rejects ALTER (allow-list is SELECT/SHOW/DESC/CALL/WITH), so the Resume button would 403. Fix: use existing POST /api/services/:name/resume endpoint which calls the RESUME_SERVICE proc. Same two fixes applied to BackloadMatching's inline auto-warm probe. Added "ORS not provisioned for <region>" empty-state for regions where the ORS_SERVICE_<REGION> doesn't exist yet. Deployed as v1.0.209. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
… auto-seed Deploys the auto-seed server hook (POST /api/regions/active calls SEED_ROUTE_OPTIMIZATION_REGION) and the updated RouteOptimization.tsx warning message. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…nt works for non-SF regions Preview Catchment was failing silently for any region other than SanFrancisco because the ISOCHRONES call passed NULL for the region arg, routing through the legacy global ORS service (SF-only graph) which is suspended on most deployments. The function returned an error and a NULL GEOJSON, but the React handler had no error path so the user saw nothing. Fix passes the active region from useRegion() and adds try/catch + alert so future failures surface to the user. Bumps image to v1.0.211. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
…k Solving state Optimize Routes was failing silently for two reasons: 1. No try/catch around sfQuery — if the call threw (e.g., transient VROOM connection failure during cold-start), setSolving(false) was never reached and the button stuck on "Solving..." forever. 2. No user-visible error message when OPTIMIZATION returned zero rows. Fix wraps the call in try/catch/finally, probes _OPTIMIZATION_RAW on empty results to extract the underlying error, and shows an alert so users see exactly why the solve failed (region not provisioned, VROOM warming up, etc.) Also adds regionName to the dependency array. Bumps image to v1.0.212. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The MatrixBuilder UI was showing 'Build failed: RES7: 65,128 hexagons (4.2B pairs) — recommend XLARGE warehouse' for builds that had actually launched successfully. The server returns this message as a soft preflight warning (
data.warning) advising the user to scale the warehouse for >625M-pair builds, but the client was rendering anydata.warningin the same red 'Build failed:' banner as a realdata.error.This change:
buildWarningReact state..warning-bannerstyle with a 'Heads up:' label.startBuildnow setsbuildErroronly ondata.error;data.warninggoes tobuildWarning.ors_control_appimage to v1.0.185 (image-versions.env + ors_control_app_service.yaml).Test plan
MATRIX_BUILD_JOBS: California RES7 build was actually RUNNING despite the red banner.Dockerfile.runtime) and pushed.SHOW ENDPOINTSconfirms ingress URL is up: jlcmjncj-pm-fleet-test.snowflakecomputing.app