Skip to content

Hazard Mapping System

Phase 3: Warehouse Floor Plan Integration

Hazard Mapping provides visual risk overlay on warehouse floor plans, integrating predictive safety scores with spatial visualization.

Overview

The Hazard Mapping system projects predictive safety scores onto warehouse floor plans, creating an interactive safety heat map. Zones are color-coded based on their risk scores, with smooth gradients and detailed tooltips.

Database Schema

hazard_zones

Stores hazard zone mappings for floor plan visualization.

sql
CREATE TABLE public.hazard_zones (
  id uuid PRIMARY KEY,
  tenant_id uuid NOT NULL REFERENCES public.tenants(id),
  floor_zone_id uuid NOT NULL REFERENCES public.floorplan_zones(id),
  risk_score numeric CHECK (risk_score >= 0 AND risk_score <= 100),
  heat_color text NOT NULL DEFAULT '#00ff00',
  source text CHECK (source IN ('predictive', 'manual')),
  marked_by uuid REFERENCES public.profiles(id),
  notes text,
  updated_at timestamp with time zone DEFAULT now(),
  created_at timestamp with time zone DEFAULT now(),
  UNIQUE(floor_zone_id)
);

Key Fields:

  • floor_zone_id: Links to floorplan_zones.id (the zone shape on the floorplan)
  • risk_score: Risk score from 0-100
  • heat_color: Hex color for visualization (auto-calculated from score)
  • source: predictive (from Edge Function) or manual (marked by Safety Officer)
  • marked_by: User who manually marked the hazard (only for manual hazards)
  • notes: Optional notes for manual hazards

Automatic Projection

When predictive scores are calculated via the Edge Function, zone scores are automatically projected into hazard_zones:

  1. Edge Function calculates scores for all entities
  2. Zone scores are filtered
  3. For each zone with a score:
    • Find corresponding floorplan_zones records
    • Calculate heat color from score
    • Upsert into hazard_zones table

Color Calculation:

typescript
if (score >= 70) return '#ff0000'; // Red
if (score >= 50) return '#ff8800'; // Orange
if (score >= 30) return '#ffaa00'; // Yellow
return '#00ff00'; // Green

UI Components

FloorplanViewer Integration

Location: src/pages/warehouse/FloorplanViewer.tsx

Features:

  • Toggle "Hazard Overlay" switch to show/hide hazard zones
  • Smooth gradient overlays on zone rectangles
  • Tooltip on hover showing:
    • Risk score
    • Source (predictive/manual)
    • Notes (if available)
  • Threshold indicators (red circles) for critical zones (70+)
  • Color legend showing risk ranges

Visualization:

  • Zones are overlaid with semi-transparent colored rectangles
  • Gradient effect from top-left to bottom-right
  • Stroke color matches fill color with higher opacity
  • Hover effect increases stroke width

Manual Hazard Marking

Access: Safety Officer role only

Workflow:

  1. Enable "Hazard Overlay" toggle
  2. Click on a zone in the floor plan
  3. Dialog opens with:
    • Risk score slider (0-100)
    • Color preview
    • Notes textarea
  4. Save to create/update hazard zone

Permissions:

  • Safety Officers: Can create, update, and delete manual hazards
  • Admins: Full access
  • Workers/Drivers: Read-only (can view but not modify)

React Query Hooks

typescript
import {
  useHazardZones,
  useHazardZone,
  useUpsertHazardZone,
  useDeleteHazardZone,
} from '@/lib/queries';

// Fetch all hazard zones for a floorplan
const { data: hazardZones } = useHazardZones(floorplanId);

// Fetch specific hazard zone
const { data: hazardZone } = useHazardZone(floorZoneId);

// Create or update hazard zone (manual marking)
const { mutateAsync: upsertHazardZone } = useUpsertHazardZone();
await upsertHazardZone({
  floor_zone_id: zoneId,
  risk_score: 75,
  notes: 'Slippery floor reported',
});

// Delete hazard zone
const { mutateAsync: deleteHazardZone } = useDeleteHazardZone();
await deleteHazardZone(hazardZoneId);

Database Functions

get_hazard_color(score numeric)

Returns hex color code based on risk score.

sql
SELECT public.get_hazard_color(85); -- Returns '#ff0000' (red)

get_hazard_zones_for_floorplan(floorplan_id uuid)

Returns all hazard zones for a specific floorplan.

sql
SELECT * FROM public.get_hazard_zones_for_floorplan('floorplan-uuid');

Permissions & RLS

Hazard Zones:

  • Admins: Full access
  • Safety Officers: Full access (within tenant)
  • Tenant Admins: Full access (within tenant)
  • Workers/Drivers: Read-only access (within tenant)

Integration with Predictive Scores

Hazard zones are automatically created/updated when:

  1. Predictive scores are calculated via Edge Function
  2. Zone scores are projected to hazard_zones
  3. Existing hazard zones are updated (if predictive source)
  4. Manual hazards are preserved (not overwritten by predictive scores)

Priority:

  • Manual hazards take precedence (can override predictive scores)
  • Predictive scores update existing predictive hazards
  • Both sources can coexist (manual for specific zones, predictive for others)

Usage Examples

View Hazard Overlay

  1. Navigate to Floorplan Viewer
  2. Select a floorplan
  3. Toggle "Hazard Overlay" switch
  4. Zones are color-coded by risk level
  5. Hover over zones to see details

Mark Manual Hazard

typescript
// Safety Officer workflow
const { mutateAsync: upsertHazardZone } = useUpsertHazardZone();

await upsertHazardZone({
  floor_zone_id: 'floor-zone-uuid',
  risk_score: 80,
  notes: 'Wet floor - maintenance required',
});

Calculate and Project Scores

typescript
// Calculate predictive scores (automatically projects to hazard_zones)
import { calculatePredictiveSafetyScores } from '@/lib/api-edge';

await calculatePredictiveSafetyScores('zone', undefined, 30);
// Zone scores are automatically projected to hazard_zones

Best Practices

  1. Calculate Scores First: Run predictive score calculation before viewing hazard overlay
  2. Manual Overrides: Use manual marking for known hazards not captured by predictive model
  3. Regular Updates: Recalculate scores periodically to keep hazard map current
  4. Notes: Add descriptive notes for manual hazards to explain context
  5. Threshold Awareness: Pay special attention to critical zones (70+ risk score)

Released under Commercial License