{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://trinetrahq.com/schemas/sangam/1.0/alert.schema.json",
  "title": "SANGAM Alert",
  "description": "A rule fired on a fused track. Alerts recommend operator attention; trained people decide any response. Alerts describe object behaviour against geometry (lines, zones, time), never the identity of people.",
  "type": "object",
  "required": ["type", "schema_version", "id", "time", "rule", "level", "track_id", "position", "message"],
  "properties": {
    "type": {"const": "alert", "description": "Record type."},
    "schema_version": {"$ref": "common.schema.json#/$defs/schemaVersion"},
    "id": {"$ref": "common.schema.json#/$defs/id", "description": "Alert id, stable for de-duplication on retry."},
    "time": {"$ref": "common.schema.json#/$defs/time", "description": "Time of the event the alert describes, UTC."},
    "rule": {
      "description": "line_crossing: track crossed a virtual line; zone_entry: track entered a zone; loitering: track stayed within a small radius near the boundary; boundary_proximity: a registered vessel is close to the boundary (safety); person_in_water: a person-class track has been on water for a while (safety).",
      "enum": ["line_crossing", "zone_entry", "loitering", "boundary_proximity", "person_in_water"]
    },
    "level": {"$ref": "common.schema.json#/$defs/level"},
    "track_id": {"$ref": "common.schema.json#/$defs/id", "description": "The track that fired the rule."},
    "position": {"$ref": "common.schema.json#/$defs/position"},
    "classification": {"$ref": "common.schema.json#/$defs/classification"},
    "direction": {"enum": ["inbound", "outbound"], "description": "For line_crossing: inbound is from the boundary side of the line to the interior side."},
    "line_id": {"$ref": "common.schema.json#/$defs/id"},
    "zone_id": {"$ref": "common.schema.json#/$defs/id"},
    "registered": {"type": "boolean", "description": "True when the track is associated with a transponder."},
    "transponder_id": {"type": ["string", "null"]},
    "safety": {"type": "boolean", "description": "True when the alert concerns the safety of people or crews."},
    "message": {"type": "string", "minLength": 1, "maxLength": 280},
    "advisory": {"type": "string", "maxLength": 280},
    "attributes": {"$ref": "common.schema.json#/$defs/attributes"},
    "simulated": {"type": "boolean"}
  },
  "allOf": [
    {"if": {"properties": {"rule": {"const": "line_crossing"}}, "required": ["rule"]}, "then": {"required": ["direction", "line_id"]}},
    {"if": {"properties": {"rule": {"const": "zone_entry"}}, "required": ["rule"]}, "then": {"required": ["zone_id"]}}
  ],
  "additionalProperties": false,
  "examples": [
    {
      "type": "alert",
      "schema_version": "1.0",
      "id": "A0007",
      "time": "2026-10-20T16:06:31.000Z",
      "rule": "line_crossing",
      "level": "danger",
      "track_id": "T0042",
      "position": {"lat": 22.58851, "lon": 88.93987},
      "classification": {"label": "small_boat", "confidence": 0.91},
      "direction": "inbound",
      "line_id": "SETBACK-1",
      "registered": false,
      "transponder_id": null,
      "safety": false,
      "message": "Unregistered small boat crossed the setback line inbound at 4.9 m/s.",
      "advisory": "Verify on camera before any response. Follow standing orders.",
      "simulated": true
    }
  ]
}
