diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..76b2e9d3624af750734d47b66233779047d2854c --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,13 @@ +# AMD / vLLM Settings +VLLM_BASE_URL=http://localhost:8000/v1 +VLLM_API_KEY=not-needed +VLLM_MODEL=Qwen/Qwen2.5-72B-Instruct +VLLM_VISION_MODEL=Qwen/Qwen2-VL-7B-Instruct + +# App Settings +APP_ENV=development +DEBUG=true +DEMO_MODE=true + +# Storage +STORAGE_PATH=./data diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..02190a2a7b9af11e1b53b0b0939df67c17976edf --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +RUN mkdir -p data + +EXPOSE 8080 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"] diff --git a/backend/__pycache__/main.cpython-312.pyc b/backend/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7b9f46be94e0ff204ab2ceb358c4266a7eb47cf Binary files /dev/null and b/backend/__pycache__/main.cpython-312.pyc differ diff --git a/backend/agents/__init__.py b/backend/agents/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a60412f3194adde51ca1b3f09cf463f1d500bf9c --- /dev/null +++ b/backend/agents/__init__.py @@ -0,0 +1,19 @@ +from .intake_agent import IntakeAgent +from .transcription_agent import TranscriptionAgent +from .vision_agent import VisionAgent +from .normalization_agent import NormalizationAgent +from .dedup_agent import DedupAgent +from .triage_agent import TriageAgent +from .resource_agent import ResourceAgent +from .dispatch_agent import DispatchAgent + +__all__ = [ + "IntakeAgent", + "TranscriptionAgent", + "VisionAgent", + "NormalizationAgent", + "DedupAgent", + "TriageAgent", + "ResourceAgent", + "DispatchAgent", +] diff --git a/backend/agents/__pycache__/__init__.cpython-312.pyc b/backend/agents/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4077940662eb81569f79ba36336c2726359a3d06 Binary files /dev/null and b/backend/agents/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/dedup_agent.cpython-312.pyc b/backend/agents/__pycache__/dedup_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6b795469f633afa1d6c4453d5cdb9b1f99c627b Binary files /dev/null and b/backend/agents/__pycache__/dedup_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/dispatch_agent.cpython-312.pyc b/backend/agents/__pycache__/dispatch_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33229e7798f30c3b87933642a99be3b129f851ea Binary files /dev/null and b/backend/agents/__pycache__/dispatch_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/intake_agent.cpython-312.pyc b/backend/agents/__pycache__/intake_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a57a82e20986202f0e507877d51196964e5d0cf7 Binary files /dev/null and b/backend/agents/__pycache__/intake_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/normalization_agent.cpython-312.pyc b/backend/agents/__pycache__/normalization_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a60c120fcde89984dec67ab005c03f6c026efabd Binary files /dev/null and b/backend/agents/__pycache__/normalization_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/resource_agent.cpython-312.pyc b/backend/agents/__pycache__/resource_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e09e0cd8569a4f63f1064ad77cd141d15e3ba16 Binary files /dev/null and b/backend/agents/__pycache__/resource_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/transcription_agent.cpython-312.pyc b/backend/agents/__pycache__/transcription_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15b1da5d4ff598cb0beeabfd47f1087afb993b69 Binary files /dev/null and b/backend/agents/__pycache__/transcription_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/triage_agent.cpython-312.pyc b/backend/agents/__pycache__/triage_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57d55f09b291fdd1c9f9e3a97a5e0bbff5d52382 Binary files /dev/null and b/backend/agents/__pycache__/triage_agent.cpython-312.pyc differ diff --git a/backend/agents/__pycache__/vision_agent.cpython-312.pyc b/backend/agents/__pycache__/vision_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..758e8a9bf43ecbe6db30e7e1017cd2cf6cf683f7 Binary files /dev/null and b/backend/agents/__pycache__/vision_agent.cpython-312.pyc differ diff --git a/backend/agents/dedup_agent.py b/backend/agents/dedup_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..43b71c68827bfcfc437ac719a3ae1fafaf6e249c --- /dev/null +++ b/backend/agents/dedup_agent.py @@ -0,0 +1,19 @@ +from __future__ import annotations +import logging +from typing import List + +from schemas.signal import NormalizedSignal +from skills.detect_duplicates import detect_duplicates + +logger = logging.getLogger(__name__) + + +class DedupAgent: + def __init__(self, threshold: float = 0.75) -> None: + self.threshold = threshold + + async def run(self, signals: List[NormalizedSignal]) -> List[NormalizedSignal]: + logger.info("DedupAgent: processing %d signals", len(signals)) + unique = await detect_duplicates(signals, threshold=self.threshold) + logger.info("DedupAgent: %d unique signals after dedup", len(unique)) + return unique diff --git a/backend/agents/dispatch_agent.py b/backend/agents/dispatch_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..3c0e24cd42b0f80c5ea844f8ccb54197d16c60a3 --- /dev/null +++ b/backend/agents/dispatch_agent.py @@ -0,0 +1,39 @@ +from __future__ import annotations +import logging +from typing import Any, List + +from schemas.dispatch import DispatchMessage +from schemas.incident import Incident +from schemas.resource import ResourceRecommendation +from skills.generate_dispatch_message import generate_dispatch_message + +logger = logging.getLogger(__name__) + + +class DispatchAgent: + def __init__(self, vllm_client: Any = None) -> None: + self.vllm_client = vllm_client + + async def run( + self, + incidents: List[Incident], + all_resources: List[ResourceRecommendation], + ) -> List[DispatchMessage]: + logger.info("DispatchAgent: generating messages for %d incidents", len(incidents)) + messages: List[DispatchMessage] = [] + resource_by_incident = {} + for r in all_resources: + resource_by_incident.setdefault(r.incident_id, []).append(r) + + for incident in incidents: + incident_resources = resource_by_incident.get(incident.id, []) + msg = await generate_dispatch_message( + incident, + incident_resources, + channel="radio", + vllm_client=self.vllm_client, + ) + messages.append(msg) + + logger.info("DispatchAgent: generated %d dispatch messages", len(messages)) + return messages diff --git a/backend/agents/intake_agent.py b/backend/agents/intake_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..6a41529c9a9f40fce3f2dfd3b8d079b482703fb7 --- /dev/null +++ b/backend/agents/intake_agent.py @@ -0,0 +1,39 @@ +from __future__ import annotations +import logging +from datetime import datetime + +from schemas.report import ReportInput, ReportType +from schemas.signal import NormalizedSignal, SignalType + +logger = logging.getLogger(__name__) + + +class IntakeAgent: + async def run(self, report: ReportInput) -> NormalizedSignal: + logger.debug("IntakeAgent processing report %s (type=%s)", report.id, report.report_type) + + content = report.content or "" + modality = report.report_type.value + + if report.report_type == ReportType.LOCATION: + signal_type = SignalType.FLOOD + description = f"Location data received: {content[:200]}" + confidence = 0.70 + elif report.report_type == ReportType.CSV: + signal_type = SignalType.FLOOD + description = f"CSV batch data: {content[:200]}" + confidence = 0.70 + else: + signal_type = SignalType.UNKNOWN + description = content[:200] if content else f"Report from {modality}" + confidence = 0.60 + + return NormalizedSignal( + source_report_id=report.id, + signal_type=signal_type, + description=description, + raw_text=content, + confidence=confidence, + modality=modality, + created_at=datetime.utcnow(), + ) diff --git a/backend/agents/normalization_agent.py b/backend/agents/normalization_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..72472f15c2de9cdfe1684bb537c4688cfdc8a28a --- /dev/null +++ b/backend/agents/normalization_agent.py @@ -0,0 +1,45 @@ +from __future__ import annotations +import logging +from datetime import datetime + +from schemas.signal import NormalizedSignal, SignalType +from skills.normalize_signal import normalize_signal + +logger = logging.getLogger(__name__) + + +class NormalizationAgent: + def __init__(self, vllm_client=None) -> None: + self.vllm_client = vllm_client + + async def run(self, raw_text: str, report_id: str, modality: str) -> NormalizedSignal: + logger.debug("NormalizationAgent processing text from report %s", report_id) + data = await normalize_signal(raw_text, modality, report_id, vllm_client=self.vllm_client) + + signal_type_str = data.get("signal_type", "unknown") + try: + signal_type = SignalType(signal_type_str) + except ValueError: + signal_type = SignalType.UNKNOWN + + created_raw = data.get("created_at", datetime.utcnow().isoformat()) + if isinstance(created_raw, str): + try: + created_at = datetime.fromisoformat(created_raw) + except ValueError: + created_at = datetime.utcnow() + else: + created_at = created_raw + + return NormalizedSignal( + source_report_id=report_id, + signal_type=signal_type, + description=data.get("description", raw_text[:200]), + location=data.get("location"), + coordinates=data.get("coordinates"), + affected_people=data.get("affected_people"), + raw_text=raw_text, + confidence=data.get("confidence", 0.7), + modality=modality, + created_at=created_at, + ) diff --git a/backend/agents/resource_agent.py b/backend/agents/resource_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..cd3bd67edfc9cc61e35ddddcbb747408bc15aaa3 --- /dev/null +++ b/backend/agents/resource_agent.py @@ -0,0 +1,23 @@ +from __future__ import annotations +import logging +from typing import Any, List + +from schemas.incident import Incident +from schemas.resource import ResourceRecommendation +from skills.recommend_resources import recommend_resources + +logger = logging.getLogger(__name__) + + +class ResourceAgent: + def __init__(self, vllm_client: Any = None) -> None: + self.vllm_client = vllm_client + + async def run(self, incidents: List[Incident]) -> List[ResourceRecommendation]: + logger.info("ResourceAgent: generating recommendations for %d incidents", len(incidents)) + all_recommendations: List[ResourceRecommendation] = [] + for incident in incidents: + recs = await recommend_resources(incident, self.vllm_client) + all_recommendations.extend(recs) + logger.info("ResourceAgent: generated %d total recommendations", len(all_recommendations)) + return all_recommendations diff --git a/backend/agents/transcription_agent.py b/backend/agents/transcription_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..4142630bea5a2500dcbd262534afc90eb131a749 --- /dev/null +++ b/backend/agents/transcription_agent.py @@ -0,0 +1,29 @@ +from __future__ import annotations +import logging + +from core.config import get_settings +from schemas.report import ReportInput +from skills.transcribe_audio import transcribe_audio + +logger = logging.getLogger(__name__) + + +class TranscriptionAgent: + def __init__(self) -> None: + self.settings = get_settings() + + async def run(self, report: ReportInput) -> str: + logger.debug("TranscriptionAgent processing report %s", report.id) + file_path = report.file_path or "" + if not file_path and report.content: + file_path = report.content + + result = await transcribe_audio(file_path, demo_mode=self.settings.demo_mode) + transcription: str = result.get("transcription", "") + logger.info( + "Transcribed audio report %s: %.50s... (confidence=%.2f)", + report.id, + transcription, + result.get("confidence", 0), + ) + return transcription diff --git a/backend/agents/triage_agent.py b/backend/agents/triage_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..80b12795af711d6c881e963e655a718777322593 --- /dev/null +++ b/backend/agents/triage_agent.py @@ -0,0 +1,106 @@ +from __future__ import annotations +import logging +import uuid +from datetime import datetime +from typing import Any, List, Optional + +from schemas.incident import EvidenceItem, Incident, IncidentStatus, Priority +from schemas.signal import NormalizedSignal, SignalType +from skills.calculate_confidence import calculate_confidence +from skills.classify_priority import classify_priority + +logger = logging.getLogger(__name__) + +_PRIORITY_ORDER = {Priority.P0: 0, Priority.P1: 1, Priority.P2: 2, Priority.P3: 3} + + +class TriageAgent: + def __init__(self, session_id: str, vllm_client: Any = None) -> None: + self.session_id = session_id + self.vllm_client = vllm_client + + async def run(self, signals: List[NormalizedSignal]) -> List[Incident]: + logger.info("TriageAgent: creating incidents from %d signals", len(signals)) + incidents: List[Incident] = [] + + groups: dict = {} + for signal in signals: + key = (signal.signal_type, signal.location or "unknown") + groups.setdefault(key, []).append(signal) + + for (signal_type, location), group_signals in groups.items(): + priority = await classify_priority(group_signals[0], self.vllm_client) + + total_affected: Optional[int] = None + for s in group_signals: + if s.affected_people: + total_affected = (total_affected or 0) + s.affected_people + + confidence = await calculate_confidence(group_signals) + title = self._make_title(signal_type, location) + description = self._make_description(signal_type, location, group_signals, total_affected) + + coords = next((s.coordinates for s in group_signals if s.coordinates), None) + evidence = [ + EvidenceItem( + report_id=s.source_report_id, + modality=s.modality, + description=s.description[:150], + ) + for s in group_signals + ] + + incident = Incident( + id=str(uuid.uuid4()), + session_id=self.session_id, + title=title, + description=description, + priority=priority, + status=IncidentStatus.NEW, + signal_ids=[s.id for s in group_signals], + evidence=evidence, + location=location if location != "unknown" else None, + coordinates=coords, + affected_people=total_affected, + confidence=confidence, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ) + incidents.append(incident) + + incidents.sort(key=lambda x: _PRIORITY_ORDER.get(x.priority, 99)) + logger.info("TriageAgent: created %d incidents", len(incidents)) + return incidents + + def _make_title(self, signal_type: SignalType, location: str) -> str: + type_labels = { + SignalType.PERSON_TRAPPED: "Persona(s) Atrapada(s)", + SignalType.MEDICAL_EMERGENCY: "Emergencia Médica", + SignalType.STRUCTURAL_DAMAGE: "Daño Estructural", + SignalType.FLOOD: "Inundación", + SignalType.FIRE: "Incendio", + SignalType.MISSING_PERSON: "Persona Desaparecida", + SignalType.RESOURCE_REQUEST: "Solicitud de Recursos", + SignalType.SAFE_STATUS: "Reporte de Seguridad", + SignalType.UNKNOWN: "Incidente Desconocido", + } + label = type_labels.get(signal_type, "Incidente") + loc = location.title() if location and location != "unknown" else "Barrio Santa Ana" + return f"{label} — {loc}" + + def _make_description( + self, + signal_type: SignalType, + location: str, + signals: List[NormalizedSignal], + affected: Optional[int], + ) -> str: + parts = [f"Tipo: {signal_type.value.replace('_', ' ').title()}."] + if location and location != "unknown": + parts.append(f"Ubicación: {location}.") + if affected: + parts.append(f"Personas afectadas estimadas: {affected}.") + parts.append(f"Basado en {len(signals)} señal(es) recibida(s).") + if signals: + parts.append(f"Reporte más reciente: {signals[-1].description[:100]}.") + return " ".join(parts) diff --git a/backend/agents/vision_agent.py b/backend/agents/vision_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..8eb0335566cbeac4fe806591693ba828e5d89987 --- /dev/null +++ b/backend/agents/vision_agent.py @@ -0,0 +1,28 @@ +from __future__ import annotations +import logging + +from core.config import get_settings +from schemas.report import ReportInput +from skills.caption_image import caption_image + +logger = logging.getLogger(__name__) + + +class VisionAgent: + def __init__(self) -> None: + self.settings = get_settings() + + async def run(self, report: ReportInput) -> str: + logger.debug("VisionAgent processing report %s", report.id) + image_path = report.file_path or "" + if not image_path and report.content: + image_path = report.content + + result = await caption_image(image_path, demo_mode=self.settings.demo_mode) + caption: str = result.get("caption", "") + hazards = result.get("hazards", []) + if hazards: + caption += f" Hazards identified: {', '.join(hazards)}." + + logger.info("Captioned image report %s: %.80s...", report.id, caption) + return caption diff --git a/backend/api/__init__.py b/backend/api/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/api/__pycache__/__init__.cpython-312.pyc b/backend/api/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c09ab1861b1c74b006ace984a31e2bc57a03d506 Binary files /dev/null and b/backend/api/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/api/routes/__init__.py b/backend/api/routes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/api/routes/__pycache__/__init__.cpython-312.pyc b/backend/api/routes/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98286c3742fa5c010d923a8c4128dce179aee7a8 Binary files /dev/null and b/backend/api/routes/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/api/routes/__pycache__/amd.cpython-312.pyc b/backend/api/routes/__pycache__/amd.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36319b27edd8442dd01d75002864002583e92955 Binary files /dev/null and b/backend/api/routes/__pycache__/amd.cpython-312.pyc differ diff --git a/backend/api/routes/__pycache__/crisis_room.cpython-312.pyc b/backend/api/routes/__pycache__/crisis_room.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bddace70e0e5f918843aa7937f6b88f7a36d3b5 Binary files /dev/null and b/backend/api/routes/__pycache__/crisis_room.cpython-312.pyc differ diff --git a/backend/api/routes/__pycache__/demo.cpython-312.pyc b/backend/api/routes/__pycache__/demo.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..834ac5701c20714ff41bc85f891c45389a2de6f1 Binary files /dev/null and b/backend/api/routes/__pycache__/demo.cpython-312.pyc differ diff --git a/backend/api/routes/__pycache__/incidents.cpython-312.pyc b/backend/api/routes/__pycache__/incidents.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7724ceba0dd33631d2480ef1edb8dab64ce06b15 Binary files /dev/null and b/backend/api/routes/__pycache__/incidents.cpython-312.pyc differ diff --git a/backend/api/routes/__pycache__/reports.cpython-312.pyc b/backend/api/routes/__pycache__/reports.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d49554bc108fee82cb6c406e43dcc8a295ff3f93 Binary files /dev/null and b/backend/api/routes/__pycache__/reports.cpython-312.pyc differ diff --git a/backend/api/routes/amd.py b/backend/api/routes/amd.py new file mode 100644 index 0000000000000000000000000000000000000000..17df669a94cad392c6f2b421e59fac5bb2ee0028 --- /dev/null +++ b/backend/api/routes/amd.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from fastapi import APIRouter + +from core.config import get_settings +from schemas.amd import AMDPerformanceMetric +from skills.fetch_amd_metrics import fetch_amd_metrics + +router = APIRouter(prefix="/amd", tags=["amd"]) + + +@router.get("/performance", response_model=AMDPerformanceMetric) +async def get_amd_performance() -> AMDPerformanceMetric: + settings = get_settings() + return await fetch_amd_metrics(settings.vllm_base_url, demo_mode=settings.demo_mode) diff --git a/backend/api/routes/crisis_room.py b/backend/api/routes/crisis_room.py new file mode 100644 index 0000000000000000000000000000000000000000..db84ce6172e7ed92c6fc82cbec7d9cfee7718af8 --- /dev/null +++ b/backend/api/routes/crisis_room.py @@ -0,0 +1,42 @@ +from __future__ import annotations +import logging +import uuid +from typing import Optional + +from fastapi import APIRouter, HTTPException +from pydantic import BaseModel + +from schemas.crisis_room import CrisisRoomSummary +from schemas.report import UploadBatch +from services.pipeline import Pipeline +from services.storage import get_storage + +logger = logging.getLogger(__name__) +router = APIRouter(prefix="/crisis-room", tags=["crisis-room"]) + + +class CrisisRoomRequest(BaseModel): + batch: UploadBatch + session_id: Optional[str] = None + + +@router.post("", response_model=CrisisRoomSummary) +async def create_crisis_room(request: CrisisRoomRequest) -> CrisisRoomSummary: + if request.session_id: + request.batch.session_id = request.session_id + pipeline = Pipeline() + try: + summary = await pipeline.process_batch(request.batch) + except Exception as exc: + logger.exception("Pipeline error: %s", exc) + raise HTTPException(status_code=500, detail=f"Pipeline error: {exc}") + return summary + + +@router.get("/{session_id}", response_model=dict) +async def get_crisis_room(session_id: str) -> dict: + storage = get_storage() + session = await storage.get_session(session_id) + if session is None: + raise HTTPException(status_code=404, detail=f"Session {session_id} not found") + return session diff --git a/backend/api/routes/demo.py b/backend/api/routes/demo.py new file mode 100644 index 0000000000000000000000000000000000000000..9334c7d255010ebc7d9cc03ee05aee168ae9d092 --- /dev/null +++ b/backend/api/routes/demo.py @@ -0,0 +1,70 @@ +from __future__ import annotations +import json +import logging +import uuid +from datetime import datetime +from pathlib import Path +from typing import Any, Dict, List + +from fastapi import APIRouter, HTTPException + +from schemas.report import ReportInput, ReportType, UploadBatch +from services.pipeline import Pipeline + +logger = logging.getLogger(__name__) +router = APIRouter(prefix="/demo", tags=["demo"]) + +_SCENARIO_PATH = Path(__file__).parent.parent.parent.parent / "demo_data" / "scenario_flood_santa_ana.json" + + +def _load_scenario() -> Dict[str, Any]: + if _SCENARIO_PATH.exists(): + return json.loads(_SCENARIO_PATH.read_text(encoding="utf-8")) + return { + "scenario_name": "Inundación Barrio Santa Ana", + "description": "Demo scenario — file not found", + "reports": [], + } + + +@router.get("/scenario") +async def get_demo_scenario() -> Dict[str, Any]: + return _load_scenario() + + +@router.post("/run") +async def run_demo() -> Dict[str, Any]: + scenario = _load_scenario() + session_id = str(uuid.uuid4()) + reports: List[ReportInput] = [] + + for raw in scenario.get("reports", []): + rtype_str = raw.get("report_type", "text") + try: + rtype = ReportType(rtype_str) + except ValueError: + rtype = ReportType.TEXT + + reports.append(ReportInput( + id=raw.get("id", str(uuid.uuid4())), + session_id=session_id, + report_type=rtype, + content=raw.get("content"), + metadata=raw.get("metadata", {}), + created_at=datetime.utcnow(), + )) + + batch = UploadBatch( + session_id=session_id, + reports=reports, + scenario_name=scenario.get("scenario_name", "Demo"), + ) + + pipeline = Pipeline() + try: + summary = await pipeline.process_batch(batch) + except Exception as exc: + logger.exception("Demo pipeline error: %s", exc) + raise HTTPException(status_code=500, detail=str(exc)) + + return summary.model_dump(mode="json") diff --git a/backend/api/routes/incidents.py b/backend/api/routes/incidents.py new file mode 100644 index 0000000000000000000000000000000000000000..c6d94e761f7ae8bbaac5fde9041630c28bd8ac6b --- /dev/null +++ b/backend/api/routes/incidents.py @@ -0,0 +1,90 @@ +from __future__ import annotations +import logging +from datetime import datetime +from typing import List, Optional + +from fastapi import APIRouter, HTTPException, Query +from pydantic import BaseModel + +from schemas.dispatch import DispatchMessage +from schemas.incident import Incident, IncidentStatus, Priority +from services.storage import get_storage +from skills.generate_dispatch_message import generate_dispatch_message + +logger = logging.getLogger(__name__) +router = APIRouter(prefix="/incidents", tags=["incidents"]) + + +class IncidentUpdate(BaseModel): + status: Optional[IncidentStatus] = None + human_approved: Optional[bool] = None + notes: Optional[str] = None + priority: Optional[Priority] = None + + +@router.get("", response_model=List[dict]) +async def list_incidents( + session_id: Optional[str] = Query(default=None), + priority: Optional[Priority] = Query(default=None), + status: Optional[IncidentStatus] = Query(default=None), +) -> List[dict]: + storage = get_storage() + incidents = await storage.list_incidents() + + if session_id: + incidents = [i for i in incidents if i.get("session_id") == session_id] + if priority: + incidents = [i for i in incidents if i.get("priority") == priority.value] + if status: + incidents = [i for i in incidents if i.get("status") == status.value] + + return incidents + + +@router.get("/{incident_id}", response_model=dict) +async def get_incident(incident_id: str) -> dict: + storage = get_storage() + incident = await storage.get_incident(incident_id) + if incident is None: + raise HTTPException(status_code=404, detail=f"Incident {incident_id} not found") + return incident + + +@router.patch("/{incident_id}", response_model=dict) +async def update_incident(incident_id: str, update: IncidentUpdate) -> dict: + storage = get_storage() + updates = {k: v for k, v in update.model_dump().items() if v is not None} + updates["updated_at"] = datetime.utcnow().isoformat() + if "priority" in updates and isinstance(updates["priority"], Priority): + updates["priority"] = updates["priority"].value + if "status" in updates and isinstance(updates["status"], IncidentStatus): + updates["status"] = updates["status"].value + + updated = await storage.update_incident(incident_id, updates) + if updated is None: + raise HTTPException(status_code=404, detail=f"Incident {incident_id} not found") + return updated + + +@router.post("/{incident_id}/dispatch-message", response_model=dict) +async def create_dispatch_message(incident_id: str, channel: str = "radio") -> dict: + storage = get_storage() + incident_data = await storage.get_incident(incident_id) + if incident_data is None: + raise HTTPException(status_code=404, detail=f"Incident {incident_id} not found") + + incident = Incident(**incident_data) + all_resources_raw = await storage.list_resources() + resources = [r for r in all_resources_raw if r.get("incident_id") == incident_id] + + from schemas.resource import ResourceRecommendation + resource_objs = [] + for r in resources: + try: + resource_objs.append(ResourceRecommendation(**r)) + except Exception: + pass + + msg = await generate_dispatch_message(incident, resource_objs, channel=channel) + await storage.save_dispatch(msg.id, msg.model_dump(mode="json")) + return msg.model_dump(mode="json") diff --git a/backend/api/routes/reports.py b/backend/api/routes/reports.py new file mode 100644 index 0000000000000000000000000000000000000000..6122eb00a4202728dba43e88573efb01a679dc99 --- /dev/null +++ b/backend/api/routes/reports.py @@ -0,0 +1,93 @@ +from __future__ import annotations +import logging +import uuid +from datetime import datetime +from typing import List, Optional + +from fastapi import APIRouter, File, Form, HTTPException, UploadFile +from pydantic import BaseModel + +from schemas.report import ReportInput, ReportType, UploadBatch +from services.pipeline import Pipeline +from services.storage import get_storage + +logger = logging.getLogger(__name__) +router = APIRouter(prefix="/reports", tags=["reports"]) + + +@router.post("/upload") +async def upload_reports( + session_id: Optional[str] = Form(default=None), + scenario_name: Optional[str] = Form(default=None), + files: List[UploadFile] = File(default=[]), + text_messages: Optional[str] = Form(default=None), +) -> dict: + sid = session_id or str(uuid.uuid4()) + reports: List[ReportInput] = [] + + if text_messages: + for i, msg in enumerate(text_messages.split("|||")): + msg = msg.strip() + if msg: + reports.append(ReportInput( + id=str(uuid.uuid4()), + session_id=sid, + report_type=ReportType.TEXT, + content=msg, + metadata={"source": "upload", "index": i}, + created_at=datetime.utcnow(), + )) + + for file in files: + filename = file.filename or "unknown" + name_lower = filename.lower() + if name_lower.endswith((".mp3", ".wav", ".ogg", ".m4a")): + rtype = ReportType.AUDIO + elif name_lower.endswith((".jpg", ".jpeg", ".png", ".webp")): + rtype = ReportType.IMAGE + elif name_lower.endswith(".csv"): + rtype = ReportType.CSV + else: + rtype = ReportType.TEXT + + content = await file.read() + reports.append(ReportInput( + id=str(uuid.uuid4()), + session_id=sid, + report_type=rtype, + content=content.decode("utf-8", errors="replace") if rtype in (ReportType.TEXT, ReportType.CSV) else None, + file_path=filename, + metadata={"original_filename": filename, "size_bytes": len(content)}, + created_at=datetime.utcnow(), + )) + + storage = get_storage() + await storage.save_session(sid, { + "session_id": sid, + "scenario_name": scenario_name, + "total_reports": len(reports), + "status": "uploaded", + "created_at": datetime.utcnow().isoformat(), + }) + + return {"session_id": sid, "batch_id": sid, "report_count": len(reports), "status": "uploaded"} + + +@router.post("/process") +async def process_batch(batch: UploadBatch) -> dict: + pipeline = Pipeline() + try: + summary = await pipeline.process_batch(batch) + except Exception as exc: + logger.exception("Batch processing error: %s", exc) + raise HTTPException(status_code=500, detail=str(exc)) + return summary.model_dump(mode="json") + + +@router.get("/{session_id}") +async def list_session_reports(session_id: str) -> dict: + storage = get_storage() + session = await storage.get_session(session_id) + if session is None: + raise HTTPException(status_code=404, detail=f"Session {session_id} not found") + return {"session_id": session_id, "session": session} diff --git a/backend/core/__init__.py b/backend/core/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/core/__pycache__/__init__.cpython-312.pyc b/backend/core/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46be4963a63ca93d96331bc2df3ce2a409ec2cd8 Binary files /dev/null and b/backend/core/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/core/__pycache__/config.cpython-312.pyc b/backend/core/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22eb688b2546153299e0f05a240b3238079a2ec5 Binary files /dev/null and b/backend/core/__pycache__/config.cpython-312.pyc differ diff --git a/backend/core/config.py b/backend/core/config.py new file mode 100644 index 0000000000000000000000000000000000000000..49267f65aa9a7ae97d09e504aaaae4ac353de792 --- /dev/null +++ b/backend/core/config.py @@ -0,0 +1,20 @@ +from functools import lru_cache +from pydantic_settings import BaseSettings + + +class Settings(BaseSettings): + vllm_base_url: str = "http://localhost:8000/v1" + vllm_api_key: str = "not-needed" + vllm_model: str = "Qwen/Qwen2.5-72B-Instruct" + vllm_vision_model: str = "Qwen/Qwen2-VL-7B-Instruct" + app_env: str = "development" + debug: bool = True + demo_mode: bool = True + storage_path: str = "./data" + + model_config = {"env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore"} + + +@lru_cache() +def get_settings() -> Settings: + return Settings() diff --git a/backend/data/dispatch/03a16c03-94e5-4e6f-ba8a-237658e28a5b.json b/backend/data/dispatch/03a16c03-94e5-4e6f-ba8a-237658e28a5b.json new file mode 100644 index 0000000000000000000000000000000000000000..5839b5504972ff16ad2f01db2ed862e5f66ba745 --- /dev/null +++ b/backend/data/dispatch/03a16c03-94e5-4e6f-ba8a-237658e28a5b.json @@ -0,0 +1 @@ +{"id": "03a16c03-94e5-4e6f-ba8a-237658e28a5b", "incident_id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "channel": "radio", "message": "ALERTA P0 \u2014 BARRIO SANTA ANA: Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 53250214. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.503776", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/12791726-6e83-4d2f-aea9-9ba2733edbe9.json b/backend/data/dispatch/12791726-6e83-4d2f-aea9-9ba2733edbe9.json new file mode 100644 index 0000000000000000000000000000000000000000..bb568db21d9d206c5518b26d68b0034c821721ef --- /dev/null +++ b/backend/data/dispatch/12791726-6e83-4d2f-aea9-9ba2733edbe9.json @@ -0,0 +1 @@ +{"id": "12791726-6e83-4d2f-aea9-9ba2733edbe9", "incident_id": "1c43f156-18ad-4322-8aa3-725416683112", "channel": "radio", "message": "ALERTA P0 \u2014 CENTRO COMUNITARIO: Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 1c43f156. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.503795", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/143f2fa6-e703-4a7e-84a4-92a5ee09d550.json b/backend/data/dispatch/143f2fa6-e703-4a7e-84a4-92a5ee09d550.json new file mode 100644 index 0000000000000000000000000000000000000000..73f784fcec0a65e4050c92f7998a3426ea248b31 --- /dev/null +++ b/backend/data/dispatch/143f2fa6-e703-4a7e-84a4-92a5ee09d550.json @@ -0,0 +1 @@ +{"id": "143f2fa6-e703-4a7e-84a4-92a5ee09d550", "incident_id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "channel": "radio", "message": "ALERTA P0 \u2014 Barrio Santa Ana: Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: e76d4ac7. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.587101", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/2048c8c5-ca83-467f-959c-a6838a3897b2.json b/backend/data/dispatch/2048c8c5-ca83-467f-959c-a6838a3897b2.json new file mode 100644 index 0000000000000000000000000000000000000000..8ef995b05eb36783046d5eeb87d319695dd67b3f --- /dev/null +++ b/backend/data/dispatch/2048c8c5-ca83-467f-959c-a6838a3897b2.json @@ -0,0 +1 @@ +{"id": "2048c8c5-ca83-467f-959c-a6838a3897b2", "incident_id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "channel": "radio", "message": "ALERTA P0 \u2014 PUENTE: Tipo: Flood. Ubicaci\u00f3n: Puente. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s recient \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: d8ebe4ff. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415505", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/22eb6be8-481a-4e35-a3f1-007b71fe871d.json b/backend/data/dispatch/22eb6be8-481a-4e35-a3f1-007b71fe871d.json new file mode 100644 index 0000000000000000000000000000000000000000..1667f88d9533ea05532b73aeb293e8697c2dead6 --- /dev/null +++ b/backend/data/dispatch/22eb6be8-481a-4e35-a3f1-007b71fe871d.json @@ -0,0 +1 @@ +{"id": "22eb6be8-481a-4e35-a3f1-007b71fe871d", "incident_id": "4588efff-8ded-444f-8d4d-e48651a094ca", "channel": "radio", "message": "ALERTA P0 \u2014 CENTRO COMUNITARIO: Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 4588efff. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415568", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/36562d51-406e-4ff6-8fb8-4a97135aa904.json b/backend/data/dispatch/36562d51-406e-4ff6-8fb8-4a97135aa904.json new file mode 100644 index 0000000000000000000000000000000000000000..2808573337e00d7290d8c6ac59baf16f67764330 --- /dev/null +++ b/backend/data/dispatch/36562d51-406e-4ff6-8fb8-4a97135aa904.json @@ -0,0 +1 @@ +{"id": "36562d51-406e-4ff6-8fb8-4a97135aa904", "incident_id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "channel": "radio", "message": "ALERTA P0 \u2014 SECTOR EL PROGRESO INFORMAMOS QUE EL NIVEL DEL AGUA COMENZ\u00d3 A BAJAR LEVEMENTE EN LAS \u00daLTIMAS 2 HORAS: Tipo: Flood. Ubicaci\u00f3n: Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 H \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: cc64a7fe. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415598", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/36d98de7-9007-4c70-a694-e066d515ba9c.json b/backend/data/dispatch/36d98de7-9007-4c70-a694-e066d515ba9c.json new file mode 100644 index 0000000000000000000000000000000000000000..ffd6c4f0dad327c5e667e7814b647ba650ff1660 --- /dev/null +++ b/backend/data/dispatch/36d98de7-9007-4c70-a694-e066d515ba9c.json @@ -0,0 +1 @@ +{"id": "36d98de7-9007-4c70-a694-e066d515ba9c", "incident_id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "channel": "radio", "message": "ALERTA P0 \u2014 CALLE SUCRE EST\u00c1 COMPLETAMENTE INUNDADA: Tipo: Flood. Ubicaci\u00f3n: Calle Sucre Est\u00e1 Completamente Inundada. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 9ca75909. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415578", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/372c2577-8f0a-42f5-ad2b-ae205ec79e1d.json b/backend/data/dispatch/372c2577-8f0a-42f5-ad2b-ae205ec79e1d.json new file mode 100644 index 0000000000000000000000000000000000000000..e358dd4233eddc848f7f8e0f8481c2e4397a9cfd --- /dev/null +++ b/backend/data/dispatch/372c2577-8f0a-42f5-ad2b-ae205ec79e1d.json @@ -0,0 +1 @@ +{"id": "372c2577-8f0a-42f5-ad2b-ae205ec79e1d", "incident_id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "channel": "radio", "message": "ALERTA P0 \u2014 Calle Sucre Est\u00e1 Completamente Inundada: Tipo: Flood. Ubicaci\u00f3n: Calle Sucre Est\u00e1 Completamente Inundada. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 5e88dc0d. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498178", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/3ec4f10a-3f9d-427d-aca8-3134efa35105.json b/backend/data/dispatch/3ec4f10a-3f9d-427d-aca8-3134efa35105.json new file mode 100644 index 0000000000000000000000000000000000000000..0f36cd21dbc89cb61bb7c1a4916e1cb215f4cfc0 --- /dev/null +++ b/backend/data/dispatch/3ec4f10a-3f9d-427d-aca8-3134efa35105.json @@ -0,0 +1 @@ +{"id": "3ec4f10a-3f9d-427d-aca8-3134efa35105", "incident_id": "6cac476b-78e0-4226-b31f-1839b7185642", "channel": "radio", "message": "ALERTA P0 \u2014 Santa Ana: Tipo: Flood. Ubicaci\u00f3n: Santa Ana. Personas afectadas estimadas: 180. Basado en 6 se\u00f1al(es) recibida(s). Reporte m\u00e1s rec \u2014 180 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 6cac476b. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498064", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/3f2d7e95-ee1c-443e-8825-cc32c7bea9b4.json b/backend/data/dispatch/3f2d7e95-ee1c-443e-8825-cc32c7bea9b4.json new file mode 100644 index 0000000000000000000000000000000000000000..523c1742c2fbd59610e331f81d67d5430402e8aa --- /dev/null +++ b/backend/data/dispatch/3f2d7e95-ee1c-443e-8825-cc32c7bea9b4.json @@ -0,0 +1 @@ +{"id": "3f2d7e95-ee1c-443e-8825-cc32c7bea9b4", "incident_id": "7de575c3-3ed9-4645-a814-f446bfda0714", "channel": "radio", "message": "ALERTA P0 \u2014 Centro Comunitario: Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 7de575c3. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.587121", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/46f1763e-8b79-4726-9f58-42f572b1634a.json b/backend/data/dispatch/46f1763e-8b79-4726-9f58-42f572b1634a.json new file mode 100644 index 0000000000000000000000000000000000000000..3af843b0130c76d2e61e0faf8ea3965006d81a0e --- /dev/null +++ b/backend/data/dispatch/46f1763e-8b79-4726-9f58-42f572b1634a.json @@ -0,0 +1 @@ +{"id": "46f1763e-8b79-4726-9f58-42f572b1634a", "incident_id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "channel": "radio", "message": "ALERTA P0 \u2014 Calle Bolivar: Tipo: Flood. Ubicaci\u00f3n: Calle Bolivar. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 1816328e. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498241", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/52bcb889-4d82-4dc3-9391-0448e167e049.json b/backend/data/dispatch/52bcb889-4d82-4dc3-9391-0448e167e049.json new file mode 100644 index 0000000000000000000000000000000000000000..8d88a27c3078c1b5b680ae324400ddb20d0ef7a4 --- /dev/null +++ b/backend/data/dispatch/52bcb889-4d82-4dc3-9391-0448e167e049.json @@ -0,0 +1 @@ +{"id": "52bcb889-4d82-4dc3-9391-0448e167e049", "incident_id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "channel": "radio", "message": "ALERTA P0 \u2014 Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas: Tipo: Flood. Ubicaci\u00f3n: Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 H \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: deb675dc. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498231", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/53838726-76f3-4722-b9a8-ec7b48a05dd9.json b/backend/data/dispatch/53838726-76f3-4722-b9a8-ec7b48a05dd9.json new file mode 100644 index 0000000000000000000000000000000000000000..172c97f34021729930d43befffb5455e817dc494 --- /dev/null +++ b/backend/data/dispatch/53838726-76f3-4722-b9a8-ec7b48a05dd9.json @@ -0,0 +1 @@ +{"id": "53838726-76f3-4722-b9a8-ec7b48a05dd9", "incident_id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "channel": "radio", "message": "ALERTA P0 \u2014 Sector Las Palmas: Tipo: Flood. Ubicaci\u00f3n: Sector Las Palmas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: b58a6e59. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498215", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/5c6bffcd-5dd0-4355-988c-3e7518e48fb1.json b/backend/data/dispatch/5c6bffcd-5dd0-4355-988c-3e7518e48fb1.json new file mode 100644 index 0000000000000000000000000000000000000000..bf44b57bb21640416a6b4119339df5a73cb378dd --- /dev/null +++ b/backend/data/dispatch/5c6bffcd-5dd0-4355-988c-3e7518e48fb1.json @@ -0,0 +1 @@ +{"id": "5c6bffcd-5dd0-4355-988c-3e7518e48fb1", "incident_id": "fead649a-4200-4465-8223-116c49aed1c5", "channel": "radio", "message": "ALERTA P0 \u2014 Escuela Sim\u00f3n Bol\u00edvar: Tipo: Flood. Ubicaci\u00f3n: Escuela Sim\u00f3n Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Repo \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: fead649a. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498097", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/6bda4497-eb22-46c8-a92d-511c3840b01c.json b/backend/data/dispatch/6bda4497-eb22-46c8-a92d-511c3840b01c.json new file mode 100644 index 0000000000000000000000000000000000000000..8df8add34067fe6e10d2c7eab1fd7d38610258a1 --- /dev/null +++ b/backend/data/dispatch/6bda4497-eb22-46c8-a92d-511c3840b01c.json @@ -0,0 +1 @@ +{"id": "6bda4497-eb22-46c8-a92d-511c3840b01c", "incident_id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "channel": "radio", "message": "ALERTA P0 \u2014 Puente: Tipo: Flood. Ubicaci\u00f3n: Puente. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s recient \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 33d7f7b1. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498157", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/6d6174f2-f2f4-491f-b5cb-5d0a9e8ca962.json b/backend/data/dispatch/6d6174f2-f2f4-491f-b5cb-5d0a9e8ca962.json new file mode 100644 index 0000000000000000000000000000000000000000..1dbcff92aa894dccdc6ad9e3750bbb424df4394c --- /dev/null +++ b/backend/data/dispatch/6d6174f2-f2f4-491f-b5cb-5d0a9e8ca962.json @@ -0,0 +1 @@ +{"id": "6d6174f2-f2f4-491f-b5cb-5d0a9e8ca962", "incident_id": "859c21e7-e963-4712-9c92-5043024542a5", "channel": "radio", "message": "ALERTA P0 \u2014 Av. Principal: Tipo: Flood. Ubicaci\u00f3n: Av. Principal. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 859c21e7. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498142", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/8d7f0333-d172-477d-8789-749c2f95c5ec.json b/backend/data/dispatch/8d7f0333-d172-477d-8789-749c2f95c5ec.json new file mode 100644 index 0000000000000000000000000000000000000000..77e3c22396024e0d455c5c4dbe92f248dd9023a5 --- /dev/null +++ b/backend/data/dispatch/8d7f0333-d172-477d-8789-749c2f95c5ec.json @@ -0,0 +1 @@ +{"id": "8d7f0333-d172-477d-8789-749c2f95c5ec", "incident_id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "channel": "radio", "message": "ALERTA P0 \u2014 Calle Bol\u00edvar: Tipo: Flood. Ubicaci\u00f3n: Calle Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: d822f7fa. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498112", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/96295f3e-1d87-401d-ab3a-c1c4a3b12a18.json b/backend/data/dispatch/96295f3e-1d87-401d-ab3a-c1c4a3b12a18.json new file mode 100644 index 0000000000000000000000000000000000000000..f91d1aa3f8e23426397210fb7abb65665615649c --- /dev/null +++ b/backend/data/dispatch/96295f3e-1d87-401d-ab3a-c1c4a3b12a18.json @@ -0,0 +1 @@ +{"id": "96295f3e-1d87-401d-ab3a-c1c4a3b12a18", "incident_id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "channel": "radio", "message": "ALERTA P0 \u2014 SECTOR LAS PALMAS: Tipo: Flood. Ubicaci\u00f3n: Sector Las Palmas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 7c27eb5f. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415587", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/abdcbb9d-4c50-4551-9118-d0a626f443ce.json b/backend/data/dispatch/abdcbb9d-4c50-4551-9118-d0a626f443ce.json new file mode 100644 index 0000000000000000000000000000000000000000..63a074fd8f1f38586259867e65a3cc4479f9d314 --- /dev/null +++ b/backend/data/dispatch/abdcbb9d-4c50-4551-9118-d0a626f443ce.json @@ -0,0 +1 @@ +{"id": "abdcbb9d-4c50-4551-9118-d0a626f443ce", "incident_id": "58be1c76-fc6e-425b-9264-8228074add3e", "channel": "radio", "message": "ALERTA P0 \u2014 Barrio Santa Ana: Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 180. Basado en 6 se\u00f1al(es) recibida(s). Reporte \u2014 180 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 58be1c76. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498127", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/ad1f99f8-6397-4859-9b38-3d6da01ce0ca.json b/backend/data/dispatch/ad1f99f8-6397-4859-9b38-3d6da01ce0ca.json new file mode 100644 index 0000000000000000000000000000000000000000..53167fe9c9746816fc8f689755373f7be65421fa --- /dev/null +++ b/backend/data/dispatch/ad1f99f8-6397-4859-9b38-3d6da01ce0ca.json @@ -0,0 +1 @@ +{"id": "ad1f99f8-6397-4859-9b38-3d6da01ce0ca", "incident_id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "channel": "radio", "message": "ALERTA P0 \u2014 BARRIO SANTA ANA: Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 150. Basado en 5 se\u00f1al(es) recibida(s). Reporte \u2014 150 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 8c9bc082. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415536", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/bb73320e-8820-4472-a5e3-a90aaa38561a.json b/backend/data/dispatch/bb73320e-8820-4472-a5e3-a90aaa38561a.json new file mode 100644 index 0000000000000000000000000000000000000000..8f76657003a632c99ebf68ada8052e893d069bb8 --- /dev/null +++ b/backend/data/dispatch/bb73320e-8820-4472-a5e3-a90aaa38561a.json @@ -0,0 +1 @@ +{"id": "bb73320e-8820-4472-a5e3-a90aaa38561a", "incident_id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "channel": "radio", "message": "ALERTA P0 \u2014 CALLE BOL\u00cdVAR: Tipo: Flood. Ubicaci\u00f3n: Calle Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 3ca30150. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415476", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/c445a27d-88b8-4063-b487-1231fa38eaed.json b/backend/data/dispatch/c445a27d-88b8-4063-b487-1231fa38eaed.json new file mode 100644 index 0000000000000000000000000000000000000000..2b3595a213e323dfa5fa2ebad9bbcc8943b53bfa --- /dev/null +++ b/backend/data/dispatch/c445a27d-88b8-4063-b487-1231fa38eaed.json @@ -0,0 +1 @@ +{"id": "c445a27d-88b8-4063-b487-1231fa38eaed", "incident_id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "channel": "radio", "message": "ALERTA P0 \u2014 AV. PRINCIPAL: Tipo: Flood. Ubicaci\u00f3n: Av. Principal. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 8d188c4a. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415559", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/c4d6b1c6-fc08-4214-9bb0-5ec567e6933b.json b/backend/data/dispatch/c4d6b1c6-fc08-4214-9bb0-5ec567e6933b.json new file mode 100644 index 0000000000000000000000000000000000000000..0bac64699f6cbae01e9870b3a3c8e24ebf661fd1 --- /dev/null +++ b/backend/data/dispatch/c4d6b1c6-fc08-4214-9bb0-5ec567e6933b.json @@ -0,0 +1 @@ +{"id": "c4d6b1c6-fc08-4214-9bb0-5ec567e6933b", "incident_id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "channel": "radio", "message": "ALERTA P0 \u2014 SANTA ANA: Tipo: Flood. Ubicaci\u00f3n: Santa Ana. Personas afectadas estimadas: 90. Basado en 3 se\u00f1al(es) recibida(s). Reporte m\u00e1s reci \u2014 90 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 2b4eb726. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415549", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/cacc44dc-bc48-4efd-a04b-ba85f4bb3d19.json b/backend/data/dispatch/cacc44dc-bc48-4efd-a04b-ba85f4bb3d19.json new file mode 100644 index 0000000000000000000000000000000000000000..9c404ee1fb6a7006e2de3231ebd2885155a36120 --- /dev/null +++ b/backend/data/dispatch/cacc44dc-bc48-4efd-a04b-ba85f4bb3d19.json @@ -0,0 +1 @@ +{"id": "cacc44dc-bc48-4efd-a04b-ba85f4bb3d19", "incident_id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "channel": "radio", "message": "ALERTA P0 \u2014 ESCUELA SIM\u00d3N BOL\u00cdVAR: Tipo: Flood. Ubicaci\u00f3n: Escuela Sim\u00f3n Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Repo \u2014 60 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 3be519d0. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415524", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/cb5f3edb-5b4b-49cd-a1e4-6d476a35aacb.json b/backend/data/dispatch/cb5f3edb-5b4b-49cd-a1e4-6d476a35aacb.json new file mode 100644 index 0000000000000000000000000000000000000000..51eca99ddb79484cd8c0d8ba4ca8c8c70b2aeb32 --- /dev/null +++ b/backend/data/dispatch/cb5f3edb-5b4b-49cd-a1e4-6d476a35aacb.json @@ -0,0 +1 @@ +{"id": "cb5f3edb-5b4b-49cd-a1e4-6d476a35aacb", "incident_id": "87be53a2-1e2a-42c7-ae02-192171266a41", "channel": "radio", "message": "ALERTA P0 \u2014 Centro Comunitario: Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 87be53a2. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:30.498168", "approved": false} \ No newline at end of file diff --git a/backend/data/dispatch/e917dda6-edef-4d31-a5ed-ead91aa3a4f8.json b/backend/data/dispatch/e917dda6-edef-4d31-a5ed-ead91aa3a4f8.json new file mode 100644 index 0000000000000000000000000000000000000000..1611d47566668fada03a97afb7bbac9982b267ce --- /dev/null +++ b/backend/data/dispatch/e917dda6-edef-4d31-a5ed-ead91aa3a4f8.json @@ -0,0 +1 @@ +{"id": "e917dda6-edef-4d31-a5ed-ead91aa3a4f8", "incident_id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "channel": "radio", "message": "ALERTA P0 \u2014 CALLE BOLIVAR: Tipo: Flood. Ubicaci\u00f3n: Calle Bolivar. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s \u2014 30 personas afectadas. Recursos necesarios: 2x Equipo de rescate acu\u00e1tico, 3x Lanchas de evacuaci\u00f3n, 200x Agua potable embotellada. Coordinar con: Brigada Alfa \u2014 Rescate Cr\u00edtico. ID incidente: 3795aa64. CAMBIO.", "brigade_target": "Brigada Alfa \u2014 Rescate Cr\u00edtico", "created_at": "2026-05-06T01:07:12.415607", "approved": false} \ No newline at end of file diff --git a/backend/data/incidents/1816328e-f3ed-4e13-a87d-552b278a58a1.json b/backend/data/incidents/1816328e-f3ed-4e13-a87d-552b278a58a1.json new file mode 100644 index 0000000000000000000000000000000000000000..b187de1972b96be8dc158dd3d5aa046c61be075f --- /dev/null +++ b/backend/data/incidents/1816328e-f3ed-4e13-a87d-552b278a58a1.json @@ -0,0 +1 @@ +{"id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Calle Bolivar", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Bolivar. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0.", "priority": "P0", "status": "new", "signal_ids": ["5853a327-1721-4582-ae88-7b79da0bb683"], "evidence": [{"id": "7c920288-9abb-4a92-a24c-f90aa21df018", "report_id": "rpt_029", "modality": "csv", "description": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99", "file_path": null, "timestamp": "2026-05-06T01:07:30.481849"}], "location": "Calle Bolivar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481856", "updated_at": "2026-05-06T01:07:30.481858", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/1c43f156-18ad-4322-8aa3-725416683112.json b/backend/data/incidents/1c43f156-18ad-4322-8aa3-725416683112.json new file mode 100644 index 0000000000000000000000000000000000000000..9e2044e66a7bc82c1643e9d1f6b75c5de185cbe3 --- /dev/null +++ b/backend/data/incidents/1c43f156-18ad-4322-8aa3-725416683112.json @@ -0,0 +1 @@ +{"id": "1c43f156-18ad-4322-8aa3-725416683112", "session_id": "fea49518-a599-4178-8b5b-2fed8273e06d", "title": "Inundaci\u00f3n \u2014 Centro Comunitario", "description": "Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua.", "priority": "P0", "status": "new", "signal_ids": ["885ee87f-fc8c-41da-a40b-6869f4b5c9b9"], "evidence": [{"id": "208d664a-3593-43fb-9b2c-81c68306c954", "report_id": "5a1dd036-4252-4572-b108-44c0fdde852f", "modality": "text", "description": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "file_path": null, "timestamp": "2026-05-06T01:07:12.501158"}], "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.501166", "updated_at": "2026-05-06T01:07:12.501168", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326.json b/backend/data/incidents/2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326.json new file mode 100644 index 0000000000000000000000000000000000000000..67564e2946d3d9685afcdd15770535d67eeba6d9 --- /dev/null +++ b/backend/data/incidents/2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326.json @@ -0,0 +1 @@ +{"id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Santa Ana. Personas afectadas estimadas: 90. Basado en 3 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos.", "priority": "P0", "status": "new", "signal_ids": ["fab24ecf-60b1-450e-a0be-441764f533d9", "5b140c5d-1598-4b33-967e-75d851660f29", "a35b42bd-82bd-45f2-836c-4c09b24d9a5a"], "evidence": [{"id": "b385c639-2f5c-4561-b162-244b18fee50e", "report_id": "rpt_022", "modality": "image", "description": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main e", "file_path": null, "timestamp": "2026-05-06T01:07:12.402257"}, {"id": "a4ce34ec-e967-4cbd-a8d2-4b541ce2e9fa", "report_id": "rpt_009", "modality": "text", "description": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracci", "file_path": null, "timestamp": "2026-05-06T01:07:12.402264"}, {"id": "afe95137-a638-4795-b01e-0862383c61c5", "report_id": "rpt_012", "modality": "text", "description": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del ", "file_path": null, "timestamp": "2026-05-06T01:07:12.402273"}], "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 90, "confidence": 1.0, "created_at": "2026-05-06T01:07:12.402280", "updated_at": "2026-05-06T01:07:12.402282", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/33d7f7b1-754e-45d4-affe-e806d18290d7.json b/backend/data/incidents/33d7f7b1-754e-45d4-affe-e806d18290d7.json new file mode 100644 index 0000000000000000000000000000000000000000..eeb47c87b63b1998e65ec2540aaed9606d6c3a38 --- /dev/null +++ b/backend/data/incidents/33d7f7b1-754e-45d4-affe-e806d18290d7.json @@ -0,0 +1 @@ +{"id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Puente", "description": "Tipo: Flood. Ubicaci\u00f3n: Puente. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular .", "priority": "P0", "status": "new", "signal_ids": ["73f3c3cb-b323-44fc-932d-d078b1f9a39f"], "evidence": [{"id": "a1ea59e4-5c5e-45b2-8b34-db57ed8c9fd6", "report_id": "rpt_004", "modality": "text", "description": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tie", "file_path": null, "timestamp": "2026-05-06T01:07:30.481684"}], "location": "Puente", "coordinates": {"lat": 10.479, "lon": -66.902}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481690", "updated_at": "2026-05-06T01:07:30.481692", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/3795aa64-71da-425d-9284-5a3dcd04a63c.json b/backend/data/incidents/3795aa64-71da-425d-9284-5a3dcd04a63c.json new file mode 100644 index 0000000000000000000000000000000000000000..e9efdf7858656b2ae72dc2af550e400ec889b9df --- /dev/null +++ b/backend/data/incidents/3795aa64-71da-425d-9284-5a3dcd04a63c.json @@ -0,0 +1 @@ +{"id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Calle Bolivar", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Bolivar. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0.", "priority": "P0", "status": "new", "signal_ids": ["1562e755-58e7-422c-a8fe-0531de586385"], "evidence": [{"id": "0b276e0a-b701-409f-bd1d-82b6268535b3", "report_id": "rpt_029", "modality": "csv", "description": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99", "file_path": null, "timestamp": "2026-05-06T01:07:12.402487"}], "location": "Calle Bolivar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.402494", "updated_at": "2026-05-06T01:07:12.402498", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/3be519d0-bfaa-433c-a4cf-adb0b3186b06.json b/backend/data/incidents/3be519d0-bfaa-433c-a4cf-adb0b3186b06.json new file mode 100644 index 0000000000000000000000000000000000000000..1c92b4bad32b9fa90756f1c9192fcf1434a98996 --- /dev/null +++ b/backend/data/incidents/3be519d0-bfaa-433c-a4cf-adb0b3186b06.json @@ -0,0 +1 @@ +{"id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar", "description": "Tipo: Flood. Ubicaci\u00f3n: Escuela Sim\u00f3n Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo pi.", "priority": "P0", "status": "new", "signal_ids": ["fd983943-526a-4ce4-b370-b5391a117c6f", "a2bf70f5-5054-4a3f-9bd8-b3fa171b7ab9"], "evidence": [{"id": "96889d84-f331-48b0-a086-eb1ce7a41403", "report_id": "rpt_018", "modality": "audio", "description": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos ", "file_path": null, "timestamp": "2026-05-06T01:07:12.402109"}, {"id": "ab1e8edc-e187-4b85-9c3d-f7d7f19baa6d", "report_id": "rpt_002", "modality": "text", "description": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya", "file_path": null, "timestamp": "2026-05-06T01:07:12.402122"}], "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:12.402129", "updated_at": "2026-05-06T01:07:12.402131", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/3ca30150-55ab-4145-b07e-9e68e1be89b5.json b/backend/data/incidents/3ca30150-55ab-4145-b07e-9e68e1be89b5.json new file mode 100644 index 0000000000000000000000000000000000000000..69f0b6daf7408a642358f2b59d26cada413bf571 --- /dev/null +++ b/backend/data/incidents/3ca30150-55ab-4145-b07e-9e68e1be89b5.json @@ -0,0 +1 @@ +{"id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Calle Bol\u00edvar", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no pued.", "priority": "P0", "status": "new", "signal_ids": ["f7b10e45-fade-4315-99ef-57a467cbdfa7", "2cba759b-3471-48b8-ab52-ac362d07e7f6"], "evidence": [{"id": "ccefc2da-3e20-409c-a08c-f8812ab192da", "report_id": "rpt_016", "modality": "audio", "description": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, nece", "file_path": null, "timestamp": "2026-05-06T01:07:12.401973"}, {"id": "3c4aef7b-82f3-4635-9607-ceda2c163d20", "report_id": "rpt_001", "modality": "text", "description": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos", "file_path": null, "timestamp": "2026-05-06T01:07:12.401990"}], "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:12.402003", "updated_at": "2026-05-06T01:07:12.402006", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/4588efff-8ded-444f-8d4d-e48651a094ca.json b/backend/data/incidents/4588efff-8ded-444f-8d4d-e48651a094ca.json new file mode 100644 index 0000000000000000000000000000000000000000..ec7d2daf8d21be265bd1d286882ff909f3cb22a2 --- /dev/null +++ b/backend/data/incidents/4588efff-8ded-444f-8d4d-e48651a094ca.json @@ -0,0 +1 @@ +{"id": "4588efff-8ded-444f-8d4d-e48651a094ca", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Centro Comunitario", "description": "Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1o.", "priority": "P0", "status": "new", "signal_ids": ["493cf0ab-da9f-4ad3-adbc-5f62e5649324"], "evidence": [{"id": "533249b3-699a-4869-a823-f556b83e88d6", "report_id": "rpt_005", "modality": "text", "description": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se ag", "file_path": null, "timestamp": "2026-05-06T01:07:12.402347"}], "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.402354", "updated_at": "2026-05-06T01:07:12.402355", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/53250214-30ee-4f0b-8be8-5b04aed8e1ef.json b/backend/data/incidents/53250214-30ee-4f0b-8be8-5b04aed8e1ef.json new file mode 100644 index 0000000000000000000000000000000000000000..7928d253a6929d2d9d92d38242164a6982be6d7d --- /dev/null +++ b/backend/data/incidents/53250214-30ee-4f0b-8be8-5b04aed8e1ef.json @@ -0,0 +1 @@ +{"id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "session_id": "fea49518-a599-4178-8b5b-2fed8273e06d", "title": "Inundaci\u00f3n \u2014 Barrio Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente.", "priority": "P0", "status": "new", "signal_ids": ["c3627714-d763-4f37-93e8-f9ec57d1ed6a"], "evidence": [{"id": "ead41c47-371d-43f6-9876-a16de707f5fa", "report_id": "739eb38e-3e24-4dce-af37-b68aa24a091f", "modality": "text", "description": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "file_path": null, "timestamp": "2026-05-06T01:07:12.501094"}], "location": "Barrio Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.501109", "updated_at": "2026-05-06T01:07:12.501113", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/58be1c76-fc6e-425b-9264-8228074add3e.json b/backend/data/incidents/58be1c76-fc6e-425b-9264-8228074add3e.json new file mode 100644 index 0000000000000000000000000000000000000000..7afebb8af338d668065517da360d5d28db486636 --- /dev/null +++ b/backend/data/incidents/58be1c76-fc6e-425b-9264-8228074add3e.json @@ -0,0 +1 @@ +{"id": "58be1c76-fc6e-425b-9264-8228074add3e", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Barrio Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 180. Basado en 6 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores.", "priority": "P0", "status": "new", "signal_ids": ["9cb5a0fb-574e-4348-b252-e3ea6cf4c2a2", "543e3974-8662-4531-93a4-2bdd39336c49", "5e41d0cb-26ff-4e5c-ae97-80bd414e9491", "138e2204-fc66-4445-aebc-cb278b4be1c4", "bbbef4ce-0097-4a21-a984-ba338b2b1544", "3fd59544-d7c9-4861-ad6c-b908654ed691"], "evidence": [{"id": "ed4b6ca2-70d0-4b93-89dc-07d59bf3a903", "report_id": "rpt_021", "modality": "image", "description": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible e", "file_path": null, "timestamp": "2026-05-06T01:07:30.481563"}, {"id": "ca01029e-a235-4ba9-848f-f6020227d85a", "report_id": "rpt_022", "modality": "image", "description": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedes", "file_path": null, "timestamp": "2026-05-06T01:07:30.481570"}, {"id": "3b794b46-27b6-458a-9bd4-f671a14182e4", "report_id": "rpt_024", "modality": "image", "description": "Makeshift raft carrying three adults navigating between houses. Improvised from wooden pallets and plastic barrels. One person appears to have a banda", "file_path": null, "timestamp": "2026-05-06T01:07:30.481577"}, {"id": "0d288e48-e177-461c-b9ce-ff0402737497", "report_id": "rpt_028", "modality": "image", "description": "Flooded electrical substation with water reaching transformer level. Live wires in contact with floodwater visible. No civilians in immediate vicinity", "file_path": null, "timestamp": "2026-05-06T01:07:30.481584"}, {"id": "642e61ee-327c-4612-8294-fc044f16b195", "report_id": "rpt_010", "modality": "text", "description": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su f", "file_path": null, "timestamp": "2026-05-06T01:07:30.481591"}, {"id": "675bf611-52fc-46f1-8521-3f72ee962bea", "report_id": "rpt_015", "modality": "text", "description": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin he", "file_path": null, "timestamp": "2026-05-06T01:07:30.481597"}], "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 180, "confidence": 1.0, "created_at": "2026-05-06T01:07:30.481604", "updated_at": "2026-05-06T01:07:30.481606", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/5e88dc0d-5c0c-4b05-98cf-0674cd48392a.json b/backend/data/incidents/5e88dc0d-5c0c-4b05-98cf-0674cd48392a.json new file mode 100644 index 0000000000000000000000000000000000000000..d35253643625b9d71705b3034aa895ba5e1098bb --- /dev/null +++ b/backend/data/incidents/5e88dc0d-5c0c-4b05-98cf-0674cd48392a.json @@ -0,0 +1 @@ +{"id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Sucre Est\u00e1 Completamente Inundada. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en co.", "priority": "P0", "status": "new", "signal_ids": ["5c52e577-8eb4-48a6-b4e6-51c42fd244e1"], "evidence": [{"id": "f5f9ec9c-f00d-4987-ba0f-053035997e31", "report_id": "rpt_007", "modality": "text", "description": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuc", "file_path": null, "timestamp": "2026-05-06T01:07:30.481754"}], "location": "Calle Sucre Est\u00e1 Completamente Inundada", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481761", "updated_at": "2026-05-06T01:07:30.481762", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/6cac476b-78e0-4226-b31f-1839b7185642.json b/backend/data/incidents/6cac476b-78e0-4226-b31f-1839b7185642.json new file mode 100644 index 0000000000000000000000000000000000000000..f4d51a308910f011b49d9a2d312d39353a4fcd15 --- /dev/null +++ b/backend/data/incidents/6cac476b-78e0-4226-b31f-1839b7185642.json @@ -0,0 +1 @@ +{"id": "6cac476b-78e0-4226-b31f-1839b7185642", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Santa Ana. Personas afectadas estimadas: 180. Basado en 6 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos.", "priority": "P0", "status": "new", "signal_ids": ["09c39c6e-7dab-44d2-aeda-2241c23f1f59", "dec8a437-45c9-4b10-8a7b-69709c4347f9", "e948583f-eb3d-4534-8c85-e032e9987a35", "15dc56ec-713d-4cf8-b2d3-9f38af951543", "474a3c1a-5b2c-4d7c-a036-6e39ef9f3d20", "d74b9685-7de3-42e3-b94a-70f770137d10"], "evidence": [{"id": "d599ca73-fd37-4b94-b69c-97eece1e7803", "report_id": "rpt_016", "modality": "audio", "description": "This is a rescue call from Santa Ana district. We have a man with a broken leg and possible spinal injury on the corner of Av. Principal and Calle 5. ", "file_path": null, "timestamp": "2026-05-06T01:07:30.481336"}, {"id": "2e5a2b57-71a8-4bc0-b1a6-bc2844f36f3d", "report_id": "rpt_023", "modality": "image", "description": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main e", "file_path": null, "timestamp": "2026-05-06T01:07:30.481353"}, {"id": "720a25aa-dc7f-48b2-bf0f-fe2f0a947319", "report_id": "rpt_025", "modality": "image", "description": "Heavily flooded residential street in Santa Ana district. Water level is approximately 1.5 meters high. A family of four including two children are vi", "file_path": null, "timestamp": "2026-05-06T01:07:30.481363"}, {"id": "81513fd4-25ea-4689-8bc1-1581be0fa8ef", "report_id": "rpt_026", "modality": "image", "description": "Child approximately 8 years old sitting alone on a fence post surrounded by floodwater. Location appears to be near the Santa Ana primary school. No a", "file_path": null, "timestamp": "2026-05-06T01:07:30.481370"}, {"id": "336164f8-1fc7-49da-8f4e-40a0ea53aa81", "report_id": "rpt_009", "modality": "text", "description": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracci", "file_path": null, "timestamp": "2026-05-06T01:07:30.481378"}, {"id": "57e97ecf-e6aa-4e45-87b5-1bb486f1bbab", "report_id": "rpt_012", "modality": "text", "description": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del ", "file_path": null, "timestamp": "2026-05-06T01:07:30.481385"}], "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 180, "confidence": 1.0, "created_at": "2026-05-06T01:07:30.481397", "updated_at": "2026-05-06T01:07:30.481400", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/7c27eb5f-0250-40f8-ae0b-8384e5933ee7.json b/backend/data/incidents/7c27eb5f-0250-40f8-ae0b-8384e5933ee7.json new file mode 100644 index 0000000000000000000000000000000000000000..43b7d2987a94ce62d7c6bffddce8ec1fbde13a34 --- /dev/null +++ b/backend/data/incidents/7c27eb5f-0250-40f8-ae0b-8384e5933ee7.json @@ -0,0 +1 @@ +{"id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Sector Las Palmas", "description": "Tipo: Flood. Ubicaci\u00f3n: Sector Las Palmas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colap.", "priority": "P0", "status": "new", "signal_ids": ["12e6e282-74a9-4b27-9bf9-7a82c92bbdfe"], "evidence": [{"id": "8a861975-6e9f-450f-8a59-e1f96c2b45c7", "report_id": "rpt_008", "modality": "text", "description": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos v", "file_path": null, "timestamp": "2026-05-06T01:07:12.402418"}], "location": "Sector Las Palmas", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.402424", "updated_at": "2026-05-06T01:07:12.402426", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/7de575c3-3ed9-4645-a814-f446bfda0714.json b/backend/data/incidents/7de575c3-3ed9-4645-a814-f446bfda0714.json new file mode 100644 index 0000000000000000000000000000000000000000..f3a8d80134a736c100cc519b7aee87119f8a2d8e --- /dev/null +++ b/backend/data/incidents/7de575c3-3ed9-4645-a814-f446bfda0714.json @@ -0,0 +1 @@ +{"id": "7de575c3-3ed9-4645-a814-f446bfda0714", "session_id": "73dc26b4-eb71-4b97-b538-f631ae51a73d", "title": "Inundaci\u00f3n \u2014 Centro Comunitario", "description": "Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua.", "priority": "P0", "status": "new", "signal_ids": ["c14a1ff0-f928-416d-a6af-86e475ab3fda"], "evidence": [{"id": "d63631f0-2f7b-4565-a32a-fa323b57535f", "report_id": "00c17b9b-0ee0-48bd-9a54-d5cd36698acc", "modality": "text", "description": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "file_path": null, "timestamp": "2026-05-06T01:07:30.584409"}], "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.584418", "updated_at": "2026-05-06T01:07:30.584420", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/859c21e7-e963-4712-9c92-5043024542a5.json b/backend/data/incidents/859c21e7-e963-4712-9c92-5043024542a5.json new file mode 100644 index 0000000000000000000000000000000000000000..afda0c34f94e7e545bb5a37344adcdad9b3f7032 --- /dev/null +++ b/backend/data/incidents/859c21e7-e963-4712-9c92-5043024542a5.json @@ -0,0 +1 @@ +{"id": "859c21e7-e963-4712-9c92-5043024542a5", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Av. Principal", "description": "Tipo: Flood. Ubicaci\u00f3n: Av. Principal. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours..", "priority": "P0", "status": "new", "signal_ids": ["7b147f89-082c-422d-82c8-81f6c75b4447", "736cc236-0302-4f63-9198-a83c7ee172c3"], "evidence": [{"id": "371c86c7-785f-4812-96b3-14a4e7dae3bf", "report_id": "rpt_003", "modality": "text", "description": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando ", "file_path": null, "timestamp": "2026-05-06T01:07:30.481634"}, {"id": "2d73b005-ac0c-4e72-a255-0a7e10e29c02", "report_id": "rpt_006", "modality": "text", "description": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs m", "file_path": null, "timestamp": "2026-05-06T01:07:30.481644"}], "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:30.481653", "updated_at": "2026-05-06T01:07:30.481655", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/87be53a2-1e2a-42c7-ae02-192171266a41.json b/backend/data/incidents/87be53a2-1e2a-42c7-ae02-192171266a41.json new file mode 100644 index 0000000000000000000000000000000000000000..cf1084029f7da0d4306fb772a85d2be017715373 --- /dev/null +++ b/backend/data/incidents/87be53a2-1e2a-42c7-ae02-192171266a41.json @@ -0,0 +1 @@ +{"id": "87be53a2-1e2a-42c7-ae02-192171266a41", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Centro Comunitario", "description": "Tipo: Flood. Ubicaci\u00f3n: Centro Comunitario. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1o.", "priority": "P0", "status": "new", "signal_ids": ["190d41d3-5af1-4018-846c-c60e34941f55"], "evidence": [{"id": "b2186ec2-47e5-4456-8800-ebb2ea02243b", "report_id": "rpt_005", "modality": "text", "description": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se ag", "file_path": null, "timestamp": "2026-05-06T01:07:30.481715"}], "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481721", "updated_at": "2026-05-06T01:07:30.481723", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/8c9bc082-90a0-4d8f-a6b2-a538f9688fb7.json b/backend/data/incidents/8c9bc082-90a0-4d8f-a6b2-a538f9688fb7.json new file mode 100644 index 0000000000000000000000000000000000000000..1c018b65f09f5ab28e86c02b394ac1ff63d80870 --- /dev/null +++ b/backend/data/incidents/8c9bc082-90a0-4d8f-a6b2-a538f9688fb7.json @@ -0,0 +1 @@ +{"id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Barrio Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 150. Basado en 5 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores.", "priority": "P0", "status": "new", "signal_ids": ["f5bc50bf-d597-42bd-8343-c43deb437eac", "f3fce772-27a3-4a1f-bd22-219ac44ae966", "cc28863a-857f-414e-8af1-9e19122a558c", "9b5cccb5-e6d0-43cf-8f22-570fc869ba3a", "0f21af7b-eeac-468d-96e7-75b12db2ba79"], "evidence": [{"id": "aa3480e7-606f-4d4b-9d25-393f0ffd1b57", "report_id": "rpt_021", "modality": "image", "description": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible e", "file_path": null, "timestamp": "2026-05-06T01:07:12.402164"}, {"id": "2c21dfac-e6a8-4758-9e9e-40e5deb63c40", "report_id": "rpt_025", "modality": "image", "description": "Collapsed wall of a two-story brick building. Rubble and debris scattered across the street blocking vehicle access. No visible casualties in frame bu", "file_path": null, "timestamp": "2026-05-06T01:07:12.402172"}, {"id": "8408f2c1-9336-4f4d-bf26-3d42b5a3c025", "report_id": "rpt_028", "modality": "image", "description": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedes", "file_path": null, "timestamp": "2026-05-06T01:07:12.402179"}, {"id": "94cb9947-5b50-4dfd-b790-b202615c8325", "report_id": "rpt_010", "modality": "text", "description": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su f", "file_path": null, "timestamp": "2026-05-06T01:07:12.402208"}, {"id": "8e732f76-a6d2-42bc-adc7-1151c10b7709", "report_id": "rpt_015", "modality": "text", "description": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin he", "file_path": null, "timestamp": "2026-05-06T01:07:12.402215"}], "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 150, "confidence": 1.0, "created_at": "2026-05-06T01:07:12.402223", "updated_at": "2026-05-06T01:07:12.402224", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/8d188c4a-e2f9-484d-a3d3-afad983a0ffa.json b/backend/data/incidents/8d188c4a-e2f9-484d-a3d3-afad983a0ffa.json new file mode 100644 index 0000000000000000000000000000000000000000..cc083f9024a728054ca00b69e28e3facc07f4768 --- /dev/null +++ b/backend/data/incidents/8d188c4a-e2f9-484d-a3d3-afad983a0ffa.json @@ -0,0 +1 @@ +{"id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Av. Principal", "description": "Tipo: Flood. Ubicaci\u00f3n: Av. Principal. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours..", "priority": "P0", "status": "new", "signal_ids": ["7e63ed59-b5ef-447e-bd79-05a862a92a39", "a55c5c9d-d9c7-409e-bb1e-176b42b6d4a6"], "evidence": [{"id": "5bc42124-f1da-4b66-9d00-7e18c7bf28e1", "report_id": "rpt_003", "modality": "text", "description": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando ", "file_path": null, "timestamp": "2026-05-06T01:07:12.402308"}, {"id": "4e4fc739-8799-4caa-b98c-928b3703968f", "report_id": "rpt_006", "modality": "text", "description": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs m", "file_path": null, "timestamp": "2026-05-06T01:07:12.402315"}], "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:12.402321", "updated_at": "2026-05-06T01:07:12.402323", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/9ca75909-d9ea-49ad-90e0-e371a8b3576c.json b/backend/data/incidents/9ca75909-d9ea-49ad-90e0-e371a8b3576c.json new file mode 100644 index 0000000000000000000000000000000000000000..bd32e1801dca73e59f3a51c28e3c531b01868ce3 --- /dev/null +++ b/backend/data/incidents/9ca75909-d9ea-49ad-90e0-e371a8b3576c.json @@ -0,0 +1 @@ +{"id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Sucre Est\u00e1 Completamente Inundada. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en co.", "priority": "P0", "status": "new", "signal_ids": ["be19b726-85b6-4c65-b075-2f7f12b03656"], "evidence": [{"id": "e8a63ea8-f0fa-4ca6-b5aa-40656da165cc", "report_id": "rpt_007", "modality": "text", "description": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuc", "file_path": null, "timestamp": "2026-05-06T01:07:12.402386"}], "location": "Calle Sucre Est\u00e1 Completamente Inundada", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.402392", "updated_at": "2026-05-06T01:07:12.402394", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/b58a6e59-a483-44b3-ab3f-6b32668a9d9a.json b/backend/data/incidents/b58a6e59-a483-44b3-ab3f-6b32668a9d9a.json new file mode 100644 index 0000000000000000000000000000000000000000..b42f595474ee7ac22d03f2e8d2703309ec7a3af9 --- /dev/null +++ b/backend/data/incidents/b58a6e59-a483-44b3-ab3f-6b32668a9d9a.json @@ -0,0 +1 @@ +{"id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Sector Las Palmas", "description": "Tipo: Flood. Ubicaci\u00f3n: Sector Las Palmas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colap.", "priority": "P0", "status": "new", "signal_ids": ["41af92a2-5411-4e09-b226-8be4c1fed977"], "evidence": [{"id": "aa217d67-b329-4115-9065-81cbcb096383", "report_id": "rpt_008", "modality": "text", "description": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos v", "file_path": null, "timestamp": "2026-05-06T01:07:30.481790"}], "location": "Sector Las Palmas", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481796", "updated_at": "2026-05-06T01:07:30.481798", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/cc64a7fe-38af-4e72-b78b-eb05aa3176e8.json b/backend/data/incidents/cc64a7fe-38af-4e72-b78b-eb05aa3176e8.json new file mode 100644 index 0000000000000000000000000000000000000000..97bec67885f25a92182d8b5cf94dcaf909be629e --- /dev/null +++ b/backend/data/incidents/cc64a7fe-38af-4e72-b78b-eb05aa3176e8.json @@ -0,0 +1 @@ +{"id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "description": "Tipo: Flood. Ubicaci\u00f3n: Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltima.", "priority": "P0", "status": "new", "signal_ids": ["010b17d8-f045-4aac-a161-cfa759be1825"], "evidence": [{"id": "e594180b-961f-4df4-92d6-6a819143ea94", "report_id": "rpt_011", "modality": "text", "description": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de ", "file_path": null, "timestamp": "2026-05-06T01:07:12.402457"}], "location": "Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:12.402464", "updated_at": "2026-05-06T01:07:12.402466", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/d822f7fa-4500-42f4-a4d7-ce5465c38c01.json b/backend/data/incidents/d822f7fa-4500-42f4-a4d7-ce5465c38c01.json new file mode 100644 index 0000000000000000000000000000000000000000..3a32abc4d567d7a8ed602ce62263b6ee921c95b6 --- /dev/null +++ b/backend/data/incidents/d822f7fa-4500-42f4-a4d7-ce5465c38c01.json @@ -0,0 +1 @@ +{"id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Calle Bol\u00edvar", "description": "Tipo: Flood. Ubicaci\u00f3n: Calle Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no pued.", "priority": "P0", "status": "new", "signal_ids": ["3bd5dc9b-a608-4f1b-982e-1f964251140a", "7368e339-876b-471e-b3a8-0cb86f9f6353"], "evidence": [{"id": "c797ec19-95db-4cff-88e3-e146e1ef7569", "report_id": "rpt_018", "modality": "audio", "description": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, nece", "file_path": null, "timestamp": "2026-05-06T01:07:30.481502"}, {"id": "53dafda6-5c26-475f-8e7c-a03989b6b67b", "report_id": "rpt_001", "modality": "text", "description": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos", "file_path": null, "timestamp": "2026-05-06T01:07:30.481510"}], "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:30.481517", "updated_at": "2026-05-06T01:07:30.481519", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/d8ebe4ff-807a-4469-b7fb-1c2e215a7827.json b/backend/data/incidents/d8ebe4ff-807a-4469-b7fb-1c2e215a7827.json new file mode 100644 index 0000000000000000000000000000000000000000..a8b03a54897e9fa924b9c2f5bb845d9abecd3222 --- /dev/null +++ b/backend/data/incidents/d8ebe4ff-807a-4469-b7fb-1c2e215a7827.json @@ -0,0 +1 @@ +{"id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "title": "Inundaci\u00f3n \u2014 Puente", "description": "Tipo: Flood. Ubicaci\u00f3n: Puente. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular .", "priority": "P0", "status": "new", "signal_ids": ["dbd3a2f8-d405-46cb-9999-0bbd63a7ed33", "41296eb4-920a-4dff-9dac-9c1bf86a45d4"], "evidence": [{"id": "74517961-ddfd-45d1-a0ac-59ab481ed01a", "report_id": "rpt_017", "modality": "audio", "description": "El puente de la entrada del barrio colaps\u00f3. No pueden entrar camiones ni ambulancias por esa v\u00eda. Solo se puede acceder por la carretera vieja del nor", "file_path": null, "timestamp": "2026-05-06T01:07:12.402059"}, {"id": "2928839b-184a-4873-81ae-967951e5f059", "report_id": "rpt_004", "modality": "text", "description": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tie", "file_path": null, "timestamp": "2026-05-06T01:07:12.402067"}], "location": "Puente", "coordinates": {"lat": 10.479, "lon": -66.902}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:12.402076", "updated_at": "2026-05-06T01:07:12.402078", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/deb675dc-b6c6-4898-816d-b3792f64c71f.json b/backend/data/incidents/deb675dc-b6c6-4898-816d-b3792f64c71f.json new file mode 100644 index 0000000000000000000000000000000000000000..9449a1161e0242208fe6713b30871de7c1f76cdb --- /dev/null +++ b/backend/data/incidents/deb675dc-b6c6-4898-816d-b3792f64c71f.json @@ -0,0 +1 @@ +{"id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "description": "Tipo: Flood. Ubicaci\u00f3n: Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltima.", "priority": "P0", "status": "new", "signal_ids": ["7ce82058-95e1-4276-8efe-50a6465e1585"], "evidence": [{"id": "5f1add38-20ec-4cc8-99d6-2d134ec9f679", "report_id": "rpt_011", "modality": "text", "description": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de ", "file_path": null, "timestamp": "2026-05-06T01:07:30.481823"}], "location": "Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "coordinates": null, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.481830", "updated_at": "2026-05-06T01:07:30.481832", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/e76d4ac7-3a14-40c5-b13d-ade472600a0a.json b/backend/data/incidents/e76d4ac7-3a14-40c5-b13d-ade472600a0a.json new file mode 100644 index 0000000000000000000000000000000000000000..d0438b539059128fbd5c163b6107ed1af5b21c21 --- /dev/null +++ b/backend/data/incidents/e76d4ac7-3a14-40c5-b13d-ade472600a0a.json @@ -0,0 +1 @@ +{"id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "session_id": "73dc26b4-eb71-4b97-b538-f631ae51a73d", "title": "Inundaci\u00f3n \u2014 Barrio Santa Ana", "description": "Tipo: Flood. Ubicaci\u00f3n: Barrio Santa Ana. Personas afectadas estimadas: 30. Basado en 1 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente.", "priority": "P0", "status": "new", "signal_ids": ["8e263224-838d-4ff4-81f3-1bd3a13eb60f"], "evidence": [{"id": "3090f110-3171-4aa1-988e-b09c119d31fb", "report_id": "7b3cffc4-4d4e-4bb2-9d6d-9373153dc900", "modality": "text", "description": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "file_path": null, "timestamp": "2026-05-06T01:07:30.584348"}], "location": "Barrio Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "confidence": 0.92, "created_at": "2026-05-06T01:07:30.584364", "updated_at": "2026-05-06T01:07:30.584367", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/incidents/fead649a-4200-4465-8223-116c49aed1c5.json b/backend/data/incidents/fead649a-4200-4465-8223-116c49aed1c5.json new file mode 100644 index 0000000000000000000000000000000000000000..503b8cbc80f968166d3be25a8c9520e0c037dcec --- /dev/null +++ b/backend/data/incidents/fead649a-4200-4465-8223-116c49aed1c5.json @@ -0,0 +1 @@ +{"id": "fead649a-4200-4465-8223-116c49aed1c5", "session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "title": "Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar", "description": "Tipo: Flood. Ubicaci\u00f3n: Escuela Sim\u00f3n Bol\u00edvar. Personas afectadas estimadas: 60. Basado en 2 se\u00f1al(es) recibida(s). Reporte m\u00e1s reciente: Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo pi.", "priority": "P0", "status": "new", "signal_ids": ["173d82f5-a505-4829-a2d1-bce3e54b264d", "81391b8f-363c-4d20-9e6b-d6738d4d209e"], "evidence": [{"id": "462ef9c3-55cb-49f4-818c-854eab188d95", "report_id": "rpt_017", "modality": "audio", "description": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos ", "file_path": null, "timestamp": "2026-05-06T01:07:30.481452"}, {"id": "c23a7cbb-2fe8-419f-86ba-83c21c995cfc", "report_id": "rpt_002", "modality": "text", "description": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya", "file_path": null, "timestamp": "2026-05-06T01:07:30.481461"}], "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 60, "confidence": 0.97, "created_at": "2026-05-06T01:07:30.481470", "updated_at": "2026-05-06T01:07:30.481472", "human_approved": false, "notes": null} \ No newline at end of file diff --git a/backend/data/resources/0366ef89-2a8b-4fdd-8e9c-8e5d3dd8fbcc.json b/backend/data/resources/0366ef89-2a8b-4fdd-8e9c-8e5d3dd8fbcc.json new file mode 100644 index 0000000000000000000000000000000000000000..3d291f55a36d3b810bcb509890a6122fcbd63d1b --- /dev/null +++ b/backend/data/resources/0366ef89-2a8b-4fdd-8e9c-8e5d3dd8fbcc.json @@ -0,0 +1 @@ +{"id": "0366ef89-2a8b-4fdd-8e9c-8e5d3dd8fbcc", "incident_id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/05776a34-4ac8-4612-a6e7-f32a0dd87853.json b/backend/data/resources/05776a34-4ac8-4612-a6e7-f32a0dd87853.json new file mode 100644 index 0000000000000000000000000000000000000000..8df6054e25370d302e937c4d9578cc77f901458d --- /dev/null +++ b/backend/data/resources/05776a34-4ac8-4612-a6e7-f32a0dd87853.json @@ -0,0 +1 @@ +{"id": "05776a34-4ac8-4612-a6e7-f32a0dd87853", "incident_id": "87be53a2-1e2a-42c7-ae02-192171266a41", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/0c200c0f-4df5-4d0b-b040-5c147191e46c.json b/backend/data/resources/0c200c0f-4df5-4d0b-b040-5c147191e46c.json new file mode 100644 index 0000000000000000000000000000000000000000..b18a0bdfaa80e700a46eaa6d99940a8d3810c645 --- /dev/null +++ b/backend/data/resources/0c200c0f-4df5-4d0b-b040-5c147191e46c.json @@ -0,0 +1 @@ +{"id": "0c200c0f-4df5-4d0b-b040-5c147191e46c", "incident_id": "1c43f156-18ad-4322-8aa3-725416683112", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/0c8ace71-baae-458c-a684-b821e59d47d2.json b/backend/data/resources/0c8ace71-baae-458c-a684-b821e59d47d2.json new file mode 100644 index 0000000000000000000000000000000000000000..1b3d51e0dda1fde0fc57479b519e6708888985f4 --- /dev/null +++ b/backend/data/resources/0c8ace71-baae-458c-a684-b821e59d47d2.json @@ -0,0 +1 @@ +{"id": "0c8ace71-baae-458c-a684-b821e59d47d2", "incident_id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/0c91128a-5690-4863-803c-dee4d2c0323d.json b/backend/data/resources/0c91128a-5690-4863-803c-dee4d2c0323d.json new file mode 100644 index 0000000000000000000000000000000000000000..33dc86eea5f3687659d409916ed7d535ed83392a --- /dev/null +++ b/backend/data/resources/0c91128a-5690-4863-803c-dee4d2c0323d.json @@ -0,0 +1 @@ +{"id": "0c91128a-5690-4863-803c-dee4d2c0323d", "incident_id": "859c21e7-e963-4712-9c92-5043024542a5", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/0cf6bbd1-cc15-4a8f-8918-6ed20d996958.json b/backend/data/resources/0cf6bbd1-cc15-4a8f-8918-6ed20d996958.json new file mode 100644 index 0000000000000000000000000000000000000000..a6a824c37541952fcee71bc228528697661bb4b5 --- /dev/null +++ b/backend/data/resources/0cf6bbd1-cc15-4a8f-8918-6ed20d996958.json @@ -0,0 +1 @@ +{"id": "0cf6bbd1-cc15-4a8f-8918-6ed20d996958", "incident_id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/10ccba6a-6b00-4616-8a80-c7d5162e9b6a.json b/backend/data/resources/10ccba6a-6b00-4616-8a80-c7d5162e9b6a.json new file mode 100644 index 0000000000000000000000000000000000000000..75d5f4d6b57d370ce9658b2239d593f5f5e03edc --- /dev/null +++ b/backend/data/resources/10ccba6a-6b00-4616-8a80-c7d5162e9b6a.json @@ -0,0 +1 @@ +{"id": "10ccba6a-6b00-4616-8a80-c7d5162e9b6a", "incident_id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/133066fc-d14b-452d-a565-aef702c801d5.json b/backend/data/resources/133066fc-d14b-452d-a565-aef702c801d5.json new file mode 100644 index 0000000000000000000000000000000000000000..70d11ea6c51e3fb1effc395a5b6d773bd8ff9e99 --- /dev/null +++ b/backend/data/resources/133066fc-d14b-452d-a565-aef702c801d5.json @@ -0,0 +1 @@ +{"id": "133066fc-d14b-452d-a565-aef702c801d5", "incident_id": "4588efff-8ded-444f-8d4d-e48651a094ca", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/15b77569-46a0-4aeb-adf0-f5968413d833.json b/backend/data/resources/15b77569-46a0-4aeb-adf0-f5968413d833.json new file mode 100644 index 0000000000000000000000000000000000000000..450731a7921dbf051a88377144338645e47bee6b --- /dev/null +++ b/backend/data/resources/15b77569-46a0-4aeb-adf0-f5968413d833.json @@ -0,0 +1 @@ +{"id": "15b77569-46a0-4aeb-adf0-f5968413d833", "incident_id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/1b164940-4c9a-433c-8331-b86bcb03f627.json b/backend/data/resources/1b164940-4c9a-433c-8331-b86bcb03f627.json new file mode 100644 index 0000000000000000000000000000000000000000..1eca52e785d27c79f243ac3ec24231d05daf7420 --- /dev/null +++ b/backend/data/resources/1b164940-4c9a-433c-8331-b86bcb03f627.json @@ -0,0 +1 @@ +{"id": "1b164940-4c9a-433c-8331-b86bcb03f627", "incident_id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/1b8212d4-e29f-4a48-99d0-4a557f55ff75.json b/backend/data/resources/1b8212d4-e29f-4a48-99d0-4a557f55ff75.json new file mode 100644 index 0000000000000000000000000000000000000000..5a96808df78434b333c24b04e596b398358dad09 --- /dev/null +++ b/backend/data/resources/1b8212d4-e29f-4a48-99d0-4a557f55ff75.json @@ -0,0 +1 @@ +{"id": "1b8212d4-e29f-4a48-99d0-4a557f55ff75", "incident_id": "859c21e7-e963-4712-9c92-5043024542a5", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/1c19c53c-892f-40b8-919a-900b2028fe06.json b/backend/data/resources/1c19c53c-892f-40b8-919a-900b2028fe06.json new file mode 100644 index 0000000000000000000000000000000000000000..f0ac7cdcb731c17fa84fe13d4d21c1bdbd09d7bb --- /dev/null +++ b/backend/data/resources/1c19c53c-892f-40b8-919a-900b2028fe06.json @@ -0,0 +1 @@ +{"id": "1c19c53c-892f-40b8-919a-900b2028fe06", "incident_id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/203fe485-6b73-4f33-b5cd-7df9672e27bb.json b/backend/data/resources/203fe485-6b73-4f33-b5cd-7df9672e27bb.json new file mode 100644 index 0000000000000000000000000000000000000000..06ad56c0dc541b6046215350276c92be035bb40b --- /dev/null +++ b/backend/data/resources/203fe485-6b73-4f33-b5cd-7df9672e27bb.json @@ -0,0 +1 @@ +{"id": "203fe485-6b73-4f33-b5cd-7df9672e27bb", "incident_id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/21181429-6351-41ab-a885-747cccbb8346.json b/backend/data/resources/21181429-6351-41ab-a885-747cccbb8346.json new file mode 100644 index 0000000000000000000000000000000000000000..e9867ad7154a1da2db9bcafbd4100745f2351c2c --- /dev/null +++ b/backend/data/resources/21181429-6351-41ab-a885-747cccbb8346.json @@ -0,0 +1 @@ +{"id": "21181429-6351-41ab-a885-747cccbb8346", "incident_id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/2390d2ef-076a-48c5-8a3d-b7a193ca7c1d.json b/backend/data/resources/2390d2ef-076a-48c5-8a3d-b7a193ca7c1d.json new file mode 100644 index 0000000000000000000000000000000000000000..4f1534cfc9a24e82d7dccf40bdc395159eba0c95 --- /dev/null +++ b/backend/data/resources/2390d2ef-076a-48c5-8a3d-b7a193ca7c1d.json @@ -0,0 +1 @@ +{"id": "2390d2ef-076a-48c5-8a3d-b7a193ca7c1d", "incident_id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/23be17bc-4163-44d3-86d5-c92af0e27b9f.json b/backend/data/resources/23be17bc-4163-44d3-86d5-c92af0e27b9f.json new file mode 100644 index 0000000000000000000000000000000000000000..7eba0fffc96d6f7d313479808dd7ed67250316a7 --- /dev/null +++ b/backend/data/resources/23be17bc-4163-44d3-86d5-c92af0e27b9f.json @@ -0,0 +1 @@ +{"id": "23be17bc-4163-44d3-86d5-c92af0e27b9f", "incident_id": "7de575c3-3ed9-4645-a814-f446bfda0714", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/29fcac53-e111-48b0-8711-2075970ae7e1.json b/backend/data/resources/29fcac53-e111-48b0-8711-2075970ae7e1.json new file mode 100644 index 0000000000000000000000000000000000000000..e8fa075ad0de5feac4e3b17527f7d0f16689329a --- /dev/null +++ b/backend/data/resources/29fcac53-e111-48b0-8711-2075970ae7e1.json @@ -0,0 +1 @@ +{"id": "29fcac53-e111-48b0-8711-2075970ae7e1", "incident_id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/2b3a1434-2629-49af-aa0a-59a3b507e51a.json b/backend/data/resources/2b3a1434-2629-49af-aa0a-59a3b507e51a.json new file mode 100644 index 0000000000000000000000000000000000000000..96b9586ebd78813f685e2b7e4188341b73e2cf34 --- /dev/null +++ b/backend/data/resources/2b3a1434-2629-49af-aa0a-59a3b507e51a.json @@ -0,0 +1 @@ +{"id": "2b3a1434-2629-49af-aa0a-59a3b507e51a", "incident_id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/2f59a045-a0ff-4956-9949-c8d07fa1ae79.json b/backend/data/resources/2f59a045-a0ff-4956-9949-c8d07fa1ae79.json new file mode 100644 index 0000000000000000000000000000000000000000..7370080263921dd11793312ef38c1e1a02ef5ea0 --- /dev/null +++ b/backend/data/resources/2f59a045-a0ff-4956-9949-c8d07fa1ae79.json @@ -0,0 +1 @@ +{"id": "2f59a045-a0ff-4956-9949-c8d07fa1ae79", "incident_id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/326f1d8e-8b1b-49ff-856b-3d9ef873ba93.json b/backend/data/resources/326f1d8e-8b1b-49ff-856b-3d9ef873ba93.json new file mode 100644 index 0000000000000000000000000000000000000000..df9ff041fe5f960414bdb9702d1d9aa6ee018e41 --- /dev/null +++ b/backend/data/resources/326f1d8e-8b1b-49ff-856b-3d9ef873ba93.json @@ -0,0 +1 @@ +{"id": "326f1d8e-8b1b-49ff-856b-3d9ef873ba93", "incident_id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/35ceb34d-4654-43d9-b2d9-382a3bb490aa.json b/backend/data/resources/35ceb34d-4654-43d9-b2d9-382a3bb490aa.json new file mode 100644 index 0000000000000000000000000000000000000000..dff6cc4774d8e0f76fb563104e9bce9d6b6e769c --- /dev/null +++ b/backend/data/resources/35ceb34d-4654-43d9-b2d9-382a3bb490aa.json @@ -0,0 +1 @@ +{"id": "35ceb34d-4654-43d9-b2d9-382a3bb490aa", "incident_id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/38adb879-b399-48e4-8350-9370ff6689b4.json b/backend/data/resources/38adb879-b399-48e4-8350-9370ff6689b4.json new file mode 100644 index 0000000000000000000000000000000000000000..bebb791667b5a80180766258fe8e5a53043b85d4 --- /dev/null +++ b/backend/data/resources/38adb879-b399-48e4-8350-9370ff6689b4.json @@ -0,0 +1 @@ +{"id": "38adb879-b399-48e4-8350-9370ff6689b4", "incident_id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/3c91d90b-0261-4d68-bd99-7ed8199e35f6.json b/backend/data/resources/3c91d90b-0261-4d68-bd99-7ed8199e35f6.json new file mode 100644 index 0000000000000000000000000000000000000000..19ba65cad12a35aa2d3aa165e09ad00963719642 --- /dev/null +++ b/backend/data/resources/3c91d90b-0261-4d68-bd99-7ed8199e35f6.json @@ -0,0 +1 @@ +{"id": "3c91d90b-0261-4d68-bd99-7ed8199e35f6", "incident_id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/4388d29b-2573-46fa-97f3-7072f9192599.json b/backend/data/resources/4388d29b-2573-46fa-97f3-7072f9192599.json new file mode 100644 index 0000000000000000000000000000000000000000..e1776c10c979c5221da0c79f4c0ad8565889fe98 --- /dev/null +++ b/backend/data/resources/4388d29b-2573-46fa-97f3-7072f9192599.json @@ -0,0 +1 @@ +{"id": "4388d29b-2573-46fa-97f3-7072f9192599", "incident_id": "7de575c3-3ed9-4645-a814-f446bfda0714", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/4471fe34-4ad7-4aa2-bd2a-33ab79716331.json b/backend/data/resources/4471fe34-4ad7-4aa2-bd2a-33ab79716331.json new file mode 100644 index 0000000000000000000000000000000000000000..9e377845c4231dd0c96a6f0f39e9d28e549862d9 --- /dev/null +++ b/backend/data/resources/4471fe34-4ad7-4aa2-bd2a-33ab79716331.json @@ -0,0 +1 @@ +{"id": "4471fe34-4ad7-4aa2-bd2a-33ab79716331", "incident_id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/4ae77979-29cd-4b4f-b945-76db2f824bb8.json b/backend/data/resources/4ae77979-29cd-4b4f-b945-76db2f824bb8.json new file mode 100644 index 0000000000000000000000000000000000000000..ae9b85703f1f417450ea30fc90eee6c3592d631c --- /dev/null +++ b/backend/data/resources/4ae77979-29cd-4b4f-b945-76db2f824bb8.json @@ -0,0 +1 @@ +{"id": "4ae77979-29cd-4b4f-b945-76db2f824bb8", "incident_id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/4fdbb6db-18d3-4d29-8ddd-b3a833863dc1.json b/backend/data/resources/4fdbb6db-18d3-4d29-8ddd-b3a833863dc1.json new file mode 100644 index 0000000000000000000000000000000000000000..049944d8a17847a320c087ff56bde0d90d62974f --- /dev/null +++ b/backend/data/resources/4fdbb6db-18d3-4d29-8ddd-b3a833863dc1.json @@ -0,0 +1 @@ +{"id": "4fdbb6db-18d3-4d29-8ddd-b3a833863dc1", "incident_id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/5006c80b-e6c6-4d19-a023-ee17388cde5b.json b/backend/data/resources/5006c80b-e6c6-4d19-a023-ee17388cde5b.json new file mode 100644 index 0000000000000000000000000000000000000000..1228f3947edf2dc7de0ad9c431130b69ff2c664d --- /dev/null +++ b/backend/data/resources/5006c80b-e6c6-4d19-a023-ee17388cde5b.json @@ -0,0 +1 @@ +{"id": "5006c80b-e6c6-4d19-a023-ee17388cde5b", "incident_id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/52206248-060b-419e-8eaa-30c8827753ef.json b/backend/data/resources/52206248-060b-419e-8eaa-30c8827753ef.json new file mode 100644 index 0000000000000000000000000000000000000000..57efc92a9b1199d6d1d3dfaa3f283eaddcdb1161 --- /dev/null +++ b/backend/data/resources/52206248-060b-419e-8eaa-30c8827753ef.json @@ -0,0 +1 @@ +{"id": "52206248-060b-419e-8eaa-30c8827753ef", "incident_id": "fead649a-4200-4465-8223-116c49aed1c5", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/5358ca32-fd3c-4c5c-a98d-653a4f599a8b.json b/backend/data/resources/5358ca32-fd3c-4c5c-a98d-653a4f599a8b.json new file mode 100644 index 0000000000000000000000000000000000000000..c13fb9dc67f6fece90d6aa0b04530bd34cb9ffd8 --- /dev/null +++ b/backend/data/resources/5358ca32-fd3c-4c5c-a98d-653a4f599a8b.json @@ -0,0 +1 @@ +{"id": "5358ca32-fd3c-4c5c-a98d-653a4f599a8b", "incident_id": "fead649a-4200-4465-8223-116c49aed1c5", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/576c9dca-1127-4aed-aa77-0ac9d2bb78ad.json b/backend/data/resources/576c9dca-1127-4aed-aa77-0ac9d2bb78ad.json new file mode 100644 index 0000000000000000000000000000000000000000..200c8c4d6f7d7359b78c2a439150b804b11e025f --- /dev/null +++ b/backend/data/resources/576c9dca-1127-4aed-aa77-0ac9d2bb78ad.json @@ -0,0 +1 @@ +{"id": "576c9dca-1127-4aed-aa77-0ac9d2bb78ad", "incident_id": "7de575c3-3ed9-4645-a814-f446bfda0714", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/58f9d3d1-d1c6-42ce-94e0-d95e5d9a654d.json b/backend/data/resources/58f9d3d1-d1c6-42ce-94e0-d95e5d9a654d.json new file mode 100644 index 0000000000000000000000000000000000000000..c6fe962ff494bf6c3e8aebbb68742d9f6a9b904d --- /dev/null +++ b/backend/data/resources/58f9d3d1-d1c6-42ce-94e0-d95e5d9a654d.json @@ -0,0 +1 @@ +{"id": "58f9d3d1-d1c6-42ce-94e0-d95e5d9a654d", "incident_id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/59534ff5-93d9-4e05-b90f-1a59128ea721.json b/backend/data/resources/59534ff5-93d9-4e05-b90f-1a59128ea721.json new file mode 100644 index 0000000000000000000000000000000000000000..970d982afcc1b8e9a438ff92ff72501393452fe2 --- /dev/null +++ b/backend/data/resources/59534ff5-93d9-4e05-b90f-1a59128ea721.json @@ -0,0 +1 @@ +{"id": "59534ff5-93d9-4e05-b90f-1a59128ea721", "incident_id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/5b6cb298-6485-453e-810a-c8492c6df685.json b/backend/data/resources/5b6cb298-6485-453e-810a-c8492c6df685.json new file mode 100644 index 0000000000000000000000000000000000000000..17fb68aba127aa060cb7b4632bc301349b50dcd6 --- /dev/null +++ b/backend/data/resources/5b6cb298-6485-453e-810a-c8492c6df685.json @@ -0,0 +1 @@ +{"id": "5b6cb298-6485-453e-810a-c8492c6df685", "incident_id": "8c9bc082-90a0-4d8f-a6b2-a538f9688fb7", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/5ca6e344-6b0d-4434-88dc-3010acb904ef.json b/backend/data/resources/5ca6e344-6b0d-4434-88dc-3010acb904ef.json new file mode 100644 index 0000000000000000000000000000000000000000..b699d943cb51afce810f6aed2c803a0bcaacf3a9 --- /dev/null +++ b/backend/data/resources/5ca6e344-6b0d-4434-88dc-3010acb904ef.json @@ -0,0 +1 @@ +{"id": "5ca6e344-6b0d-4434-88dc-3010acb904ef", "incident_id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/5e015de0-4324-41f8-a65d-0975427c972a.json b/backend/data/resources/5e015de0-4324-41f8-a65d-0975427c972a.json new file mode 100644 index 0000000000000000000000000000000000000000..69bcfea0816e89d71378ef6e734ac9a560e91f21 --- /dev/null +++ b/backend/data/resources/5e015de0-4324-41f8-a65d-0975427c972a.json @@ -0,0 +1 @@ +{"id": "5e015de0-4324-41f8-a65d-0975427c972a", "incident_id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/5f07aef1-25ac-46ad-ac3d-c5f30bea9479.json b/backend/data/resources/5f07aef1-25ac-46ad-ac3d-c5f30bea9479.json new file mode 100644 index 0000000000000000000000000000000000000000..8935e0f3f8a9fb86932728522336bbe56e22300b --- /dev/null +++ b/backend/data/resources/5f07aef1-25ac-46ad-ac3d-c5f30bea9479.json @@ -0,0 +1 @@ +{"id": "5f07aef1-25ac-46ad-ac3d-c5f30bea9479", "incident_id": "87be53a2-1e2a-42c7-ae02-192171266a41", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/625289dd-d30d-4005-918c-85ade1cfaec9.json b/backend/data/resources/625289dd-d30d-4005-918c-85ade1cfaec9.json new file mode 100644 index 0000000000000000000000000000000000000000..8f4753429060e2df1bb2306454e68c0f63b4d0f5 --- /dev/null +++ b/backend/data/resources/625289dd-d30d-4005-918c-85ade1cfaec9.json @@ -0,0 +1 @@ +{"id": "625289dd-d30d-4005-918c-85ade1cfaec9", "incident_id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/6804de36-545c-4a50-b44c-10e087feb678.json b/backend/data/resources/6804de36-545c-4a50-b44c-10e087feb678.json new file mode 100644 index 0000000000000000000000000000000000000000..d0e2c40d5ea8cf1e47889268b385d0986a457e92 --- /dev/null +++ b/backend/data/resources/6804de36-545c-4a50-b44c-10e087feb678.json @@ -0,0 +1 @@ +{"id": "6804de36-545c-4a50-b44c-10e087feb678", "incident_id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/683f5179-aeb1-4d54-971b-a50fee99386e.json b/backend/data/resources/683f5179-aeb1-4d54-971b-a50fee99386e.json new file mode 100644 index 0000000000000000000000000000000000000000..60acf49d6d218f7891039cfc7a7efc48970a81ad --- /dev/null +++ b/backend/data/resources/683f5179-aeb1-4d54-971b-a50fee99386e.json @@ -0,0 +1 @@ +{"id": "683f5179-aeb1-4d54-971b-a50fee99386e", "incident_id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/6949efa6-a195-44c5-a216-0c03bc35aba6.json b/backend/data/resources/6949efa6-a195-44c5-a216-0c03bc35aba6.json new file mode 100644 index 0000000000000000000000000000000000000000..ed7c0e3b2b26ef9d975fc86d4966e96608774179 --- /dev/null +++ b/backend/data/resources/6949efa6-a195-44c5-a216-0c03bc35aba6.json @@ -0,0 +1 @@ +{"id": "6949efa6-a195-44c5-a216-0c03bc35aba6", "incident_id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/6a25a0e6-8076-408a-92c7-a722616b8199.json b/backend/data/resources/6a25a0e6-8076-408a-92c7-a722616b8199.json new file mode 100644 index 0000000000000000000000000000000000000000..c5e795c93d9a829843c0f4d54c3b2fcc4f1d7087 --- /dev/null +++ b/backend/data/resources/6a25a0e6-8076-408a-92c7-a722616b8199.json @@ -0,0 +1 @@ +{"id": "6a25a0e6-8076-408a-92c7-a722616b8199", "incident_id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/6acb17f2-da18-456b-bd7a-aef181ae5f75.json b/backend/data/resources/6acb17f2-da18-456b-bd7a-aef181ae5f75.json new file mode 100644 index 0000000000000000000000000000000000000000..3c9bea2ea30a0ea4d1f076cbb267990e21b700a2 --- /dev/null +++ b/backend/data/resources/6acb17f2-da18-456b-bd7a-aef181ae5f75.json @@ -0,0 +1 @@ +{"id": "6acb17f2-da18-456b-bd7a-aef181ae5f75", "incident_id": "6cac476b-78e0-4226-b31f-1839b7185642", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/73b6283e-2922-404c-a06b-a79bbdf250b4.json b/backend/data/resources/73b6283e-2922-404c-a06b-a79bbdf250b4.json new file mode 100644 index 0000000000000000000000000000000000000000..8355243ecb910d81e17bcabd805e0e3ee545c5e2 --- /dev/null +++ b/backend/data/resources/73b6283e-2922-404c-a06b-a79bbdf250b4.json @@ -0,0 +1 @@ +{"id": "73b6283e-2922-404c-a06b-a79bbdf250b4", "incident_id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/76d561f0-2997-43b6-89da-d723b3feb908.json b/backend/data/resources/76d561f0-2997-43b6-89da-d723b3feb908.json new file mode 100644 index 0000000000000000000000000000000000000000..1691aa4d3b6acdd360b2ee96f3efc747707c322c --- /dev/null +++ b/backend/data/resources/76d561f0-2997-43b6-89da-d723b3feb908.json @@ -0,0 +1 @@ +{"id": "76d561f0-2997-43b6-89da-d723b3feb908", "incident_id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/78af6c73-bd93-45d4-bab4-c07e1633f9e8.json b/backend/data/resources/78af6c73-bd93-45d4-bab4-c07e1633f9e8.json new file mode 100644 index 0000000000000000000000000000000000000000..db96e20f270b87480e90dae581d663c99fd8e774 --- /dev/null +++ b/backend/data/resources/78af6c73-bd93-45d4-bab4-c07e1633f9e8.json @@ -0,0 +1 @@ +{"id": "78af6c73-bd93-45d4-bab4-c07e1633f9e8", "incident_id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/791d1c39-7b56-4dee-bd77-9d30be31d578.json b/backend/data/resources/791d1c39-7b56-4dee-bd77-9d30be31d578.json new file mode 100644 index 0000000000000000000000000000000000000000..8c32737c100a715c05ba07c7260b5e0a6b49a058 --- /dev/null +++ b/backend/data/resources/791d1c39-7b56-4dee-bd77-9d30be31d578.json @@ -0,0 +1 @@ +{"id": "791d1c39-7b56-4dee-bd77-9d30be31d578", "incident_id": "33d7f7b1-754e-45d4-affe-e806d18290d7", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/7d518d0b-5b4c-49d1-b05c-4895791f1b33.json b/backend/data/resources/7d518d0b-5b4c-49d1-b05c-4895791f1b33.json new file mode 100644 index 0000000000000000000000000000000000000000..85a706b48955f1ed0664cf7a4e3bf051595b8aa4 --- /dev/null +++ b/backend/data/resources/7d518d0b-5b4c-49d1-b05c-4895791f1b33.json @@ -0,0 +1 @@ +{"id": "7d518d0b-5b4c-49d1-b05c-4895791f1b33", "incident_id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/7e6cabbc-f2ae-4ab3-9367-8af7525c5ceb.json b/backend/data/resources/7e6cabbc-f2ae-4ab3-9367-8af7525c5ceb.json new file mode 100644 index 0000000000000000000000000000000000000000..aac74112e0073765d12dd0088e3aa427e2c2ccd4 --- /dev/null +++ b/backend/data/resources/7e6cabbc-f2ae-4ab3-9367-8af7525c5ceb.json @@ -0,0 +1 @@ +{"id": "7e6cabbc-f2ae-4ab3-9367-8af7525c5ceb", "incident_id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/8ae074a0-5578-4c50-bcff-266f574bd471.json b/backend/data/resources/8ae074a0-5578-4c50-bcff-266f574bd471.json new file mode 100644 index 0000000000000000000000000000000000000000..57db3a78a1592d73f580bcb4d5c98375fea3d638 --- /dev/null +++ b/backend/data/resources/8ae074a0-5578-4c50-bcff-266f574bd471.json @@ -0,0 +1 @@ +{"id": "8ae074a0-5578-4c50-bcff-266f574bd471", "incident_id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/8d6107cd-c294-4364-8bdc-a14e52073fc6.json b/backend/data/resources/8d6107cd-c294-4364-8bdc-a14e52073fc6.json new file mode 100644 index 0000000000000000000000000000000000000000..17c9a64bf4de4d7a27b4da9fcf32613d87d3cfe6 --- /dev/null +++ b/backend/data/resources/8d6107cd-c294-4364-8bdc-a14e52073fc6.json @@ -0,0 +1 @@ +{"id": "8d6107cd-c294-4364-8bdc-a14e52073fc6", "incident_id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/8e16a46e-441d-42d4-941b-410777272dfc.json b/backend/data/resources/8e16a46e-441d-42d4-941b-410777272dfc.json new file mode 100644 index 0000000000000000000000000000000000000000..d9235994f63392ae29319d2f6510a846d6ecd192 --- /dev/null +++ b/backend/data/resources/8e16a46e-441d-42d4-941b-410777272dfc.json @@ -0,0 +1 @@ +{"id": "8e16a46e-441d-42d4-941b-410777272dfc", "incident_id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/906cd174-b191-4a12-b4c6-91332da23da0.json b/backend/data/resources/906cd174-b191-4a12-b4c6-91332da23da0.json new file mode 100644 index 0000000000000000000000000000000000000000..b08fc304f2667d220966f6271b128c3fa22a0381 --- /dev/null +++ b/backend/data/resources/906cd174-b191-4a12-b4c6-91332da23da0.json @@ -0,0 +1 @@ +{"id": "906cd174-b191-4a12-b4c6-91332da23da0", "incident_id": "1c43f156-18ad-4322-8aa3-725416683112", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/92e0543d-4527-4cfa-9406-0134c094a9fc.json b/backend/data/resources/92e0543d-4527-4cfa-9406-0134c094a9fc.json new file mode 100644 index 0000000000000000000000000000000000000000..568574ff53863b25db453ab9630987ea116977bd --- /dev/null +++ b/backend/data/resources/92e0543d-4527-4cfa-9406-0134c094a9fc.json @@ -0,0 +1 @@ +{"id": "92e0543d-4527-4cfa-9406-0134c094a9fc", "incident_id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/943f2de7-026b-4d36-aa23-dce3de2fa66c.json b/backend/data/resources/943f2de7-026b-4d36-aa23-dce3de2fa66c.json new file mode 100644 index 0000000000000000000000000000000000000000..af94232141571fb26d8c8ad1efaea7797e776727 --- /dev/null +++ b/backend/data/resources/943f2de7-026b-4d36-aa23-dce3de2fa66c.json @@ -0,0 +1 @@ +{"id": "943f2de7-026b-4d36-aa23-dce3de2fa66c", "incident_id": "87be53a2-1e2a-42c7-ae02-192171266a41", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/94534f66-3c79-46ed-b508-066f5a03b6da.json b/backend/data/resources/94534f66-3c79-46ed-b508-066f5a03b6da.json new file mode 100644 index 0000000000000000000000000000000000000000..142c0f65bc4351f260433a5e75a7646cf34f1510 --- /dev/null +++ b/backend/data/resources/94534f66-3c79-46ed-b508-066f5a03b6da.json @@ -0,0 +1 @@ +{"id": "94534f66-3c79-46ed-b508-066f5a03b6da", "incident_id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/965f3378-1413-4d1a-91ed-ad48965816bb.json b/backend/data/resources/965f3378-1413-4d1a-91ed-ad48965816bb.json new file mode 100644 index 0000000000000000000000000000000000000000..292d18fabca9521f2249e348f9ca3021811b5654 --- /dev/null +++ b/backend/data/resources/965f3378-1413-4d1a-91ed-ad48965816bb.json @@ -0,0 +1 @@ +{"id": "965f3378-1413-4d1a-91ed-ad48965816bb", "incident_id": "4588efff-8ded-444f-8d4d-e48651a094ca", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/96c68b54-17ec-4e68-ad2e-9744df469e04.json b/backend/data/resources/96c68b54-17ec-4e68-ad2e-9744df469e04.json new file mode 100644 index 0000000000000000000000000000000000000000..1eabc155d28636b264ee209dbe59210cd68084f4 --- /dev/null +++ b/backend/data/resources/96c68b54-17ec-4e68-ad2e-9744df469e04.json @@ -0,0 +1 @@ +{"id": "96c68b54-17ec-4e68-ad2e-9744df469e04", "incident_id": "1c43f156-18ad-4322-8aa3-725416683112", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/98514e1c-f70c-4b67-b7d5-40ed0ede934a.json b/backend/data/resources/98514e1c-f70c-4b67-b7d5-40ed0ede934a.json new file mode 100644 index 0000000000000000000000000000000000000000..48abc70d09ac8f0141383ebde0e254dc92ea07e4 --- /dev/null +++ b/backend/data/resources/98514e1c-f70c-4b67-b7d5-40ed0ede934a.json @@ -0,0 +1 @@ +{"id": "98514e1c-f70c-4b67-b7d5-40ed0ede934a", "incident_id": "6cac476b-78e0-4226-b31f-1839b7185642", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/9d5246c2-852b-4e5d-80c3-8c895601259a.json b/backend/data/resources/9d5246c2-852b-4e5d-80c3-8c895601259a.json new file mode 100644 index 0000000000000000000000000000000000000000..9a16cab21f1682447f68d6d59e2953e8cf9e021e --- /dev/null +++ b/backend/data/resources/9d5246c2-852b-4e5d-80c3-8c895601259a.json @@ -0,0 +1 @@ +{"id": "9d5246c2-852b-4e5d-80c3-8c895601259a", "incident_id": "deb675dc-b6c6-4898-816d-b3792f64c71f", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/9e1c7e92-2cb9-493e-a40b-852ddeab533f.json b/backend/data/resources/9e1c7e92-2cb9-493e-a40b-852ddeab533f.json new file mode 100644 index 0000000000000000000000000000000000000000..8f14a72c848e1cf4cc124f7c77fe344340772c8e --- /dev/null +++ b/backend/data/resources/9e1c7e92-2cb9-493e-a40b-852ddeab533f.json @@ -0,0 +1 @@ +{"id": "9e1c7e92-2cb9-493e-a40b-852ddeab533f", "incident_id": "58be1c76-fc6e-425b-9264-8228074add3e", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/9ef6fb98-e4fa-4a2e-be07-7305fd4e86a2.json b/backend/data/resources/9ef6fb98-e4fa-4a2e-be07-7305fd4e86a2.json new file mode 100644 index 0000000000000000000000000000000000000000..2146b61ff4322a1d0278b1bbc6fa99f43f627a30 --- /dev/null +++ b/backend/data/resources/9ef6fb98-e4fa-4a2e-be07-7305fd4e86a2.json @@ -0,0 +1 @@ +{"id": "9ef6fb98-e4fa-4a2e-be07-7305fd4e86a2", "incident_id": "fead649a-4200-4465-8223-116c49aed1c5", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/a075063b-1d5b-4b88-b51d-8fd9ce782194.json b/backend/data/resources/a075063b-1d5b-4b88-b51d-8fd9ce782194.json new file mode 100644 index 0000000000000000000000000000000000000000..5591def31b92be2b75a42ca46a4e1b2c40954335 --- /dev/null +++ b/backend/data/resources/a075063b-1d5b-4b88-b51d-8fd9ce782194.json @@ -0,0 +1 @@ +{"id": "a075063b-1d5b-4b88-b51d-8fd9ce782194", "incident_id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/a08d339a-882f-4346-bdbf-d4c7efd946dd.json b/backend/data/resources/a08d339a-882f-4346-bdbf-d4c7efd946dd.json new file mode 100644 index 0000000000000000000000000000000000000000..d9e6284a9154f6b286c5fb75b392be1023b2c9f4 --- /dev/null +++ b/backend/data/resources/a08d339a-882f-4346-bdbf-d4c7efd946dd.json @@ -0,0 +1 @@ +{"id": "a08d339a-882f-4346-bdbf-d4c7efd946dd", "incident_id": "58be1c76-fc6e-425b-9264-8228074add3e", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/a3c83b95-9fef-41b9-8831-a02d9ba0006a.json b/backend/data/resources/a3c83b95-9fef-41b9-8831-a02d9ba0006a.json new file mode 100644 index 0000000000000000000000000000000000000000..11396446c6666e91292fc54cdea509cca2d615cf --- /dev/null +++ b/backend/data/resources/a3c83b95-9fef-41b9-8831-a02d9ba0006a.json @@ -0,0 +1 @@ +{"id": "a3c83b95-9fef-41b9-8831-a02d9ba0006a", "incident_id": "fead649a-4200-4465-8223-116c49aed1c5", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/a3da0a54-e196-4948-8ddd-fa38ded19f37.json b/backend/data/resources/a3da0a54-e196-4948-8ddd-fa38ded19f37.json new file mode 100644 index 0000000000000000000000000000000000000000..8fe83cd0b7f8f48fad56c193670281b50418e19a --- /dev/null +++ b/backend/data/resources/a3da0a54-e196-4948-8ddd-fa38ded19f37.json @@ -0,0 +1 @@ +{"id": "a3da0a54-e196-4948-8ddd-fa38ded19f37", "incident_id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/a4840195-147d-4484-88e2-537ebce20a8b.json b/backend/data/resources/a4840195-147d-4484-88e2-537ebce20a8b.json new file mode 100644 index 0000000000000000000000000000000000000000..e49b3b658f80fb8fdff44c5a06e5f72de0ec80ab --- /dev/null +++ b/backend/data/resources/a4840195-147d-4484-88e2-537ebce20a8b.json @@ -0,0 +1 @@ +{"id": "a4840195-147d-4484-88e2-537ebce20a8b", "incident_id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/a6998357-7cce-4211-85fc-8183a41ce41f.json b/backend/data/resources/a6998357-7cce-4211-85fc-8183a41ce41f.json new file mode 100644 index 0000000000000000000000000000000000000000..3ada08ce09a2e0f92ba84185a390b7e9fb1edfcc --- /dev/null +++ b/backend/data/resources/a6998357-7cce-4211-85fc-8183a41ce41f.json @@ -0,0 +1 @@ +{"id": "a6998357-7cce-4211-85fc-8183a41ce41f", "incident_id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/a7e01a1c-5c1c-4fb4-9962-339fd9326710.json b/backend/data/resources/a7e01a1c-5c1c-4fb4-9962-339fd9326710.json new file mode 100644 index 0000000000000000000000000000000000000000..3d7e05438ad4fdf7c7a6cdaff43fb9db3a337da7 --- /dev/null +++ b/backend/data/resources/a7e01a1c-5c1c-4fb4-9962-339fd9326710.json @@ -0,0 +1 @@ +{"id": "a7e01a1c-5c1c-4fb4-9962-339fd9326710", "incident_id": "6cac476b-78e0-4226-b31f-1839b7185642", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/a947aaf3-6891-4bee-8e6b-b82150dedd6d.json b/backend/data/resources/a947aaf3-6891-4bee-8e6b-b82150dedd6d.json new file mode 100644 index 0000000000000000000000000000000000000000..810b1fa0421b67a90d8ff437b58f8859fd82e19b --- /dev/null +++ b/backend/data/resources/a947aaf3-6891-4bee-8e6b-b82150dedd6d.json @@ -0,0 +1 @@ +{"id": "a947aaf3-6891-4bee-8e6b-b82150dedd6d", "incident_id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/ac5d4a53-3622-4b3a-bb4e-d7d3547fed0b.json b/backend/data/resources/ac5d4a53-3622-4b3a-bb4e-d7d3547fed0b.json new file mode 100644 index 0000000000000000000000000000000000000000..30be366e65d5ff3da6646e2b1b12a4a7dc6a2b37 --- /dev/null +++ b/backend/data/resources/ac5d4a53-3622-4b3a-bb4e-d7d3547fed0b.json @@ -0,0 +1 @@ +{"id": "ac5d4a53-3622-4b3a-bb4e-d7d3547fed0b", "incident_id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/b57af0a3-ad9a-4e89-8cd7-c9be3c8f7e19.json b/backend/data/resources/b57af0a3-ad9a-4e89-8cd7-c9be3c8f7e19.json new file mode 100644 index 0000000000000000000000000000000000000000..b821ccb0e783f862b74fc47f0c84dbee4c69fab5 --- /dev/null +++ b/backend/data/resources/b57af0a3-ad9a-4e89-8cd7-c9be3c8f7e19.json @@ -0,0 +1 @@ +{"id": "b57af0a3-ad9a-4e89-8cd7-c9be3c8f7e19", "incident_id": "58be1c76-fc6e-425b-9264-8228074add3e", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/bb37d006-7b03-4698-9c62-1bde073d3208.json b/backend/data/resources/bb37d006-7b03-4698-9c62-1bde073d3208.json new file mode 100644 index 0000000000000000000000000000000000000000..eb8caac705f0882c105790b6d1ec5b6617976b0c --- /dev/null +++ b/backend/data/resources/bb37d006-7b03-4698-9c62-1bde073d3208.json @@ -0,0 +1 @@ +{"id": "bb37d006-7b03-4698-9c62-1bde073d3208", "incident_id": "7c27eb5f-0250-40f8-ae0b-8384e5933ee7", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/bc10a119-b122-4a49-9376-62286c5be6a9.json b/backend/data/resources/bc10a119-b122-4a49-9376-62286c5be6a9.json new file mode 100644 index 0000000000000000000000000000000000000000..ec50f90702308ee13cedac123a99fb84ae266394 --- /dev/null +++ b/backend/data/resources/bc10a119-b122-4a49-9376-62286c5be6a9.json @@ -0,0 +1 @@ +{"id": "bc10a119-b122-4a49-9376-62286c5be6a9", "incident_id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/bd09c4a6-870c-4e1f-ad25-ec641c59c04f.json b/backend/data/resources/bd09c4a6-870c-4e1f-ad25-ec641c59c04f.json new file mode 100644 index 0000000000000000000000000000000000000000..df4ade3882d5f5d8cd24ac5d2743499b3702e2b0 --- /dev/null +++ b/backend/data/resources/bd09c4a6-870c-4e1f-ad25-ec641c59c04f.json @@ -0,0 +1 @@ +{"id": "bd09c4a6-870c-4e1f-ad25-ec641c59c04f", "incident_id": "4588efff-8ded-444f-8d4d-e48651a094ca", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/bd7a2ca6-7f53-4ba6-9ce3-411cf5d925b0.json b/backend/data/resources/bd7a2ca6-7f53-4ba6-9ce3-411cf5d925b0.json new file mode 100644 index 0000000000000000000000000000000000000000..07bb649a3c836a89966b362860a8e542d0a366c8 --- /dev/null +++ b/backend/data/resources/bd7a2ca6-7f53-4ba6-9ce3-411cf5d925b0.json @@ -0,0 +1 @@ +{"id": "bd7a2ca6-7f53-4ba6-9ce3-411cf5d925b0", "incident_id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/resources/c077b496-b8e3-4323-b75e-187f079eaa3b.json b/backend/data/resources/c077b496-b8e3-4323-b75e-187f079eaa3b.json new file mode 100644 index 0000000000000000000000000000000000000000..8b36e923038513bad980e9131ac6f2be282792bd --- /dev/null +++ b/backend/data/resources/c077b496-b8e3-4323-b75e-187f079eaa3b.json @@ -0,0 +1 @@ +{"id": "c077b496-b8e3-4323-b75e-187f079eaa3b", "incident_id": "4588efff-8ded-444f-8d4d-e48651a094ca", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/c1abb7c6-0673-46b8-9281-2a4e1429971d.json b/backend/data/resources/c1abb7c6-0673-46b8-9281-2a4e1429971d.json new file mode 100644 index 0000000000000000000000000000000000000000..e928a645b21f0ff7200d3446153b3b209641160f --- /dev/null +++ b/backend/data/resources/c1abb7c6-0673-46b8-9281-2a4e1429971d.json @@ -0,0 +1 @@ +{"id": "c1abb7c6-0673-46b8-9281-2a4e1429971d", "incident_id": "8d188c4a-e2f9-484d-a3d3-afad983a0ffa", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/c39d762c-6477-4f41-a6c7-68142e9f1a35.json b/backend/data/resources/c39d762c-6477-4f41-a6c7-68142e9f1a35.json new file mode 100644 index 0000000000000000000000000000000000000000..3c46e3e9cdd5c6d3d7b75d3388619eccc9a1fcef --- /dev/null +++ b/backend/data/resources/c39d762c-6477-4f41-a6c7-68142e9f1a35.json @@ -0,0 +1 @@ +{"id": "c39d762c-6477-4f41-a6c7-68142e9f1a35", "incident_id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/c3d7846b-afb3-4428-87af-a7296e00afc6.json b/backend/data/resources/c3d7846b-afb3-4428-87af-a7296e00afc6.json new file mode 100644 index 0000000000000000000000000000000000000000..02a1c024f5689887332d86529d70901a5a5607b5 --- /dev/null +++ b/backend/data/resources/c3d7846b-afb3-4428-87af-a7296e00afc6.json @@ -0,0 +1 @@ +{"id": "c3d7846b-afb3-4428-87af-a7296e00afc6", "incident_id": "7de575c3-3ed9-4645-a814-f446bfda0714", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/cba07a06-3a84-4a35-acba-82c166846bf6.json b/backend/data/resources/cba07a06-3a84-4a35-acba-82c166846bf6.json new file mode 100644 index 0000000000000000000000000000000000000000..aaf8a06bdf7536ef2f1a27635febf154556201f9 --- /dev/null +++ b/backend/data/resources/cba07a06-3a84-4a35-acba-82c166846bf6.json @@ -0,0 +1 @@ +{"id": "cba07a06-3a84-4a35-acba-82c166846bf6", "incident_id": "58be1c76-fc6e-425b-9264-8228074add3e", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/ccdec0f4-3360-40af-8ee1-3c426d7cf0df.json b/backend/data/resources/ccdec0f4-3360-40af-8ee1-3c426d7cf0df.json new file mode 100644 index 0000000000000000000000000000000000000000..add24f333fdd85d689b9c9517babdb523a28d926 --- /dev/null +++ b/backend/data/resources/ccdec0f4-3360-40af-8ee1-3c426d7cf0df.json @@ -0,0 +1 @@ +{"id": "ccdec0f4-3360-40af-8ee1-3c426d7cf0df", "incident_id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/d02521df-029b-4c8e-bf37-21c14b7a8e89.json b/backend/data/resources/d02521df-029b-4c8e-bf37-21c14b7a8e89.json new file mode 100644 index 0000000000000000000000000000000000000000..7534e33e4685b67f805268a6ad711dc73421935a --- /dev/null +++ b/backend/data/resources/d02521df-029b-4c8e-bf37-21c14b7a8e89.json @@ -0,0 +1 @@ +{"id": "d02521df-029b-4c8e-bf37-21c14b7a8e89", "incident_id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/d02e34a8-368f-4034-ba9a-db77fa3172c0.json b/backend/data/resources/d02e34a8-368f-4034-ba9a-db77fa3172c0.json new file mode 100644 index 0000000000000000000000000000000000000000..5d2308a6d8b969091ac92ebf65f6d6df450fdd6e --- /dev/null +++ b/backend/data/resources/d02e34a8-368f-4034-ba9a-db77fa3172c0.json @@ -0,0 +1 @@ +{"id": "d02e34a8-368f-4034-ba9a-db77fa3172c0", "incident_id": "1816328e-f3ed-4e13-a87d-552b278a58a1", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/d0acd4b5-7354-4219-8d0b-a3e3e68cb136.json b/backend/data/resources/d0acd4b5-7354-4219-8d0b-a3e3e68cb136.json new file mode 100644 index 0000000000000000000000000000000000000000..575009b392906d237a03a99a83f941f8eb08b28c --- /dev/null +++ b/backend/data/resources/d0acd4b5-7354-4219-8d0b-a3e3e68cb136.json @@ -0,0 +1 @@ +{"id": "d0acd4b5-7354-4219-8d0b-a3e3e68cb136", "incident_id": "1c43f156-18ad-4322-8aa3-725416683112", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/d7126cbf-88fe-4314-aced-35edf5869d97.json b/backend/data/resources/d7126cbf-88fe-4314-aced-35edf5869d97.json new file mode 100644 index 0000000000000000000000000000000000000000..8e14b2f223067155eea8e6a639b909fa04450910 --- /dev/null +++ b/backend/data/resources/d7126cbf-88fe-4314-aced-35edf5869d97.json @@ -0,0 +1 @@ +{"id": "d7126cbf-88fe-4314-aced-35edf5869d97", "incident_id": "e76d4ac7-3a14-40c5-b13d-ade472600a0a", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/dadd8a2b-d03c-4608-b631-54eb50d677f0.json b/backend/data/resources/dadd8a2b-d03c-4608-b631-54eb50d677f0.json new file mode 100644 index 0000000000000000000000000000000000000000..43337555897cd693df26610441e894b2239b955a --- /dev/null +++ b/backend/data/resources/dadd8a2b-d03c-4608-b631-54eb50d677f0.json @@ -0,0 +1 @@ +{"id": "dadd8a2b-d03c-4608-b631-54eb50d677f0", "incident_id": "859c21e7-e963-4712-9c92-5043024542a5", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/dbefdb71-3fd8-4211-90b8-4e2a3338d3a8.json b/backend/data/resources/dbefdb71-3fd8-4211-90b8-4e2a3338d3a8.json new file mode 100644 index 0000000000000000000000000000000000000000..a878567fb266004243fae40918b513e34354b158 --- /dev/null +++ b/backend/data/resources/dbefdb71-3fd8-4211-90b8-4e2a3338d3a8.json @@ -0,0 +1 @@ +{"id": "dbefdb71-3fd8-4211-90b8-4e2a3338d3a8", "incident_id": "2b4eb726-bd0c-4ead-a1e1-f3a27a0ac326", "resource_type": "water", "description": "Agua potable embotellada", "quantity": 200, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/ddbe9701-de0c-48a9-bb1e-117f0f483b84.json b/backend/data/resources/ddbe9701-de0c-48a9-bb1e-117f0f483b84.json new file mode 100644 index 0000000000000000000000000000000000000000..ba46e804bb5982e513afccb2f3931d02c27c87ce --- /dev/null +++ b/backend/data/resources/ddbe9701-de0c-48a9-bb1e-117f0f483b84.json @@ -0,0 +1 @@ +{"id": "ddbe9701-de0c-48a9-bb1e-117f0f483b84", "incident_id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/dfe7d8e7-2aa2-4775-bbfb-da304544eab5.json b/backend/data/resources/dfe7d8e7-2aa2-4775-bbfb-da304544eab5.json new file mode 100644 index 0000000000000000000000000000000000000000..ad19fcd08c29ee2eba9360723b01d597fd25f74e --- /dev/null +++ b/backend/data/resources/dfe7d8e7-2aa2-4775-bbfb-da304544eab5.json @@ -0,0 +1 @@ +{"id": "dfe7d8e7-2aa2-4775-bbfb-da304544eab5", "incident_id": "53250214-30ee-4f0b-8be8-5b04aed8e1ef", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Barrio Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/e2a88688-36af-4f2d-9cc5-c1085de22be9.json b/backend/data/resources/e2a88688-36af-4f2d-9cc5-c1085de22be9.json new file mode 100644 index 0000000000000000000000000000000000000000..83d2e0ce228fad0101cd52bac01f5dae075b67c9 --- /dev/null +++ b/backend/data/resources/e2a88688-36af-4f2d-9cc5-c1085de22be9.json @@ -0,0 +1 @@ +{"id": "e2a88688-36af-4f2d-9cc5-c1085de22be9", "incident_id": "6cac476b-78e0-4226-b31f-1839b7185642", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Santa Ana"} \ No newline at end of file diff --git a/backend/data/resources/e4a2107a-ea95-4797-ab1b-69b62d6de64b.json b/backend/data/resources/e4a2107a-ea95-4797-ab1b-69b62d6de64b.json new file mode 100644 index 0000000000000000000000000000000000000000..d308f70d7a5d6c312d141edda3051d310a55b916 --- /dev/null +++ b/backend/data/resources/e4a2107a-ea95-4797-ab1b-69b62d6de64b.json @@ -0,0 +1 @@ +{"id": "e4a2107a-ea95-4797-ab1b-69b62d6de64b", "incident_id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/e6c087c5-c0dd-498e-be90-86c24c33e8c3.json b/backend/data/resources/e6c087c5-c0dd-498e-be90-86c24c33e8c3.json new file mode 100644 index 0000000000000000000000000000000000000000..cea5e4795d2e18ec7c12983861c7c4dc04d86d9a --- /dev/null +++ b/backend/data/resources/e6c087c5-c0dd-498e-be90-86c24c33e8c3.json @@ -0,0 +1 @@ +{"id": "e6c087c5-c0dd-498e-be90-86c24c33e8c3", "incident_id": "5e88dc0d-5c0c-4b05-98cf-0674cd48392a", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/ee65e824-bb2a-412a-8871-bce2b4db4fa7.json b/backend/data/resources/ee65e824-bb2a-412a-8871-bce2b4db4fa7.json new file mode 100644 index 0000000000000000000000000000000000000000..e5396f472476d52481251fd2fc8c3c66ede148d5 --- /dev/null +++ b/backend/data/resources/ee65e824-bb2a-412a-8871-bce2b4db4fa7.json @@ -0,0 +1 @@ +{"id": "ee65e824-bb2a-412a-8871-bce2b4db4fa7", "incident_id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/f10adb18-ff4f-4e42-874a-33758c765701.json b/backend/data/resources/f10adb18-ff4f-4e42-874a-33758c765701.json new file mode 100644 index 0000000000000000000000000000000000000000..91992a7b4ec40cd1e8881567fc2973f8438aeeaa --- /dev/null +++ b/backend/data/resources/f10adb18-ff4f-4e42-874a-33758c765701.json @@ -0,0 +1 @@ +{"id": "f10adb18-ff4f-4e42-874a-33758c765701", "incident_id": "87be53a2-1e2a-42c7-ae02-192171266a41", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Centro Comunitario"} \ No newline at end of file diff --git a/backend/data/resources/f32e4115-8209-4873-a460-07a2aa36183d.json b/backend/data/resources/f32e4115-8209-4873-a460-07a2aa36183d.json new file mode 100644 index 0000000000000000000000000000000000000000..5a706c841221e98c644ac334be84a137ff6f28f3 --- /dev/null +++ b/backend/data/resources/f32e4115-8209-4873-a460-07a2aa36183d.json @@ -0,0 +1 @@ +{"id": "f32e4115-8209-4873-a460-07a2aa36183d", "incident_id": "3ca30150-55ab-4145-b07e-9e68e1be89b5", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/f482deea-905c-4258-8231-a6aac2a6633b.json b/backend/data/resources/f482deea-905c-4258-8231-a6aac2a6633b.json new file mode 100644 index 0000000000000000000000000000000000000000..945ba2d28fc208b7303d0250233eb250d7c0c2a7 --- /dev/null +++ b/backend/data/resources/f482deea-905c-4258-8231-a6aac2a6633b.json @@ -0,0 +1 @@ +{"id": "f482deea-905c-4258-8231-a6aac2a6633b", "incident_id": "9ca75909-d9ea-49ad-90e0-e371a8b3576c", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Sucre Est\u00e1 Completamente Inundada"} \ No newline at end of file diff --git a/backend/data/resources/f5606747-2d4c-44ff-adec-85ca2604f63a.json b/backend/data/resources/f5606747-2d4c-44ff-adec-85ca2604f63a.json new file mode 100644 index 0000000000000000000000000000000000000000..a002957a0f6feea31a654eef846c8e9f6d7de00f --- /dev/null +++ b/backend/data/resources/f5606747-2d4c-44ff-adec-85ca2604f63a.json @@ -0,0 +1 @@ +{"id": "f5606747-2d4c-44ff-adec-85ca2604f63a", "incident_id": "3795aa64-71da-425d-9284-5a3dcd04a63c", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bolivar"} \ No newline at end of file diff --git a/backend/data/resources/f63bd386-2e49-4ae7-a2ac-3e3e00e1379b.json b/backend/data/resources/f63bd386-2e49-4ae7-a2ac-3e3e00e1379b.json new file mode 100644 index 0000000000000000000000000000000000000000..d7a905d5c46494493d7b9fe6630501adf71add6e --- /dev/null +++ b/backend/data/resources/f63bd386-2e49-4ae7-a2ac-3e3e00e1379b.json @@ -0,0 +1 @@ +{"id": "f63bd386-2e49-4ae7-a2ac-3e3e00e1379b", "incident_id": "cc64a7fe-38af-4e72-b78b-eb05aa3176e8", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector El Progreso Informamos Que El Nivel Del "} \ No newline at end of file diff --git a/backend/data/resources/f8d43610-afe8-4339-bbaa-af42e07752b3.json b/backend/data/resources/f8d43610-afe8-4339-bbaa-af42e07752b3.json new file mode 100644 index 0000000000000000000000000000000000000000..00ac87b1970329a4fece58b770a6f4463a6a48e2 --- /dev/null +++ b/backend/data/resources/f8d43610-afe8-4339-bbaa-af42e07752b3.json @@ -0,0 +1 @@ +{"id": "f8d43610-afe8-4339-bbaa-af42e07752b3", "incident_id": "859c21e7-e963-4712-9c92-5043024542a5", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Av. Principal"} \ No newline at end of file diff --git a/backend/data/resources/fb75d77e-9260-4a4f-ac9e-4f192c40d332.json b/backend/data/resources/fb75d77e-9260-4a4f-ac9e-4f192c40d332.json new file mode 100644 index 0000000000000000000000000000000000000000..b8ebabf2cd603f798fde8b0241122fe6a8432f79 --- /dev/null +++ b/backend/data/resources/fb75d77e-9260-4a4f-ac9e-4f192c40d332.json @@ -0,0 +1 @@ +{"id": "fb75d77e-9260-4a4f-ac9e-4f192c40d332", "incident_id": "d822f7fa-4500-42f4-a4d7-ce5465c38c01", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Calle Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/fc17b663-355f-4d98-ab83-8143a87021c6.json b/backend/data/resources/fc17b663-355f-4d98-ab83-8143a87021c6.json new file mode 100644 index 0000000000000000000000000000000000000000..1d3ebed19a755c2289073f6f4be2e23b766ccd0c --- /dev/null +++ b/backend/data/resources/fc17b663-355f-4d98-ab83-8143a87021c6.json @@ -0,0 +1 @@ +{"id": "fc17b663-355f-4d98-ab83-8143a87021c6", "incident_id": "3be519d0-bfaa-433c-a4cf-adb0b3186b06", "resource_type": "transport", "description": "Lanchas de evacuaci\u00f3n", "quantity": 3, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Escuela Sim\u00f3n Bol\u00edvar"} \ No newline at end of file diff --git a/backend/data/resources/fd3d6dbb-3d91-4284-a7fe-08c99485e99f.json b/backend/data/resources/fd3d6dbb-3d91-4284-a7fe-08c99485e99f.json new file mode 100644 index 0000000000000000000000000000000000000000..eef7d92c1e688352e75c7cedce1439854255f8a8 --- /dev/null +++ b/backend/data/resources/fd3d6dbb-3d91-4284-a7fe-08c99485e99f.json @@ -0,0 +1 @@ +{"id": "fd3d6dbb-3d91-4284-a7fe-08c99485e99f", "incident_id": "d8ebe4ff-807a-4469-b7fb-1c2e215a7827", "resource_type": "food", "description": "Raciones alimentarias de emergencia", "quantity": 100, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Puente"} \ No newline at end of file diff --git a/backend/data/resources/fe45e3af-7899-4271-81d3-221275184890.json b/backend/data/resources/fe45e3af-7899-4271-81d3-221275184890.json new file mode 100644 index 0000000000000000000000000000000000000000..48cd21cb7e482d161021f415b662e6072a6f74f2 --- /dev/null +++ b/backend/data/resources/fe45e3af-7899-4271-81d3-221275184890.json @@ -0,0 +1 @@ +{"id": "fe45e3af-7899-4271-81d3-221275184890", "incident_id": "b58a6e59-a483-44b3-ab3f-6b32668a9d9a", "resource_type": "rescue_team", "description": "Equipo de rescate acu\u00e1tico", "quantity": 2, "urgency": "immediate", "rationale": "Requerido por incidente P0: Inundaci\u00f3n \u2014 Sector Las Palmas"} \ No newline at end of file diff --git a/backend/data/sessions/53fb5060-a75c-4762-be08-d5098194da4f.json b/backend/data/sessions/53fb5060-a75c-4762-be08-d5098194da4f.json new file mode 100644 index 0000000000000000000000000000000000000000..358d56a6740f4fa204a49544f9c9a25c307ce381 --- /dev/null +++ b/backend/data/sessions/53fb5060-a75c-4762-be08-d5098194da4f.json @@ -0,0 +1 @@ +{"session_id": "53fb5060-a75c-4762-be08-d5098194da4f", "scenario_name": "Inundaci\u00f3n Barrio Santa Ana", "total_reports": 29, "total_signals": 21, "total_incidents": 11, "status": "ready", "processing_time_seconds": 0.09, "created_at": "2026-05-06T01:07:12.428306"} \ No newline at end of file diff --git a/backend/data/sessions/73dc26b4-eb71-4b97-b538-f631ae51a73d.json b/backend/data/sessions/73dc26b4-eb71-4b97-b538-f631ae51a73d.json new file mode 100644 index 0000000000000000000000000000000000000000..97cc539a1edce1d18a508213297c3b3f9f73bbff --- /dev/null +++ b/backend/data/sessions/73dc26b4-eb71-4b97-b538-f631ae51a73d.json @@ -0,0 +1 @@ +{"session_id": "73dc26b4-eb71-4b97-b538-f631ae51a73d", "scenario_name": "Test Flood", "total_reports": 2, "total_signals": 2, "total_incidents": 2, "status": "ready", "processing_time_seconds": 0.07, "created_at": "2026-05-06T01:07:30.597778"} \ No newline at end of file diff --git a/backend/data/sessions/f5a7d1ab-181d-4663-bb87-e7a714a609a2.json b/backend/data/sessions/f5a7d1ab-181d-4663-bb87-e7a714a609a2.json new file mode 100644 index 0000000000000000000000000000000000000000..7d2385ed36295f568d18bec64d9235bbb16cc301 --- /dev/null +++ b/backend/data/sessions/f5a7d1ab-181d-4663-bb87-e7a714a609a2.json @@ -0,0 +1 @@ +{"session_id": "f5a7d1ab-181d-4663-bb87-e7a714a609a2", "scenario_name": "Inundaci\u00f3n Barrio Santa Ana", "total_reports": 29, "total_signals": 24, "total_incidents": 11, "status": "ready", "processing_time_seconds": 0.1, "created_at": "2026-05-06T01:07:30.511632"} \ No newline at end of file diff --git a/backend/data/sessions/fea49518-a599-4178-8b5b-2fed8273e06d.json b/backend/data/sessions/fea49518-a599-4178-8b5b-2fed8273e06d.json new file mode 100644 index 0000000000000000000000000000000000000000..17b810a6db514473a088e05a7874c91d8d24d4c6 --- /dev/null +++ b/backend/data/sessions/fea49518-a599-4178-8b5b-2fed8273e06d.json @@ -0,0 +1 @@ +{"session_id": "fea49518-a599-4178-8b5b-2fed8273e06d", "scenario_name": "Test Flood", "total_reports": 2, "total_signals": 2, "total_incidents": 2, "status": "ready", "processing_time_seconds": 0.07, "created_at": "2026-05-06T01:07:12.514505"} \ No newline at end of file diff --git a/backend/data/signals/010b17d8-f045-4aac-a161-cfa759be1825.json b/backend/data/signals/010b17d8-f045-4aac-a161-cfa759be1825.json new file mode 100644 index 0000000000000000000000000000000000000000..a21d71317ef0bd8dafc251bc143be72d5c748f9f --- /dev/null +++ b/backend/data/signals/010b17d8-f045-4aac-a161-cfa759be1825.json @@ -0,0 +1 @@ +{"id": "010b17d8-f045-4aac-a161-cfa759be1825", "source_report_id": "rpt_011", "signal_type": "flood", "description": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de la iglesia Nuestra Se\u00f1ora. Todos est\u00e1n bien, sin h", "location": "Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "coordinates": null, "affected_people": 30, "raw_text": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de la iglesia Nuestra Se\u00f1ora. Todos est\u00e1n bien, sin heridos. Tenemos suficiente comida por ahora pero necesitaremos agua potable ma\u00f1ana.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392575"} \ No newline at end of file diff --git a/backend/data/signals/09c39c6e-7dab-44d2-aeda-2241c23f1f59.json b/backend/data/signals/09c39c6e-7dab-44d2-aeda-2241c23f1f59.json new file mode 100644 index 0000000000000000000000000000000000000000..93cc26dde14b2afd581b35cf61f470c4588f83e4 --- /dev/null +++ b/backend/data/signals/09c39c6e-7dab-44d2-aeda-2241c23f1f59.json @@ -0,0 +1 @@ +{"id": "09c39c6e-7dab-44d2-aeda-2241c23f1f59", "source_report_id": "rpt_016", "signal_type": "flood", "description": "This is a rescue call from Santa Ana district. We have a man with a broken leg and possible spinal injury on the corner of Av. Principal and Calle 5. He cannot be moved without a stretcher. Medical te", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "This is a rescue call from Santa Ana district. We have a man with a broken leg and possible spinal injury on the corner of Av. Principal and Calle 5. He cannot be moved without a stretcher. Medical team needed immediately.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:30.468182"} \ No newline at end of file diff --git a/backend/data/signals/0f21af7b-eeac-468d-96e7-75b12db2ba79.json b/backend/data/signals/0f21af7b-eeac-468d-96e7-75b12db2ba79.json new file mode 100644 index 0000000000000000000000000000000000000000..9d03a5957b330a79ff92ccbc85df53da99321f70 --- /dev/null +++ b/backend/data/signals/0f21af7b-eeac-468d-96e7-75b12db2ba79.json @@ -0,0 +1 @@ +{"id": "0f21af7b-eeac-468d-96e7-75b12db2ba79", "source_report_id": "rpt_015", "signal_type": "flood", "description": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin heridos ni emergencias m\u00e9dicas activas. Necesitaremo", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin heridos ni emergencias m\u00e9dicas activas. Necesitaremos colchonetas y frazadas para esta noche ya que bajan las temperaturas.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392731"} \ No newline at end of file diff --git a/backend/data/signals/12e6e282-74a9-4b27-9bf9-7a82c92bbdfe.json b/backend/data/signals/12e6e282-74a9-4b27-9bf9-7a82c92bbdfe.json new file mode 100644 index 0000000000000000000000000000000000000000..2006d7f9246354555a1271140bcf856cce6bafc2 --- /dev/null +++ b/backend/data/signals/12e6e282-74a9-4b27-9bf9-7a82c92bbdfe.json @@ -0,0 +1 @@ +{"id": "12e6e282-74a9-4b27-9bf9-7a82c92bbdfe", "source_report_id": "rpt_008", "signal_type": "flood", "description": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos voces pidiendo ayuda desde el segundo piso. Se nece", "location": "Sector Las Palmas", "coordinates": null, "affected_people": 30, "raw_text": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos voces pidiendo ayuda desde el segundo piso. Se necesita equipo de rescate especializado y evaluaci\u00f3n estructural urgente.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392473"} \ No newline at end of file diff --git a/backend/data/signals/138e2204-fc66-4445-aebc-cb278b4be1c4.json b/backend/data/signals/138e2204-fc66-4445-aebc-cb278b4be1c4.json new file mode 100644 index 0000000000000000000000000000000000000000..961cf7a50466b71018edea7bd51a0805346bf05c --- /dev/null +++ b/backend/data/signals/138e2204-fc66-4445-aebc-cb278b4be1c4.json @@ -0,0 +1 @@ +{"id": "138e2204-fc66-4445-aebc-cb278b4be1c4", "source_report_id": "rpt_028", "signal_type": "flood", "description": "Flooded electrical substation with water reaching transformer level. Live wires in contact with floodwater visible. No civilians in immediate vicinity but risk of electrocution to anyone in the area. ", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Flooded electrical substation with water reaching transformer level. Live wires in contact with floodwater visible. No civilians in immediate vicinity but risk of electrocution to anyone in the area. Hazards identified: electrocution_risk, live_wires_in_water, critical_infrastructure_failure.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.469839"} \ No newline at end of file diff --git a/backend/data/signals/1562e755-58e7-422c-a8fe-0531de586385.json b/backend/data/signals/1562e755-58e7-422c-a8fe-0531de586385.json new file mode 100644 index 0000000000000000000000000000000000000000..efce25f5e5784fa74e13dcd67bba46446085707d --- /dev/null +++ b/backend/data/signals/1562e755-58e7-422c-a8fe-0531de586385.json @@ -0,0 +1 @@ +{"id": "1562e755-58e7-422c-a8fe-0531de586385", "source_report_id": "rpt_029", "signal_type": "flood", "description": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99,P1\n10.4795,-66.9028,Av Principal ferreteria,emerg", "location": "Calle Bolivar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99,P1\n10.4795,-66.9028,Av Principal ferreteria,emergencia_medica,1,P0\n10.4808,-66.9033,Centro Comunitario,refugio,62,P2\n10.4801,-66.9043,Calle 5 esquina Av Principal,atrapados,3,P0\n10.4818,-66.9055,Mercado Municipal,atrapados,45,P0\n10.4800,-66.9030,Edificio El Mirador,derrumbe,8,P1\n10.4790,-66.9020,Puente norte,colapsado,0,P1\n10.4815,-66.9048,Subestacion electrica Sucre,peligro_electrico,0,P1\n10.4825,-66.9060,Liceo Andres Bello,refugio_estable,34,P3\n10.4797,-66.9038,Iglesia Nuestra Senora,refugio_estable,28,P3", "confidence": 0.92, "modality": "csv", "created_at": "2026-05-06T01:07:12.392760"} \ No newline at end of file diff --git a/backend/data/signals/15dc56ec-713d-4cf8-b2d3-9f38af951543.json b/backend/data/signals/15dc56ec-713d-4cf8-b2d3-9f38af951543.json new file mode 100644 index 0000000000000000000000000000000000000000..53f811ab7868f9127882a1dadbee34e4c3436b76 --- /dev/null +++ b/backend/data/signals/15dc56ec-713d-4cf8-b2d3-9f38af951543.json @@ -0,0 +1 @@ +{"id": "15dc56ec-713d-4cf8-b2d3-9f38af951543", "source_report_id": "rpt_026", "signal_type": "flood", "description": "Child approximately 8 years old sitting alone on a fence post surrounded by floodwater. Location appears to be near the Santa Ana primary school. No adults visible nearby. Child appears distressed. Ha", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Child approximately 8 years old sitting alone on a fence post surrounded by floodwater. Location appears to be near the Santa Ana primary school. No adults visible nearby. Child appears distressed. Hazards identified: unaccompanied_minor, immediate_rescue_needed, drowning_risk.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.469784"} \ No newline at end of file diff --git a/backend/data/signals/173d82f5-a505-4829-a2d1-bce3e54b264d.json b/backend/data/signals/173d82f5-a505-4829-a2d1-bce3e54b264d.json new file mode 100644 index 0000000000000000000000000000000000000000..a4b5b2b961751f9351679d5aa6e20652e6546c2a --- /dev/null +++ b/backend/data/signals/173d82f5-a505-4829-a2d1-bce3e54b264d.json @@ -0,0 +1 @@ +{"id": "173d82f5-a505-4829-a2d1-bce3e54b264d", "source_report_id": "rpt_017", "signal_type": "flood", "description": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos cuatro horas aqu\u00ed.", "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 30, "raw_text": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos cuatro horas aqu\u00ed.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:30.468301"} \ No newline at end of file diff --git a/backend/data/signals/190d41d3-5af1-4018-846c-c60e34941f55.json b/backend/data/signals/190d41d3-5af1-4018-846c-c60e34941f55.json new file mode 100644 index 0000000000000000000000000000000000000000..edb43270f4d6cade779c072c4fb46606237e6d29 --- /dev/null +++ b/backend/data/signals/190d41d3-5af1-4018-846c-c60e34941f55.json @@ -0,0 +1 @@ +{"id": "190d41d3-5af1-4018-846c-c60e34941f55", "source_report_id": "rpt_005", "signal_type": "flood", "description": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se agot\u00f3 completamente el agua potable. Los alimentos a", "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "raw_text": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se agot\u00f3 completamente el agua potable. Los alimentos alcanzan para 6 horas m\u00e1s. Solicitamos suministros de emergencia urgentes.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470012"} \ No newline at end of file diff --git a/backend/data/signals/2cba759b-3471-48b8-ab52-ac362d07e7f6.json b/backend/data/signals/2cba759b-3471-48b8-ab52-ac362d07e7f6.json new file mode 100644 index 0000000000000000000000000000000000000000..a339d47a2164dd90dbf6cdd17754de584da95732 --- /dev/null +++ b/backend/data/signals/2cba759b-3471-48b8-ab52-ac362d07e7f6.json @@ -0,0 +1 @@ +{"id": "2cba759b-3471-48b8-ab52-ac362d07e7f6", "source_report_id": "rpt_001", "signal_type": "flood", "description": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos lancha y param\u00e9dicos YA!!", "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos lancha y param\u00e9dicos YA!!", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392173"} \ No newline at end of file diff --git a/backend/data/signals/3bd5dc9b-a608-4f1b-982e-1f964251140a.json b/backend/data/signals/3bd5dc9b-a608-4f1b-982e-1f964251140a.json new file mode 100644 index 0000000000000000000000000000000000000000..8876f3be4f24f5dfe14be05107b50940c6cc395c --- /dev/null +++ b/backend/data/signals/3bd5dc9b-a608-4f1b-982e-1f964251140a.json @@ -0,0 +1 @@ +{"id": "3bd5dc9b-a608-4f1b-982e-1f964251140a", "source_report_id": "rpt_018", "signal_type": "flood", "description": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, necesitamos ayuda urgente, por favor.", "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, necesitamos ayuda urgente, por favor.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:30.468361"} \ No newline at end of file diff --git a/backend/data/signals/3fd59544-d7c9-4861-ad6c-b908654ed691.json b/backend/data/signals/3fd59544-d7c9-4861-ad6c-b908654ed691.json new file mode 100644 index 0000000000000000000000000000000000000000..b1173f0db653ba615997a2bb4a86078e821cae5a --- /dev/null +++ b/backend/data/signals/3fd59544-d7c9-4861-ad6c-b908654ed691.json @@ -0,0 +1 @@ +{"id": "3fd59544-d7c9-4861-ad6c-b908654ed691", "source_report_id": "rpt_015", "signal_type": "flood", "description": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin heridos ni emergencias m\u00e9dicas activas. Necesitaremo", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Situaci\u00f3n estable en el refugio del Liceo Andr\u00e9s Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el d\u00eda de hoy. Sin heridos ni emergencias m\u00e9dicas activas. Necesitaremos colchonetas y frazadas para esta noche ya que bajan las temperaturas.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470429"} \ No newline at end of file diff --git a/backend/data/signals/41296eb4-920a-4dff-9dac-9c1bf86a45d4.json b/backend/data/signals/41296eb4-920a-4dff-9dac-9c1bf86a45d4.json new file mode 100644 index 0000000000000000000000000000000000000000..f95b1727ea270ae04686cf1292c8932efeaa64e7 --- /dev/null +++ b/backend/data/signals/41296eb4-920a-4dff-9dac-9c1bf86a45d4.json @@ -0,0 +1 @@ +{"id": "41296eb4-920a-4dff-9dac-9c1bf86a45d4", "source_report_id": "rpt_004", "signal_type": "flood", "description": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tiene muchos baches y barro. Ambulancias y camiones p", "location": "Puente", "coordinates": {"lat": 10.479, "lon": -66.902}, "affected_people": 30, "raw_text": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tiene muchos baches y barro. Ambulancias y camiones pesados no pueden pasar. Sugiero coordinar por v\u00eda a\u00e9rea o lancha.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392340"} \ No newline at end of file diff --git a/backend/data/signals/41af92a2-5411-4e09-b226-8be4c1fed977.json b/backend/data/signals/41af92a2-5411-4e09-b226-8be4c1fed977.json new file mode 100644 index 0000000000000000000000000000000000000000..574d64f32647094725b965c9596c44610cd74046 --- /dev/null +++ b/backend/data/signals/41af92a2-5411-4e09-b226-8be4c1fed977.json @@ -0,0 +1 @@ +{"id": "41af92a2-5411-4e09-b226-8be4c1fed977", "source_report_id": "rpt_008", "signal_type": "flood", "description": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos voces pidiendo ayuda desde el segundo piso. Se nece", "location": "Sector Las Palmas", "coordinates": null, "affected_people": 30, "raw_text": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colaps\u00f3. Hay 4 apartamentos comprometidos. Escuchamos voces pidiendo ayuda desde el segundo piso. Se necesita equipo de rescate especializado y evaluaci\u00f3n estructural urgente.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470108"} \ No newline at end of file diff --git a/backend/data/signals/474a3c1a-5b2c-4d7c-a036-6e39ef9f3d20.json b/backend/data/signals/474a3c1a-5b2c-4d7c-a036-6e39ef9f3d20.json new file mode 100644 index 0000000000000000000000000000000000000000..4cfee5ea36be24e26e6deced54c57d7f6be67722 --- /dev/null +++ b/backend/data/signals/474a3c1a-5b2c-4d7c-a036-6e39ef9f3d20.json @@ -0,0 +1 @@ +{"id": "474a3c1a-5b2c-4d7c-a036-6e39ef9f3d20", "source_report_id": "rpt_009", "signal_type": "flood", "description": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracciones. Necesitamos evacuaci\u00f3n m\u00e9dica urgente para e", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracciones. Necesitamos evacuaci\u00f3n m\u00e9dica urgente para ella primero. Los dem\u00e1s podemos esperar un poco m\u00e1s.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470148"} \ No newline at end of file diff --git a/backend/data/signals/493cf0ab-da9f-4ad3-adbc-5f62e5649324.json b/backend/data/signals/493cf0ab-da9f-4ad3-adbc-5f62e5649324.json new file mode 100644 index 0000000000000000000000000000000000000000..37f8c165f7a55b59ae28e1c8996680d914216cb4 --- /dev/null +++ b/backend/data/signals/493cf0ab-da9f-4ad3-adbc-5f62e5649324.json @@ -0,0 +1 @@ +{"id": "493cf0ab-da9f-4ad3-adbc-5f62e5649324", "source_report_id": "rpt_005", "signal_type": "flood", "description": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se agot\u00f3 completamente el agua potable. Los alimentos a", "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "raw_text": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 ni\u00f1os menores de 10 a\u00f1os y 8 adultos mayores. Ya se agot\u00f3 completamente el agua potable. Los alimentos alcanzan para 6 horas m\u00e1s. Solicitamos suministros de emergencia urgentes.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392376"} \ No newline at end of file diff --git a/backend/data/signals/543e3974-8662-4531-93a4-2bdd39336c49.json b/backend/data/signals/543e3974-8662-4531-93a4-2bdd39336c49.json new file mode 100644 index 0000000000000000000000000000000000000000..3cb47e4b1cb6682d0d833fee231c700f0468d17a --- /dev/null +++ b/backend/data/signals/543e3974-8662-4531-93a4-2bdd39336c49.json @@ -0,0 +1 @@ +{"id": "543e3974-8662-4531-93a4-2bdd39336c49", "source_report_id": "rpt_022", "signal_type": "flood", "description": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedestrian bridge visible in background shows water is ", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedestrian bridge visible in background shows water is 2m above normal. Hazards identified: blocked_emergency_access, high_water_level.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.468537"} \ No newline at end of file diff --git a/backend/data/signals/5853a327-1721-4582-ae88-7b79da0bb683.json b/backend/data/signals/5853a327-1721-4582-ae88-7b79da0bb683.json new file mode 100644 index 0000000000000000000000000000000000000000..a3a235ee3382f81b5819c7349ddb3e5b9fd4d653 --- /dev/null +++ b/backend/data/signals/5853a327-1721-4582-ae88-7b79da0bb683.json @@ -0,0 +1 @@ +{"id": "5853a327-1721-4582-ae88-7b79da0bb683", "source_report_id": "rpt_029", "signal_type": "flood", "description": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99,P1\n10.4795,-66.9028,Av Principal ferreteria,emerg", "location": "Calle Bolivar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99,P1\n10.4795,-66.9028,Av Principal ferreteria,emergencia_medica,1,P0\n10.4808,-66.9033,Centro Comunitario,refugio,62,P2\n10.4801,-66.9043,Calle 5 esquina Av Principal,atrapados,3,P0\n10.4818,-66.9055,Mercado Municipal,atrapados,45,P0\n10.4800,-66.9030,Edificio El Mirador,derrumbe,8,P1\n10.4790,-66.9020,Puente norte,colapsado,0,P1\n10.4815,-66.9048,Subestacion electrica Sucre,peligro_electrico,0,P1\n10.4825,-66.9060,Liceo Andres Bello,refugio_estable,34,P3\n10.4797,-66.9038,Iglesia Nuestra Senora,refugio_estable,28,P3", "confidence": 0.92, "modality": "csv", "created_at": "2026-05-06T01:07:30.470455"} \ No newline at end of file diff --git a/backend/data/signals/5b140c5d-1598-4b33-967e-75d851660f29.json b/backend/data/signals/5b140c5d-1598-4b33-967e-75d851660f29.json new file mode 100644 index 0000000000000000000000000000000000000000..4b9c816ada45481c1939ffc97f50b6409435387f --- /dev/null +++ b/backend/data/signals/5b140c5d-1598-4b33-967e-75d851660f29.json @@ -0,0 +1 @@ +{"id": "5b140c5d-1598-4b33-967e-75d851660f29", "source_report_id": "rpt_009", "signal_type": "flood", "description": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracciones. Necesitamos evacuaci\u00f3n m\u00e9dica urgente para e", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una se\u00f1ora embarazada de 8 meses con contracciones. Necesitamos evacuaci\u00f3n m\u00e9dica urgente para ella primero. Los dem\u00e1s podemos esperar un poco m\u00e1s.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392508"} \ No newline at end of file diff --git a/backend/data/signals/5c52e577-8eb4-48a6-b4e6-51c42fd244e1.json b/backend/data/signals/5c52e577-8eb4-48a6-b4e6-51c42fd244e1.json new file mode 100644 index 0000000000000000000000000000000000000000..d576718a43f7d5eb0c47d7ae8f185c7c974e0f78 --- /dev/null +++ b/backend/data/signals/5c52e577-8eb4-48a6-b4e6-51c42fd244e1.json @@ -0,0 +1 @@ +{"id": "5c52e577-8eb4-48a6-b4e6-51c42fd244e1", "source_report_id": "rpt_007", "signal_type": "flood", "description": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuci\u00f3n en toda la zona norte del barrio. Urge corte d", "location": "Calle Sucre Est\u00e1 Completamente Inundada", "coordinates": null, "affected_people": 30, "raw_text": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuci\u00f3n en toda la zona norte del barrio. Urge corte de energ\u00eda inmediato y se\u00f1alizaci\u00f3n del \u00e1rea.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470070"} \ No newline at end of file diff --git a/backend/data/signals/5e41d0cb-26ff-4e5c-ae97-80bd414e9491.json b/backend/data/signals/5e41d0cb-26ff-4e5c-ae97-80bd414e9491.json new file mode 100644 index 0000000000000000000000000000000000000000..af07ef8ce5949c4e317fb93f3892f69ac27b8df7 --- /dev/null +++ b/backend/data/signals/5e41d0cb-26ff-4e5c-ae97-80bd414e9491.json @@ -0,0 +1 @@ +{"id": "5e41d0cb-26ff-4e5c-ae97-80bd414e9491", "source_report_id": "rpt_024", "signal_type": "flood", "description": "Makeshift raft carrying three adults navigating between houses. Improvised from wooden pallets and plastic barrels. One person appears to have a bandaged leg injury. Hazards identified: unstable_flota", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Makeshift raft carrying three adults navigating between houses. Improvised from wooden pallets and plastic barrels. One person appears to have a bandaged leg injury. Hazards identified: unstable_flotation, injured_civilian, flood_navigation_risk.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.469714"} \ No newline at end of file diff --git a/backend/data/signals/7368e339-876b-471e-b3a8-0cb86f9f6353.json b/backend/data/signals/7368e339-876b-471e-b3a8-0cb86f9f6353.json new file mode 100644 index 0000000000000000000000000000000000000000..493e92b9703730131065d265d1a7f9b66da71d1e --- /dev/null +++ b/backend/data/signals/7368e339-876b-471e-b3a8-0cb86f9f6353.json @@ -0,0 +1 @@ +{"id": "7368e339-876b-471e-b3a8-0cb86f9f6353", "source_report_id": "rpt_001", "signal_type": "flood", "description": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos lancha y param\u00e9dicos YA!!", "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "URGENTE: Familia atrapada en techo de casa calle Bol\u00edvar #45. Abuela de 78 a\u00f1os con diabetes no puede moverse. Agua lleg\u00f3 al segundo piso. Necesitamos lancha y param\u00e9dicos YA!!", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.469871"} \ No newline at end of file diff --git a/backend/data/signals/736cc236-0302-4f63-9198-a83c7ee172c3.json b/backend/data/signals/736cc236-0302-4f63-9198-a83c7ee172c3.json new file mode 100644 index 0000000000000000000000000000000000000000..d347aaff293e92b1b06bac5c152cafafc6958e8c --- /dev/null +++ b/backend/data/signals/736cc236-0302-4f63-9198-a83c7ee172c3.json @@ -0,0 +1 @@ +{"id": "736cc236-0302-4f63-9198-a83c7ee172c3", "source_report_id": "rpt_006", "signal_type": "flood", "description": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs medication. Water level is about 1.8 meters and sti", "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 30, "raw_text": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs medication. Water level is about 1.8 meters and still rising slowly. Please send boat rescue.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470035"} \ No newline at end of file diff --git a/backend/data/signals/73f3c3cb-b323-44fc-932d-d078b1f9a39f.json b/backend/data/signals/73f3c3cb-b323-44fc-932d-d078b1f9a39f.json new file mode 100644 index 0000000000000000000000000000000000000000..40601bc8dd83ba764db9053f1f073849374723d2 --- /dev/null +++ b/backend/data/signals/73f3c3cb-b323-44fc-932d-d078b1f9a39f.json @@ -0,0 +1 @@ +{"id": "73f3c3cb-b323-44fc-932d-d078b1f9a39f", "source_report_id": "rpt_004", "signal_type": "flood", "description": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tiene muchos baches y barro. Ambulancias y camiones p", "location": "Puente", "coordinates": {"lat": 10.479, "lon": -66.902}, "affected_people": 30, "raw_text": "El puente peatonal de la entrada norte al barrio colaps\u00f3 hace 20 minutos. El \u00fanico acceso vehicular ahora es por la carretera vieja del norte pero tiene muchos baches y barro. Ambulancias y camiones pesados no pueden pasar. Sugiero coordinar por v\u00eda a\u00e9rea o lancha.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.469977"} \ No newline at end of file diff --git a/backend/data/signals/7b147f89-082c-422d-82c8-81f6c75b4447.json b/backend/data/signals/7b147f89-082c-422d-82c8-81f6c75b4447.json new file mode 100644 index 0000000000000000000000000000000000000000..7e180ccc384b7d55b68d78476a69fb7a7417d01b --- /dev/null +++ b/backend/data/signals/7b147f89-082c-422d-82c8-81f6c75b4447.json @@ -0,0 +1 @@ +{"id": "7b147f89-082c-422d-82c8-81f6c75b4447", "source_report_id": "rpt_003", "signal_type": "flood", "description": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando pero no responde. Necesitamos ambulancia de emerge", "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 30, "raw_text": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando pero no responde. Necesitamos ambulancia de emergencia inmediatamente.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.469941"} \ No newline at end of file diff --git a/backend/data/signals/7ce82058-95e1-4276-8efe-50a6465e1585.json b/backend/data/signals/7ce82058-95e1-4276-8efe-50a6465e1585.json new file mode 100644 index 0000000000000000000000000000000000000000..f7030dd74a4c3a173330a32311167a85ea2dae6a --- /dev/null +++ b/backend/data/signals/7ce82058-95e1-4276-8efe-50a6465e1585.json @@ -0,0 +1 @@ +{"id": "7ce82058-95e1-4276-8efe-50a6465e1585", "source_report_id": "rpt_011", "signal_type": "flood", "description": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de la iglesia Nuestra Se\u00f1ora. Todos est\u00e1n bien, sin h", "location": "Sector El Progreso Informamos Que El Nivel Del Agua Comenz\u00f3 A Bajar Levemente En Las \u00daltimas 2 Horas", "coordinates": null, "affected_people": 30, "raw_text": "Desde el sector El Progreso informamos que el nivel del agua comenz\u00f3 a bajar levemente en las \u00faltimas 2 horas. Tenemos a 28 personas en el refugio de la iglesia Nuestra Se\u00f1ora. Todos est\u00e1n bien, sin heridos. Tenemos suficiente comida por ahora pero necesitaremos agua potable ma\u00f1ana.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470262"} \ No newline at end of file diff --git a/backend/data/signals/7e63ed59-b5ef-447e-bd79-05a862a92a39.json b/backend/data/signals/7e63ed59-b5ef-447e-bd79-05a862a92a39.json new file mode 100644 index 0000000000000000000000000000000000000000..ff0db26d3aad206ba97230e81a4718f00b99a0bb --- /dev/null +++ b/backend/data/signals/7e63ed59-b5ef-447e-bd79-05a862a92a39.json @@ -0,0 +1 @@ +{"id": "7e63ed59-b5ef-447e-bd79-05a862a92a39", "source_report_id": "rpt_003", "signal_type": "flood", "description": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando pero no responde. Necesitamos ambulancia de emerge", "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 30, "raw_text": "CR\u00cdTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferreter\u00eda Los Andes. Parece tener herida en la cabeza. Est\u00e1 respirando pero no responde. Necesitamos ambulancia de emergencia inmediatamente.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392299"} \ No newline at end of file diff --git a/backend/data/signals/81391b8f-363c-4d20-9e6b-d6738d4d209e.json b/backend/data/signals/81391b8f-363c-4d20-9e6b-d6738d4d209e.json new file mode 100644 index 0000000000000000000000000000000000000000..7bac744e03e40cc6075c21a36f182d076dd8beb4 --- /dev/null +++ b/backend/data/signals/81391b8f-363c-4d20-9e6b-d6738d4d209e.json @@ -0,0 +1 @@ +{"id": "81391b8f-363c-4d20-9e6b-d6738d4d209e", "source_report_id": "rpt_002", "signal_type": "flood", "description": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya no tenemos comida ni agua potable. El agua sigue ", "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 30, "raw_text": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya no tenemos comida ni agua potable. El agua sigue subiendo. Por favor env\u00eden ayuda.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.469904"} \ No newline at end of file diff --git a/backend/data/signals/885ee87f-fc8c-41da-a40b-6869f4b5c9b9.json b/backend/data/signals/885ee87f-fc8c-41da-a40b-6869f4b5c9b9.json new file mode 100644 index 0000000000000000000000000000000000000000..af89ceae6a699bc3a4ed18fb0495c7a54a7f05b9 --- /dev/null +++ b/backend/data/signals/885ee87f-fc8c-41da-a40b-6869f4b5c9b9.json @@ -0,0 +1 @@ +{"id": "885ee87f-fc8c-41da-a40b-6869f4b5c9b9", "source_report_id": "5a1dd036-4252-4572-b108-44c0fdde852f", "signal_type": "flood", "description": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "raw_text": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.500231"} \ No newline at end of file diff --git a/backend/data/signals/8e263224-838d-4ff4-81f3-1bd3a13eb60f.json b/backend/data/signals/8e263224-838d-4ff4-81f3-1bd3a13eb60f.json new file mode 100644 index 0000000000000000000000000000000000000000..1f6e19163124daf993a894fe1acab50cf5bd02c8 --- /dev/null +++ b/backend/data/signals/8e263224-838d-4ff4-81f3-1bd3a13eb60f.json @@ -0,0 +1 @@ +{"id": "8e263224-838d-4ff4-81f3-1bd3a13eb60f", "source_report_id": "7b3cffc4-4d4e-4bb2-9d6d-9373153dc900", "signal_type": "flood", "description": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "location": "Barrio Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.583260"} \ No newline at end of file diff --git a/backend/data/signals/9b5cccb5-e6d0-43cf-8f22-570fc869ba3a.json b/backend/data/signals/9b5cccb5-e6d0-43cf-8f22-570fc869ba3a.json new file mode 100644 index 0000000000000000000000000000000000000000..c552a69cfb41d5405690e7bd45f1f5e63811843a --- /dev/null +++ b/backend/data/signals/9b5cccb5-e6d0-43cf-8f22-570fc869ba3a.json @@ -0,0 +1 @@ +{"id": "9b5cccb5-e6d0-43cf-8f22-570fc869ba3a", "source_report_id": "rpt_010", "signal_type": "flood", "description": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su familia est\u00e1 desesperada. Si alguien lo ve por favo", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su familia est\u00e1 desesperada. Si alguien lo ve por favor contactar al n\u00famero 0412-5678901.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392541"} \ No newline at end of file diff --git a/backend/data/signals/9cb5a0fb-574e-4348-b252-e3ea6cf4c2a2.json b/backend/data/signals/9cb5a0fb-574e-4348-b252-e3ea6cf4c2a2.json new file mode 100644 index 0000000000000000000000000000000000000000..51c5cc61274fac5ec496f1a58f4456afb015991a --- /dev/null +++ b/backend/data/signals/9cb5a0fb-574e-4348-b252-e3ea6cf4c2a2.json @@ -0,0 +1 @@ +{"id": "9cb5a0fb-574e-4348-b252-e3ea6cf4c2a2", "source_report_id": "rpt_021", "signal_type": "flood", "description": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible empty water containers and minimal food stocks. Haz", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible empty water containers and minimal food stocks. Hazards identified: resource_shortage, vulnerable_population.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.468505"} \ No newline at end of file diff --git a/backend/data/signals/a2bf70f5-5054-4a3f-9bd8-b3fa171b7ab9.json b/backend/data/signals/a2bf70f5-5054-4a3f-9bd8-b3fa171b7ab9.json new file mode 100644 index 0000000000000000000000000000000000000000..a244952dc28cf79b540d34a2cc179be133952a19 --- /dev/null +++ b/backend/data/signals/a2bf70f5-5054-4a3f-9bd8-b3fa171b7ab9.json @@ -0,0 +1 @@ +{"id": "a2bf70f5-5054-4a3f-9bd8-b3fa171b7ab9", "source_report_id": "rpt_002", "signal_type": "flood", "description": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya no tenemos comida ni agua potable. El agua sigue ", "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 30, "raw_text": "Soy profesora de la Escuela Sim\u00f3n Bol\u00edvar. Tenemos 87 ni\u00f1os y 12 adultos refugiados en el segundo piso. El primer piso est\u00e1 completamente inundado. Ya no tenemos comida ni agua potable. El agua sigue subiendo. Por favor env\u00eden ayuda.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392238"} \ No newline at end of file diff --git a/backend/data/signals/a35b42bd-82bd-45f2-836c-4c09b24d9a5a.json b/backend/data/signals/a35b42bd-82bd-45f2-836c-4c09b24d9a5a.json new file mode 100644 index 0000000000000000000000000000000000000000..602a1dd05aaa2000778c2e4941a0f353e50aa4bc --- /dev/null +++ b/backend/data/signals/a35b42bd-82bd-45f2-836c-4c09b24d9a5a.json @@ -0,0 +1 @@ +{"id": "a35b42bd-82bd-45f2-836c-4c09b24d9a5a", "source_report_id": "rpt_012", "signal_type": "flood", "description": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del barrio que necesitan insulina diariamente incluyen", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del barrio que necesitan insulina diariamente incluyendo la se\u00f1ora del techo de la calle Bol\u00edvar. Solicitar provisi\u00f3n de medicamentos de emergencia.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392613"} \ No newline at end of file diff --git a/backend/data/signals/a55c5c9d-d9c7-409e-bb1e-176b42b6d4a6.json b/backend/data/signals/a55c5c9d-d9c7-409e-bb1e-176b42b6d4a6.json new file mode 100644 index 0000000000000000000000000000000000000000..69ca43f5b27b495fd088fcc225ca3cb7eabf0f97 --- /dev/null +++ b/backend/data/signals/a55c5c9d-d9c7-409e-bb1e-176b42b6d4a6.json @@ -0,0 +1 @@ +{"id": "a55c5c9d-d9c7-409e-bb1e-176b42b6d4a6", "source_report_id": "rpt_006", "signal_type": "flood", "description": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs medication. Water level is about 1.8 meters and sti", "location": "Av. Principal", "coordinates": {"lat": 10.4795, "lon": -66.9028}, "affected_people": 30, "raw_text": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs medication. Water level is about 1.8 meters and still rising slowly. Please send boat rescue.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392404"} \ No newline at end of file diff --git a/backend/data/signals/bbbef4ce-0097-4a21-a984-ba338b2b1544.json b/backend/data/signals/bbbef4ce-0097-4a21-a984-ba338b2b1544.json new file mode 100644 index 0000000000000000000000000000000000000000..d5e22d9dd7aa0ec0bfade3931b2bef69ca00e557 --- /dev/null +++ b/backend/data/signals/bbbef4ce-0097-4a21-a984-ba338b2b1544.json @@ -0,0 +1 @@ +{"id": "bbbef4ce-0097-4a21-a984-ba338b2b1544", "source_report_id": "rpt_010", "signal_type": "flood", "description": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su familia est\u00e1 desesperada. Si alguien lo ve por favo", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Desaparecido: ni\u00f1o de 7 a\u00f1os, Andr\u00e9s Rodr\u00edguez, con camiseta roja y pantal\u00f3n azul. Fue visto por \u00faltima vez en el parque principal a las 12:30pm. Su familia est\u00e1 desesperada. Si alguien lo ve por favor contactar al n\u00famero 0412-5678901.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470218"} \ No newline at end of file diff --git a/backend/data/signals/be19b726-85b6-4c65-b075-2f7f12b03656.json b/backend/data/signals/be19b726-85b6-4c65-b075-2f7f12b03656.json new file mode 100644 index 0000000000000000000000000000000000000000..9178b7f1498655c76dbf8783f302e07051c84e2a --- /dev/null +++ b/backend/data/signals/be19b726-85b6-4c65-b075-2f7f12b03656.json @@ -0,0 +1 @@ +{"id": "be19b726-85b6-4c65-b075-2f7f12b03656", "source_report_id": "rpt_007", "signal_type": "flood", "description": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuci\u00f3n en toda la zona norte del barrio. Urge corte d", "location": "Calle Sucre Est\u00e1 Completamente Inundada", "coordinates": null, "affected_people": 30, "raw_text": "La subestaci\u00f3n el\u00e9ctrica de la calle Sucre est\u00e1 completamente inundada. Cables de alta tensi\u00f3n en contacto con el agua. Hay riesgo grave de electrocuci\u00f3n en toda la zona norte del barrio. Urge corte de energ\u00eda inmediato y se\u00f1alizaci\u00f3n del \u00e1rea.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.392437"} \ No newline at end of file diff --git a/backend/data/signals/c14a1ff0-f928-416d-a6af-86e475ab3fda.json b/backend/data/signals/c14a1ff0-f928-416d-a6af-86e475ab3fda.json new file mode 100644 index 0000000000000000000000000000000000000000..567c7d5418ec73d94cb8c6e22532065be018f9ea --- /dev/null +++ b/backend/data/signals/c14a1ff0-f928-416d-a6af-86e475ab3fda.json @@ -0,0 +1 @@ +{"id": "c14a1ff0-f928-416d-a6af-86e475ab3fda", "source_report_id": "00c17b9b-0ee0-48bd-9a54-d5cd36698acc", "signal_type": "flood", "description": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "location": "Centro Comunitario", "coordinates": {"lat": 10.4808, "lon": -66.9033}, "affected_people": 30, "raw_text": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.583354"} \ No newline at end of file diff --git a/backend/data/signals/c3627714-d763-4f37-93e8-f9ec57d1ed6a.json b/backend/data/signals/c3627714-d763-4f37-93e8-f9ec57d1ed6a.json new file mode 100644 index 0000000000000000000000000000000000000000..c43b016d56e9312364bc94b3551d671030759de4 --- /dev/null +++ b/backend/data/signals/c3627714-d763-4f37-93e8-f9ec57d1ed6a.json @@ -0,0 +1 @@ +{"id": "c3627714-d763-4f37-93e8-f9ec57d1ed6a", "source_report_id": "739eb38e-3e24-4dce-af37-b68aa24a091f", "signal_type": "flood", "description": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "location": "Barrio Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:12.500121"} \ No newline at end of file diff --git a/backend/data/signals/cc28863a-857f-414e-8af1-9e19122a558c.json b/backend/data/signals/cc28863a-857f-414e-8af1-9e19122a558c.json new file mode 100644 index 0000000000000000000000000000000000000000..b1ba460a33b5e55af8c8b82f784f0166afa66767 --- /dev/null +++ b/backend/data/signals/cc28863a-857f-414e-8af1-9e19122a558c.json @@ -0,0 +1 @@ +{"id": "cc28863a-857f-414e-8af1-9e19122a558c", "source_report_id": "rpt_028", "signal_type": "flood", "description": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedestrian bridge visible in background shows water is ", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedestrian bridge visible in background shows water is 2m above normal. Hazards identified: blocked_emergency_access, high_water_level.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:12.392116"} \ No newline at end of file diff --git a/backend/data/signals/d74b9685-7de3-42e3-b94a-70f770137d10.json b/backend/data/signals/d74b9685-7de3-42e3-b94a-70f770137d10.json new file mode 100644 index 0000000000000000000000000000000000000000..504a448bbe5cd2f3cb721dbbbe7a418cbdb9a481 --- /dev/null +++ b/backend/data/signals/d74b9685-7de3-42e3-b94a-70f770137d10.json @@ -0,0 +1 @@ +{"id": "d74b9685-7de3-42e3-b94a-70f770137d10", "source_report_id": "rpt_012", "signal_type": "flood", "description": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del barrio que necesitan insulina diariamente incluyen", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de fr\u00edo. Hay al menos 15 pacientes del barrio que necesitan insulina diariamente incluyendo la se\u00f1ora del techo de la calle Bol\u00edvar. Solicitar provisi\u00f3n de medicamentos de emergencia.", "confidence": 0.92, "modality": "text", "created_at": "2026-05-06T01:07:30.470314"} \ No newline at end of file diff --git a/backend/data/signals/dbd3a2f8-d405-46cb-9999-0bbd63a7ed33.json b/backend/data/signals/dbd3a2f8-d405-46cb-9999-0bbd63a7ed33.json new file mode 100644 index 0000000000000000000000000000000000000000..e26b36ecd614df96bcf6743626cdcdf3f7908917 --- /dev/null +++ b/backend/data/signals/dbd3a2f8-d405-46cb-9999-0bbd63a7ed33.json @@ -0,0 +1 @@ +{"id": "dbd3a2f8-d405-46cb-9999-0bbd63a7ed33", "source_report_id": "rpt_017", "signal_type": "flood", "description": "El puente de la entrada del barrio colaps\u00f3. No pueden entrar camiones ni ambulancias por esa v\u00eda. Solo se puede acceder por la carretera vieja del norte, pero est\u00e1 muy deteriorada.", "location": "Puente", "coordinates": {"lat": 10.479, "lon": -66.902}, "affected_people": 30, "raw_text": "El puente de la entrada del barrio colaps\u00f3. No pueden entrar camiones ni ambulancias por esa v\u00eda. Solo se puede acceder por la carretera vieja del norte, pero est\u00e1 muy deteriorada.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:12.391749"} \ No newline at end of file diff --git a/backend/data/signals/dec8a437-45c9-4b10-8a7b-69709c4347f9.json b/backend/data/signals/dec8a437-45c9-4b10-8a7b-69709c4347f9.json new file mode 100644 index 0000000000000000000000000000000000000000..ed064147f47410b8f3cd881b60026a221437db71 --- /dev/null +++ b/backend/data/signals/dec8a437-45c9-4b10-8a7b-69709c4347f9.json @@ -0,0 +1 @@ +{"id": "dec8a437-45c9-4b10-8a7b-69709c4347f9", "source_report_id": "rpt_023", "signal_type": "flood", "description": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main evacuation route (Av. Principal) is completely floo", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main evacuation route (Av. Principal) is completely flooded. Hazards identified: widespread_flooding, multiple_stranded_civilians, blocked_evacuation_routes.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.468571"} \ No newline at end of file diff --git a/backend/data/signals/e948583f-eb3d-4534-8c85-e032e9987a35.json b/backend/data/signals/e948583f-eb3d-4534-8c85-e032e9987a35.json new file mode 100644 index 0000000000000000000000000000000000000000..d13d65b0b2221413b5fc71f1137d853bcb388033 --- /dev/null +++ b/backend/data/signals/e948583f-eb3d-4534-8c85-e032e9987a35.json @@ -0,0 +1 @@ +{"id": "e948583f-eb3d-4534-8c85-e032e9987a35", "source_report_id": "rpt_025", "signal_type": "flood", "description": "Heavily flooded residential street in Santa Ana district. Water level is approximately 1.5 meters high. A family of four including two children are visible on a rooftop, waving a red cloth for attenti", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Heavily flooded residential street in Santa Ana district. Water level is approximately 1.5 meters high. A family of four including two children are visible on a rooftop, waving a red cloth for attention. Hazards identified: rising_water, stranded_people, electrical_hazard.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:30.469755"} \ No newline at end of file diff --git a/backend/data/signals/f3fce772-27a3-4a1f-bd22-219ac44ae966.json b/backend/data/signals/f3fce772-27a3-4a1f-bd22-219ac44ae966.json new file mode 100644 index 0000000000000000000000000000000000000000..7957c11c99be99e96d99af58d786e47fddf53cc8 --- /dev/null +++ b/backend/data/signals/f3fce772-27a3-4a1f-bd22-219ac44ae966.json @@ -0,0 +1 @@ +{"id": "f3fce772-27a3-4a1f-bd22-219ac44ae966", "source_report_id": "rpt_025", "signal_type": "flood", "description": "Collapsed wall of a two-story brick building. Rubble and debris scattered across the street blocking vehicle access. No visible casualties in frame but possible entrapment under debris. Hazards identi", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Collapsed wall of a two-story brick building. Rubble and debris scattered across the street blocking vehicle access. No visible casualties in frame but possible entrapment under debris. Hazards identified: structural_collapse, road_blockage, possible_entrapment.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:12.392028"} \ No newline at end of file diff --git a/backend/data/signals/f5bc50bf-d597-42bd-8343-c43deb437eac.json b/backend/data/signals/f5bc50bf-d597-42bd-8343-c43deb437eac.json new file mode 100644 index 0000000000000000000000000000000000000000..3a2f15073a6341df7ba422610fd69cf25164e783 --- /dev/null +++ b/backend/data/signals/f5bc50bf-d597-42bd-8343-c43deb437eac.json @@ -0,0 +1 @@ +{"id": "f5bc50bf-d597-42bd-8343-c43deb437eac", "source_report_id": "rpt_021", "signal_type": "flood", "description": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible empty water containers and minimal food stocks. Haz", "location": "Barrio Santa Ana", "coordinates": null, "affected_people": 30, "raw_text": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low \u2014 visible empty water containers and minimal food stocks. Hazards identified: resource_shortage, vulnerable_population.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:12.391920"} \ No newline at end of file diff --git a/backend/data/signals/f7b10e45-fade-4315-99ef-57a467cbdfa7.json b/backend/data/signals/f7b10e45-fade-4315-99ef-57a467cbdfa7.json new file mode 100644 index 0000000000000000000000000000000000000000..edf692fbf416981f759616d68718a1a6d599e9be --- /dev/null +++ b/backend/data/signals/f7b10e45-fade-4315-99ef-57a467cbdfa7.json @@ -0,0 +1 @@ +{"id": "f7b10e45-fade-4315-99ef-57a467cbdfa7", "source_report_id": "rpt_016", "signal_type": "flood", "description": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, necesitamos ayuda urgente, por favor.", "location": "Calle Bol\u00edvar", "coordinates": {"lat": 10.4812, "lon": -66.9041}, "affected_people": 30, "raw_text": "Aqu\u00ed en la calle Bol\u00edvar con Sucre, el agua ya lleg\u00f3 al segundo piso. Hay una se\u00f1ora mayor que no puede caminar atrapada en el edificio amarillo, necesitamos ayuda urgente, por favor.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:12.391647"} \ No newline at end of file diff --git a/backend/data/signals/fab24ecf-60b1-450e-a0be-441764f533d9.json b/backend/data/signals/fab24ecf-60b1-450e-a0be-441764f533d9.json new file mode 100644 index 0000000000000000000000000000000000000000..688ad57f8b24be5f239d3a20028c0d78680e39e8 --- /dev/null +++ b/backend/data/signals/fab24ecf-60b1-450e-a0be-441764f533d9.json @@ -0,0 +1 @@ +{"id": "fab24ecf-60b1-450e-a0be-441764f533d9", "source_report_id": "rpt_022", "signal_type": "flood", "description": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main evacuation route (Av. Principal) is completely floo", "location": "Santa Ana", "coordinates": {"lat": 10.4806, "lon": -66.9036}, "affected_people": 30, "raw_text": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main evacuation route (Av. Principal) is completely flooded. Hazards identified: widespread_flooding, multiple_stranded_civilians, blocked_evacuation_routes.", "confidence": 0.92, "modality": "image", "created_at": "2026-05-06T01:07:12.391957"} \ No newline at end of file diff --git a/backend/data/signals/fd983943-526a-4ce4-b370-b5391a117c6f.json b/backend/data/signals/fd983943-526a-4ce4-b370-b5391a117c6f.json new file mode 100644 index 0000000000000000000000000000000000000000..ac47538a822fd7caceacc0b73fdf50a190f2ff73 --- /dev/null +++ b/backend/data/signals/fd983943-526a-4ce4-b370-b5391a117c6f.json @@ -0,0 +1 @@ +{"id": "fd983943-526a-4ce4-b370-b5391a117c6f", "source_report_id": "rpt_018", "signal_type": "flood", "description": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos cuatro horas aqu\u00ed.", "location": "Escuela Sim\u00f3n Bol\u00edvar", "coordinates": {"lat": 10.482, "lon": -66.905}, "affected_people": 30, "raw_text": "Somos diez familias en el techo de la escuela Sim\u00f3n Bol\u00edvar. Los ni\u00f1os est\u00e1n bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos cuatro horas aqu\u00ed.", "confidence": 0.92, "modality": "audio", "created_at": "2026-05-06T01:07:12.391803"} \ No newline at end of file diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000000000000000000000000000000000000..d0159b6442dee695ad61aa260d03549a45b3cafd --- /dev/null +++ b/backend/main.py @@ -0,0 +1,64 @@ +from __future__ import annotations +import logging +from contextlib import asynccontextmanager +from pathlib import Path + +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from api.routes import amd, crisis_room, demo, incidents, reports +from core.config import get_settings + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s — %(name)s — %(levelname)s — %(message)s", +) +logger = logging.getLogger(__name__) + + +@asynccontextmanager +async def lifespan(app: FastAPI): + settings = get_settings() + storage_path = Path(settings.storage_path) + for sub in ("sessions", "incidents", "signals", "resources", "dispatch"): + (storage_path / sub).mkdir(parents=True, exist_ok=True) + logger.info("ReliefLensAI backend started (demo_mode=%s)", settings.demo_mode) + yield + logger.info("ReliefLensAI backend shutting down") + + +app = FastAPI( + title="ReliefLensAI", + description="Real-time multimodal disaster triage system powered by AMD MI300X + vLLM", + version="1.0.0", + lifespan=lifespan, +) + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +app.include_router(crisis_room.router, prefix="/api") +app.include_router(reports.router, prefix="/api") +app.include_router(incidents.router, prefix="/api") +app.include_router(amd.router, prefix="/api") +app.include_router(demo.router, prefix="/api") + + +@app.get("/health", tags=["health"]) +async def health_check() -> dict: + settings = get_settings() + return { + "status": "healthy", + "demo_mode": settings.demo_mode, + "app_env": settings.app_env, + } + + +@app.get("/", tags=["root"]) +async def root() -> dict: + return {"name": "ReliefLensAI", "version": "1.0.0", "status": "ready"} diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..3d5b81992fd7fadb8ab1cf481df8b1677ee917de --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,14 @@ +fastapi>=0.110.0 +uvicorn[standard]>=0.27.0 +pydantic>=2.0.0 +pydantic-settings>=2.0.0 +python-multipart>=0.0.9 +httpx>=0.27.0 +openai>=1.12.0 +python-dotenv>=1.0.0 +aiofiles>=23.2.0 +pandas>=2.0.0 +numpy>=1.26.0 +Pillow>=10.0.0 +pytest>=8.0.0 +pytest-asyncio>=0.23.0 diff --git a/backend/schemas/__init__.py b/backend/schemas/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..798fdb68aeeab94e616c0059eb98827187e6cbb3 --- /dev/null +++ b/backend/schemas/__init__.py @@ -0,0 +1,17 @@ +from .report import ReportInput, ReportType, UploadBatch +from .signal import NormalizedSignal, SignalType +from .incident import Incident, IncidentStatus, Priority, EvidenceItem +from .resource import ResourceRecommendation, ResourceType +from .dispatch import DispatchMessage +from .amd import AMDPerformanceMetric +from .crisis_room import CrisisRoomSummary + +__all__ = [ + "ReportInput", "ReportType", "UploadBatch", + "NormalizedSignal", "SignalType", + "Incident", "IncidentStatus", "Priority", "EvidenceItem", + "ResourceRecommendation", "ResourceType", + "DispatchMessage", + "AMDPerformanceMetric", + "CrisisRoomSummary", +] diff --git a/backend/schemas/__pycache__/__init__.cpython-312.pyc b/backend/schemas/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa9a37db4e454c79d3dce5d35ee90e47a5f7a6bc Binary files /dev/null and b/backend/schemas/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/amd.cpython-312.pyc b/backend/schemas/__pycache__/amd.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5598ab499c4b908490e53e3b19cb50fd80465468 Binary files /dev/null and b/backend/schemas/__pycache__/amd.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/crisis_room.cpython-312.pyc b/backend/schemas/__pycache__/crisis_room.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cfcee1b0d8c2654cd1d20e938daca1fb6b36426 Binary files /dev/null and b/backend/schemas/__pycache__/crisis_room.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/dispatch.cpython-312.pyc b/backend/schemas/__pycache__/dispatch.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06d5c4193c6eede63fe8656cd9525f46fbae9e6a Binary files /dev/null and b/backend/schemas/__pycache__/dispatch.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/incident.cpython-312.pyc b/backend/schemas/__pycache__/incident.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff2cc7c854cbfc22ab2d48fd57e55a89ea57164c Binary files /dev/null and b/backend/schemas/__pycache__/incident.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/report.cpython-312.pyc b/backend/schemas/__pycache__/report.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5ca45159a7d37bc32592cbd2dc6313fad3863a5 Binary files /dev/null and b/backend/schemas/__pycache__/report.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/resource.cpython-312.pyc b/backend/schemas/__pycache__/resource.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf760d1cfcc523c330abfac171a5e8db569cc547 Binary files /dev/null and b/backend/schemas/__pycache__/resource.cpython-312.pyc differ diff --git a/backend/schemas/__pycache__/signal.cpython-312.pyc b/backend/schemas/__pycache__/signal.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cff543900fc13570f6299dfdcf5aa7a899cf591 Binary files /dev/null and b/backend/schemas/__pycache__/signal.cpython-312.pyc differ diff --git a/backend/schemas/amd.py b/backend/schemas/amd.py new file mode 100644 index 0000000000000000000000000000000000000000..02890c8ca141906fa397288bfd1d26750d96262a --- /dev/null +++ b/backend/schemas/amd.py @@ -0,0 +1,18 @@ +from __future__ import annotations +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + + +class AMDPerformanceMetric(BaseModel): + timestamp: datetime + gpu_utilization: float + memory_used_gb: float + memory_total_gb: float + tokens_per_second: float + requests_processed: int + avg_latency_ms: float + model_name: str + rocm_version: Optional[str] = None + power_watts: Optional[float] = None diff --git a/backend/schemas/crisis_room.py b/backend/schemas/crisis_room.py new file mode 100644 index 0000000000000000000000000000000000000000..57be63615f832efa9d7f4b8a72135566ea8bba95 --- /dev/null +++ b/backend/schemas/crisis_room.py @@ -0,0 +1,26 @@ +from __future__ import annotations +from datetime import datetime +from typing import Dict, List, Optional + +from pydantic import BaseModel + +from .amd import AMDPerformanceMetric +from .dispatch import DispatchMessage +from .incident import Incident +from .resource import ResourceRecommendation + + +class CrisisRoomSummary(BaseModel): + session_id: str + scenario_name: str + total_reports: int + total_signals: int + total_incidents: int + incidents_by_priority: Dict[str, int] + critical_incidents: List[Incident] + resource_recommendations: List[ResourceRecommendation] + dispatch_messages: List[DispatchMessage] + amd_metrics: Optional[AMDPerformanceMetric] = None + processing_time_seconds: float + created_at: datetime + status: str # processing, ready, error diff --git a/backend/schemas/dispatch.py b/backend/schemas/dispatch.py new file mode 100644 index 0000000000000000000000000000000000000000..6404a29fbeefa8ebe45c8b69fbe2676884a3c286 --- /dev/null +++ b/backend/schemas/dispatch.py @@ -0,0 +1,16 @@ +from __future__ import annotations +from datetime import datetime +from typing import Optional +import uuid + +from pydantic import BaseModel, Field + + +class DispatchMessage(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + incident_id: str + channel: str # radio, whatsapp, sms, email + message: str + brigade_target: Optional[str] = None + created_at: datetime = Field(default_factory=datetime.utcnow) + approved: bool = False diff --git a/backend/schemas/incident.py b/backend/schemas/incident.py new file mode 100644 index 0000000000000000000000000000000000000000..78afc7f3a151fdabea1d12129742e5ecfd53dc59 --- /dev/null +++ b/backend/schemas/incident.py @@ -0,0 +1,49 @@ +from __future__ import annotations +from datetime import datetime +from enum import Enum +from typing import Dict, List, Optional +import uuid + +from pydantic import BaseModel, Field + + +class Priority(str, Enum): + P0 = "P0" + P1 = "P1" + P2 = "P2" + P3 = "P3" + + +class IncidentStatus(str, Enum): + NEW = "new" + ACKNOWLEDGED = "acknowledged" + IN_PROGRESS = "in_progress" + RESOLVED = "resolved" + + +class EvidenceItem(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + report_id: str + modality: str + description: str + file_path: Optional[str] = None + timestamp: datetime = Field(default_factory=datetime.utcnow) + + +class Incident(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + session_id: str + title: str + description: str + priority: Priority + status: IncidentStatus = IncidentStatus.NEW + signal_ids: List[str] = Field(default_factory=list) + evidence: List[EvidenceItem] = Field(default_factory=list) + location: Optional[str] = None + coordinates: Optional[Dict[str, float]] = None + affected_people: Optional[int] = None + confidence: float = Field(ge=0.0, le=1.0) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + human_approved: bool = False + notes: Optional[str] = None diff --git a/backend/schemas/report.py b/backend/schemas/report.py new file mode 100644 index 0000000000000000000000000000000000000000..d7855c82eaf2cfc9b1747c554aebd21efbf47138 --- /dev/null +++ b/backend/schemas/report.py @@ -0,0 +1,31 @@ +from __future__ import annotations +from datetime import datetime +from enum import Enum +from typing import Any, Dict, List, Optional +import uuid + +from pydantic import BaseModel, Field + + +class ReportType(str, Enum): + TEXT = "text" + AUDIO = "audio" + IMAGE = "image" + CSV = "csv" + LOCATION = "location" + + +class ReportInput(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + session_id: str + report_type: ReportType + content: Optional[str] = None + file_path: Optional[str] = None + metadata: Dict[str, Any] = Field(default_factory=dict) + created_at: datetime = Field(default_factory=datetime.utcnow) + + +class UploadBatch(BaseModel): + session_id: str = Field(default_factory=lambda: str(uuid.uuid4())) + reports: List[ReportInput] + scenario_name: Optional[str] = None diff --git a/backend/schemas/resource.py b/backend/schemas/resource.py new file mode 100644 index 0000000000000000000000000000000000000000..7162f6c9288eb34dc5456941c0a6f1ec0947dbe5 --- /dev/null +++ b/backend/schemas/resource.py @@ -0,0 +1,27 @@ +from __future__ import annotations +from enum import Enum +from typing import Optional +import uuid + +from pydantic import BaseModel, Field + + +class ResourceType(str, Enum): + RESCUE_TEAM = "rescue_team" + MEDICAL = "medical" + WATER = "water" + FOOD = "food" + SHELTER = "shelter" + TRANSPORT = "transport" + COMMUNICATION = "communication" + STRUCTURAL = "structural" + + +class ResourceRecommendation(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + incident_id: str + resource_type: ResourceType + description: str + quantity: Optional[int] = None + urgency: str # immediate, within_hour, within_day + rationale: str diff --git a/backend/schemas/signal.py b/backend/schemas/signal.py new file mode 100644 index 0000000000000000000000000000000000000000..744056baaabfbf0e93a182f4c56e48b10dfabe9f --- /dev/null +++ b/backend/schemas/signal.py @@ -0,0 +1,33 @@ +from __future__ import annotations +from datetime import datetime +from enum import Enum +from typing import Any, Dict, Optional +import uuid + +from pydantic import BaseModel, Field + + +class SignalType(str, Enum): + STRUCTURAL_DAMAGE = "structural_damage" + PERSON_TRAPPED = "person_trapped" + MEDICAL_EMERGENCY = "medical_emergency" + FLOOD = "flood" + FIRE = "fire" + MISSING_PERSON = "missing_person" + RESOURCE_REQUEST = "resource_request" + SAFE_STATUS = "safe_status" + UNKNOWN = "unknown" + + +class NormalizedSignal(BaseModel): + id: str = Field(default_factory=lambda: str(uuid.uuid4())) + source_report_id: str + signal_type: SignalType + description: str + location: Optional[str] = None + coordinates: Optional[Dict[str, float]] = None + affected_people: Optional[int] = None + raw_text: str + confidence: float = Field(ge=0.0, le=1.0) + modality: str + created_at: datetime = Field(default_factory=datetime.utcnow) diff --git a/backend/services/__init__.py b/backend/services/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/services/__pycache__/__init__.cpython-312.pyc b/backend/services/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae037b5b7499816cb919b4db90fb2767296c1473 Binary files /dev/null and b/backend/services/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/services/__pycache__/pipeline.cpython-312.pyc b/backend/services/__pycache__/pipeline.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..764bfc0803f5fa5c086718bbd911a629cc010d2d Binary files /dev/null and b/backend/services/__pycache__/pipeline.cpython-312.pyc differ diff --git a/backend/services/__pycache__/storage.cpython-312.pyc b/backend/services/__pycache__/storage.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc99193974b25cbcf95d9071829c125c6f10b6d3 Binary files /dev/null and b/backend/services/__pycache__/storage.cpython-312.pyc differ diff --git a/backend/services/__pycache__/vllm_client.cpython-312.pyc b/backend/services/__pycache__/vllm_client.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e1f3a119821cc910c34f948d63b1b4922a3b4ad Binary files /dev/null and b/backend/services/__pycache__/vllm_client.cpython-312.pyc differ diff --git a/backend/services/pipeline.py b/backend/services/pipeline.py new file mode 100644 index 0000000000000000000000000000000000000000..e7c17c7e90f228bbbee232d8071fbf242392dc98 --- /dev/null +++ b/backend/services/pipeline.py @@ -0,0 +1,170 @@ +from __future__ import annotations +import asyncio +import logging +import time +import uuid +from datetime import datetime +from typing import Dict, List + +from agents.dedup_agent import DedupAgent +from agents.dispatch_agent import DispatchAgent +from agents.intake_agent import IntakeAgent +from agents.normalization_agent import NormalizationAgent +from agents.resource_agent import ResourceAgent +from agents.triage_agent import TriageAgent +from agents.transcription_agent import TranscriptionAgent +from agents.vision_agent import VisionAgent +from core.config import get_settings +from schemas.crisis_room import CrisisRoomSummary +from schemas.incident import Incident, Priority +from schemas.report import ReportInput, ReportType, UploadBatch +from schemas.signal import NormalizedSignal +from services.storage import get_storage +from services.vllm_client import get_vllm_client +from skills.fetch_amd_metrics import fetch_amd_metrics + +logger = logging.getLogger(__name__) + + +class Pipeline: + def __init__(self) -> None: + self.settings = get_settings() + self.storage = get_storage() + self.vllm = get_vllm_client() + + async def process_batch(self, batch: UploadBatch) -> CrisisRoomSummary: + t_start = time.monotonic() + session_id = batch.session_id + scenario_name = batch.scenario_name or "Disaster Response Session" + + logger.info("Pipeline: processing batch session=%s (%d reports)", session_id, len(batch.reports)) + + await self.storage.save_session(session_id, { + "session_id": session_id, + "scenario_name": scenario_name, + "total_reports": len(batch.reports), + "status": "processing", + "created_at": datetime.utcnow().isoformat(), + }) + + # Step 1: Intake + intake_agent = IntakeAgent() + raw_signals: List[NormalizedSignal] = [] + for report in batch.reports: + sig = await intake_agent.run(report) + raw_signals.append(sig) + + # Step 2 & 3: Transcription + Vision (in parallel) + transcription_agent = TranscriptionAgent() + vision_agent = VisionAgent() + normalization_agent = NormalizationAgent(vllm_client=self.vllm) + + text_signals: List[NormalizedSignal] = [] + + audio_reports = [r for r in batch.reports if r.report_type == ReportType.AUDIO] + image_reports = [r for r in batch.reports if r.report_type == ReportType.IMAGE] + text_reports = [r for r in batch.reports if r.report_type in (ReportType.TEXT, ReportType.CSV, ReportType.LOCATION)] + + async def process_audio(report: ReportInput) -> NormalizedSignal: + transcription = await transcription_agent.run(report) + return await normalization_agent.run(transcription, report.id, "audio") + + async def process_image(report: ReportInput) -> NormalizedSignal: + caption = await vision_agent.run(report) + return await normalization_agent.run(caption, report.id, "image") + + async def process_text(report: ReportInput) -> NormalizedSignal: + content = report.content or "" + return await normalization_agent.run(content, report.id, report.report_type.value) + + tasks = ( + [process_audio(r) for r in audio_reports] + + [process_image(r) for r in image_reports] + + [process_text(r) for r in text_reports] + ) + + if tasks: + results = await asyncio.gather(*tasks, return_exceptions=True) + for result in results: + if isinstance(result, NormalizedSignal): + text_signals.append(result) + elif isinstance(result, Exception): + logger.warning("Signal processing error: %s", result) + + all_signals = text_signals if text_signals else raw_signals + + # Step 5: Dedup + dedup_agent = DedupAgent(threshold=0.75) + unique_signals = await dedup_agent.run(all_signals) + + # Save signals + for signal in unique_signals: + await self.storage.save_signal(signal.id, signal.model_dump(mode="json")) + + # Step 6: Triage + triage_agent = TriageAgent(session_id=session_id, vllm_client=self.vllm) + incidents = await triage_agent.run(unique_signals) + for incident in incidents: + await self.storage.save_incident(incident.id, incident.model_dump(mode="json")) + + # Step 7: Resources + resource_agent = ResourceAgent(vllm_client=self.vllm) + resources = await resource_agent.run(incidents) + for resource in resources: + await self.storage.save_resource(resource.id, resource.model_dump(mode="json")) + + # Step 8: Dispatch + dispatch_agent = DispatchAgent(vllm_client=self.vllm) + dispatch_messages = await dispatch_agent.run(incidents, resources) + for msg in dispatch_messages: + await self.storage.save_dispatch(msg.id, msg.model_dump(mode="json")) + + # Step 9: AMD metrics + amd_metrics = await fetch_amd_metrics( + self.settings.vllm_base_url, + demo_mode=self.settings.demo_mode, + ) + + # Step 10: Build summary + incidents_by_priority: Dict[str, int] = {"P0": 0, "P1": 0, "P2": 0, "P3": 0} + for inc in incidents: + incidents_by_priority[inc.priority.value] += 1 + + critical = [i for i in incidents if i.priority in (Priority.P0, Priority.P1)] + + processing_time = time.monotonic() - t_start + + summary = CrisisRoomSummary( + session_id=session_id, + scenario_name=scenario_name, + total_reports=len(batch.reports), + total_signals=len(unique_signals), + total_incidents=len(incidents), + incidents_by_priority=incidents_by_priority, + critical_incidents=critical, + resource_recommendations=resources, + dispatch_messages=dispatch_messages, + amd_metrics=amd_metrics, + processing_time_seconds=round(processing_time, 2), + created_at=datetime.utcnow(), + status="ready", + ) + + await self.storage.save_session(session_id, { + "session_id": session_id, + "scenario_name": scenario_name, + "total_reports": len(batch.reports), + "total_signals": len(unique_signals), + "total_incidents": len(incidents), + "status": "ready", + "processing_time_seconds": round(processing_time, 2), + "created_at": datetime.utcnow().isoformat(), + }) + + logger.info( + "Pipeline complete: session=%s incidents=%d time=%.2fs", + session_id, + len(incidents), + processing_time, + ) + return summary diff --git a/backend/services/storage.py b/backend/services/storage.py new file mode 100644 index 0000000000000000000000000000000000000000..61a142556fcf871059212119f0d50ab8884e8366 --- /dev/null +++ b/backend/services/storage.py @@ -0,0 +1,115 @@ +from __future__ import annotations +import asyncio +import json +import logging +import os +from pathlib import Path +from typing import Any, Dict, List, Optional +from functools import lru_cache + +from core.config import get_settings + +logger = logging.getLogger(__name__) + + +class StorageService: + def __init__(self) -> None: + self.settings = get_settings() + self._cache: Dict[str, Any] = {} + self._lock = asyncio.Lock() + self.base_path = Path(self.settings.storage_path) + + def _ensure_dirs(self) -> None: + for sub in ("sessions", "incidents", "signals", "resources", "dispatch"): + (self.base_path / sub).mkdir(parents=True, exist_ok=True) + + def _path(self, collection: str, item_id: str) -> Path: + return self.base_path / collection / f"{item_id}.json" + + async def _write(self, collection: str, item_id: str, data: Dict[str, Any]) -> None: + self._ensure_dirs() + cache_key = f"{collection}:{item_id}" + async with self._lock: + self._cache[cache_key] = data + loop = asyncio.get_event_loop() + await loop.run_in_executor(None, self._sync_write, collection, item_id, data) + + def _sync_write(self, collection: str, item_id: str, data: Dict[str, Any]) -> None: + path = self._path(collection, item_id) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(data, default=str), encoding="utf-8") + + async def _read(self, collection: str, item_id: str) -> Optional[Dict[str, Any]]: + cache_key = f"{collection}:{item_id}" + if cache_key in self._cache: + return self._cache[cache_key] + path = self._path(collection, item_id) + if not path.exists(): + return None + try: + data: Dict[str, Any] = json.loads(path.read_text(encoding="utf-8")) + self._cache[cache_key] = data + return data + except Exception as exc: + logger.error("Failed to read %s: %s", path, exc) + return None + + async def _list(self, collection: str) -> List[Dict[str, Any]]: + self._ensure_dirs() + folder = self.base_path / collection + items: List[Dict[str, Any]] = [] + for fp in folder.glob("*.json"): + try: + items.append(json.loads(fp.read_text(encoding="utf-8"))) + except Exception as exc: + logger.warning("Skip corrupt file %s: %s", fp, exc) + return items + + async def save_session(self, session_id: str, data: Dict[str, Any]) -> None: + await self._write("sessions", session_id, data) + + async def get_session(self, session_id: str) -> Optional[Dict[str, Any]]: + return await self._read("sessions", session_id) + + async def save_incident(self, incident_id: str, data: Dict[str, Any]) -> None: + await self._write("incidents", incident_id, data) + + async def get_incident(self, incident_id: str) -> Optional[Dict[str, Any]]: + return await self._read("incidents", incident_id) + + async def list_incidents(self) -> List[Dict[str, Any]]: + return await self._list("incidents") + + async def save_signal(self, signal_id: str, data: Dict[str, Any]) -> None: + await self._write("signals", signal_id, data) + + async def get_signal(self, signal_id: str) -> Optional[Dict[str, Any]]: + return await self._read("signals", signal_id) + + async def list_signals(self) -> List[Dict[str, Any]]: + return await self._list("signals") + + async def save_resource(self, resource_id: str, data: Dict[str, Any]) -> None: + await self._write("resources", resource_id, data) + + async def list_resources(self) -> List[Dict[str, Any]]: + return await self._list("resources") + + async def save_dispatch(self, dispatch_id: str, data: Dict[str, Any]) -> None: + await self._write("dispatch", dispatch_id, data) + + async def list_dispatch(self) -> List[Dict[str, Any]]: + return await self._list("dispatch") + + async def update_incident(self, incident_id: str, updates: Dict[str, Any]) -> Optional[Dict[str, Any]]: + existing = await self.get_incident(incident_id) + if existing is None: + return None + existing.update(updates) + await self.save_incident(incident_id, existing) + return existing + + +@lru_cache() +def get_storage() -> StorageService: + return StorageService() diff --git a/backend/services/vllm_client.py b/backend/services/vllm_client.py new file mode 100644 index 0000000000000000000000000000000000000000..453ff6dc1342cf02bd0b8b91bf041137ea7688e6 --- /dev/null +++ b/backend/services/vllm_client.py @@ -0,0 +1,141 @@ +from __future__ import annotations +import asyncio +import json +import logging +import time +from functools import lru_cache +from typing import Any, Dict, Optional + +import httpx + +from core.config import get_settings + +logger = logging.getLogger(__name__) + +_DEMO_RESPONSES: Dict[str, str] = { + "normalize": json.dumps({ + "signal_type": "flood", + "description": "Inundación reportada en Barrio Santa Ana, agua alcanza 1.5 metros", + "location": "Barrio Santa Ana", + "coordinates": {"lat": 10.4806, "lon": -66.9036}, + "affected_people": 30, + "confidence": 0.92, + }), + "classify": json.dumps({"priority": "P1", "rationale": "Urgente — comunidad sin vías de evacuación"}), + "resources": json.dumps([ + {"resource_type": "rescue_team", "description": "Equipo de rescate acuático", "quantity": 2, "urgency": "immediate", "rationale": "Personas atrapadas en techos"}, + {"resource_type": "medical", "description": "Paramédicos con botiquín de trauma", "quantity": 4, "urgency": "immediate", "rationale": "Posibles heridos"}, + {"resource_type": "water", "description": "Agua potable embotellada", "quantity": 500, "urgency": "within_hour", "rationale": "Contaminación del suministro local"}, + ]), + "dispatch": "ALERTA P1 - Barrio Santa Ana: Inundación severa, familias en techos. Recursos: 2 equipos rescate acuático, 4 paramédicos, 500 botellas agua. Coordinar con: Brigada Norte. Contacto: Canal 7.", +} + + +class VLLMClient: + def __init__(self) -> None: + self.settings = get_settings() + self._request_count = 0 + self._total_latency_ms = 0.0 + + async def complete(self, prompt: str, system: str = "", max_tokens: int = 1000) -> str: + if self.settings.demo_mode: + await asyncio.sleep(0.05) + for key, val in _DEMO_RESPONSES.items(): + if key in prompt.lower(): + return val + return _DEMO_RESPONSES["normalize"] + + t0 = time.monotonic() + try: + async with httpx.AsyncClient(timeout=30) as client: + payload = { + "model": self.settings.vllm_model, + "messages": [ + {"role": "system", "content": system or "You are a helpful disaster response assistant."}, + {"role": "user", "content": prompt}, + ], + "max_tokens": max_tokens, + "temperature": 0.1, + } + resp = await client.post( + f"{self.settings.vllm_base_url}/chat/completions", + json=payload, + headers={"Authorization": f"Bearer {self.settings.vllm_api_key}"}, + ) + resp.raise_for_status() + data = resp.json() + content: str = data["choices"][0]["message"]["content"] + except Exception as exc: + logger.warning("vLLM complete failed: %s", exc) + return _DEMO_RESPONSES["normalize"] + finally: + elapsed = (time.monotonic() - t0) * 1000 + self._total_latency_ms += elapsed + self._request_count += 1 + return content + + async def complete_json(self, prompt: str, system: str = "", schema: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + raw = await self.complete(prompt, system=system) + raw = raw.strip() + if raw.startswith("```"): + raw = raw.split("```")[1] + if raw.startswith("json"): + raw = raw[4:] + try: + return json.loads(raw) + except json.JSONDecodeError: + logger.warning("Failed to parse JSON from LLM response, returning empty dict") + return {} + + async def caption_image(self, image_base64: str, prompt: str = "") -> str: + if self.settings.demo_mode: + await asyncio.sleep(0.05) + return ( + "Flooded street in residential area. Water level approximately 1.2 meters. " + "A family of four visible on rooftop waving for help. Submerged vehicles. " + "Single-story homes partially underwater. Power lines dangerously close to water." + ) + + t0 = time.monotonic() + try: + async with httpx.AsyncClient(timeout=60) as client: + payload = { + "model": self.settings.vllm_vision_model, + "messages": [ + { + "role": "user", + "content": [ + {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_base64}"}}, + {"type": "text", "text": prompt or "Describe this disaster scene in detail. Focus on victims, structural damage, and immediate hazards."}, + ], + } + ], + "max_tokens": 500, + } + resp = await client.post( + f"{self.settings.vllm_base_url}/chat/completions", + json=payload, + headers={"Authorization": f"Bearer {self.settings.vllm_api_key}"}, + ) + resp.raise_for_status() + data = resp.json() + caption: str = data["choices"][0]["message"]["content"] + except Exception as exc: + logger.warning("vLLM caption_image failed: %s", exc) + caption = "Image analysis unavailable — vLLM connection error." + finally: + elapsed = (time.monotonic() - t0) * 1000 + self._total_latency_ms += elapsed + self._request_count += 1 + return caption + + @property + def avg_latency_ms(self) -> float: + if self._request_count == 0: + return 0.0 + return self._total_latency_ms / self._request_count + + +@lru_cache() +def get_vllm_client() -> VLLMClient: + return VLLMClient() diff --git a/backend/skills/__init__.py b/backend/skills/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cc342833d03479ac9e0d4e88513385ec8bce8d8 --- /dev/null +++ b/backend/skills/__init__.py @@ -0,0 +1,25 @@ +from .transcribe_audio import transcribe_audio +from .caption_image import caption_image +from .extract_location import extract_location +from .normalize_signal import normalize_signal +from .detect_duplicates import detect_duplicates +from .classify_priority import classify_priority +from .recommend_resources import recommend_resources +from .generate_dispatch_message import generate_dispatch_message +from .calculate_confidence import calculate_confidence +from .fetch_amd_metrics import fetch_amd_metrics +from .export_incident_report import export_incident_report + +__all__ = [ + "transcribe_audio", + "caption_image", + "extract_location", + "normalize_signal", + "detect_duplicates", + "classify_priority", + "recommend_resources", + "generate_dispatch_message", + "calculate_confidence", + "fetch_amd_metrics", + "export_incident_report", +] diff --git a/backend/skills/__pycache__/__init__.cpython-312.pyc b/backend/skills/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c3f3279fec1ee578d4d0089b39a8540ca4482d9 Binary files /dev/null and b/backend/skills/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/calculate_confidence.cpython-312.pyc b/backend/skills/__pycache__/calculate_confidence.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37ad90b5c99189bd6c7df4cb932dcc35d5717056 Binary files /dev/null and b/backend/skills/__pycache__/calculate_confidence.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/caption_image.cpython-312.pyc b/backend/skills/__pycache__/caption_image.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4c4fe5c55a107dfe6b9c276d4be1ab7395df6d2 Binary files /dev/null and b/backend/skills/__pycache__/caption_image.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/classify_priority.cpython-312.pyc b/backend/skills/__pycache__/classify_priority.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8effbede6017c980a9a4400fe727c4aa782a2edf Binary files /dev/null and b/backend/skills/__pycache__/classify_priority.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/detect_duplicates.cpython-312.pyc b/backend/skills/__pycache__/detect_duplicates.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7754c481d117a7d88f889941c6cb6c7da6dc675f Binary files /dev/null and b/backend/skills/__pycache__/detect_duplicates.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/export_incident_report.cpython-312.pyc b/backend/skills/__pycache__/export_incident_report.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6aa139d438d04e3702921df24b76be0d9fab804c Binary files /dev/null and b/backend/skills/__pycache__/export_incident_report.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/extract_location.cpython-312.pyc b/backend/skills/__pycache__/extract_location.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e4fb34fbbfaa3f8e95f04916ac6b6a5d7229952 Binary files /dev/null and b/backend/skills/__pycache__/extract_location.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/fetch_amd_metrics.cpython-312.pyc b/backend/skills/__pycache__/fetch_amd_metrics.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be0da23cfc7c6c61547f3ffbcec2ace7943b9002 Binary files /dev/null and b/backend/skills/__pycache__/fetch_amd_metrics.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/generate_dispatch_message.cpython-312.pyc b/backend/skills/__pycache__/generate_dispatch_message.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee0e17099f3b2d4e97d2f509cdd1552e16821f2b Binary files /dev/null and b/backend/skills/__pycache__/generate_dispatch_message.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/normalize_signal.cpython-312.pyc b/backend/skills/__pycache__/normalize_signal.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d098253be45e045d1265b724433862a3cdf9230 Binary files /dev/null and b/backend/skills/__pycache__/normalize_signal.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/recommend_resources.cpython-312.pyc b/backend/skills/__pycache__/recommend_resources.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..badad99c801c5bb692714f823a635cb82908886d Binary files /dev/null and b/backend/skills/__pycache__/recommend_resources.cpython-312.pyc differ diff --git a/backend/skills/__pycache__/transcribe_audio.cpython-312.pyc b/backend/skills/__pycache__/transcribe_audio.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e47d81efb0ff824c127929d6c37e21c24888eb7b Binary files /dev/null and b/backend/skills/__pycache__/transcribe_audio.cpython-312.pyc differ diff --git a/backend/skills/calculate_confidence.py b/backend/skills/calculate_confidence.py new file mode 100644 index 0000000000000000000000000000000000000000..4ea3cb57ee680e4bdeebbe75ab0945e3407896b5 --- /dev/null +++ b/backend/skills/calculate_confidence.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from typing import List + +from schemas.signal import NormalizedSignal + + +async def calculate_confidence(signals: List[NormalizedSignal]) -> float: + if not signals: + return 0.0 + + weights = { + "text": 1.0, + "audio": 0.9, + "image": 1.1, + "csv": 0.8, + "location": 0.7, + } + + total_weight = 0.0 + weighted_sum = 0.0 + for signal in signals: + w = weights.get(signal.modality, 1.0) + weighted_sum += signal.confidence * w + total_weight += w + + if total_weight == 0: + return 0.0 + + base = weighted_sum / total_weight + + count_bonus = min(0.05 * (len(signals) - 1), 0.15) + return round(min(base + count_bonus, 1.0), 3) diff --git a/backend/skills/caption_image.py b/backend/skills/caption_image.py new file mode 100644 index 0000000000000000000000000000000000000000..415ba395e9169f82dccebb7f352c1eb8c6f76266 --- /dev/null +++ b/backend/skills/caption_image.py @@ -0,0 +1,83 @@ +from __future__ import annotations +from typing import Any, Dict, List + +_DEMO_CAPTIONS = [ + { + "caption": "Heavily flooded residential street in Santa Ana district. Water level is approximately 1.5 meters high. A family of four including two children are visible on a rooftop, waving a red cloth for attention.", + "objects_detected": ["flooded_street", "people_on_roof", "submerged_vehicles", "residential_buildings"], + "confidence": 0.93, + "hazards": ["rising_water", "stranded_people", "electrical_hazard"], + }, + { + "caption": "Collapsed wall of a two-story brick building. Rubble and debris scattered across the street blocking vehicle access. No visible casualties in frame but possible entrapment under debris.", + "objects_detected": ["collapsed_building", "debris", "blocked_road"], + "confidence": 0.91, + "hazards": ["structural_collapse", "road_blockage", "possible_entrapment"], + }, + { + "caption": "Community center being used as emergency shelter. Approximately 40 people visible including elderly and children. Supplies are running low — visible empty water containers and minimal food stocks.", + "objects_detected": ["shelter", "civilians", "empty_containers", "elderly_people", "children"], + "confidence": 0.95, + "hazards": ["resource_shortage", "vulnerable_population"], + }, + { + "caption": "Flooded main road with a partially submerged ambulance attempting to navigate. Water level at door level. Emergency vehicle unable to proceed. A pedestrian bridge visible in background shows water is 2m above normal.", + "objects_detected": ["flooded_road", "ambulance", "pedestrian_bridge", "emergency_vehicle"], + "confidence": 0.88, + "hazards": ["blocked_emergency_access", "high_water_level"], + }, + { + "caption": "Aerial view of the Santa Ana neighborhood. Approximately 60% of the area is under water. Multiple rooftops with stranded residents visible. The main evacuation route (Av. Principal) is completely flooded.", + "objects_detected": ["aerial_view", "flooded_neighborhood", "rooftop_survivors", "blocked_roads"], + "confidence": 0.96, + "hazards": ["widespread_flooding", "multiple_stranded_civilians", "blocked_evacuation_routes"], + }, + { + "caption": "Makeshift raft carrying three adults navigating between houses. Improvised from wooden pallets and plastic barrels. One person appears to have a bandaged leg injury.", + "objects_detected": ["makeshift_raft", "injured_person", "improvised_flotation", "adults"], + "confidence": 0.87, + "hazards": ["unstable_flotation", "injured_civilian", "flood_navigation_risk"], + }, + { + "caption": "Flooded electrical substation with water reaching transformer level. Live wires in contact with floodwater visible. No civilians in immediate vicinity but risk of electrocution to anyone in the area.", + "objects_detected": ["electrical_substation", "live_wires", "floodwater", "transformer"], + "confidence": 0.94, + "hazards": ["electrocution_risk", "live_wires_in_water", "critical_infrastructure_failure"], + }, + { + "caption": "Child approximately 8 years old sitting alone on a fence post surrounded by floodwater. Location appears to be near the Santa Ana primary school. No adults visible nearby. Child appears distressed.", + "objects_detected": ["child", "fence_post", "floodwater", "school_building"], + "confidence": 0.98, + "hazards": ["unaccompanied_minor", "immediate_rescue_needed", "drowning_risk"], + }, +] + + +async def caption_image(image_path: str, demo_mode: bool = True) -> Dict[str, Any]: + if demo_mode: + idx = abs(hash(image_path)) % len(_DEMO_CAPTIONS) + result = _DEMO_CAPTIONS[idx].copy() + result["image_path"] = image_path + return result + + try: + import base64 + from pathlib import Path + from services.vllm_client import get_vllm_client + + client = get_vllm_client() + data = Path(image_path).read_bytes() + b64 = base64.b64encode(data).decode() + caption = await client.caption_image(b64) + return { + "caption": caption, + "objects_detected": [], + "confidence": 0.85, + "hazards": [], + "image_path": image_path, + } + except Exception: + idx = abs(hash(image_path)) % len(_DEMO_CAPTIONS) + result = _DEMO_CAPTIONS[idx].copy() + result["image_path"] = image_path + return result diff --git a/backend/skills/classify_priority.py b/backend/skills/classify_priority.py new file mode 100644 index 0000000000000000000000000000000000000000..4869b80169c9974eadd0174109cf3107705af671 --- /dev/null +++ b/backend/skills/classify_priority.py @@ -0,0 +1,50 @@ +from __future__ import annotations +import logging +from typing import Any, Optional + +from schemas.incident import Priority +from schemas.signal import NormalizedSignal, SignalType + +logger = logging.getLogger(__name__) + +_PRIORITY_RULES = { + SignalType.PERSON_TRAPPED: Priority.P0, + SignalType.MEDICAL_EMERGENCY: Priority.P0, + SignalType.FIRE: Priority.P0, + SignalType.STRUCTURAL_DAMAGE: Priority.P1, + SignalType.MISSING_PERSON: Priority.P1, + SignalType.FLOOD: Priority.P1, + SignalType.RESOURCE_REQUEST: Priority.P2, + SignalType.SAFE_STATUS: Priority.P3, + SignalType.UNKNOWN: Priority.P2, +} + +_P0_KEYWORDS = ["atrapado", "trapped", "no puede salir", "inconsciente", "unconscious", "no respira", "not breathing", "critical", "crítico", "sangre", "bleeding", "niño solo", "child alone"] +_P1_KEYWORDS = ["urgente", "urgent", "rescate", "rescue", "evacuar", "evacuate", "herido", "injured", "derrumbe", "collapse"] + + +async def classify_priority( + signal: NormalizedSignal, + vllm_client: Any = None, +) -> Priority: + base = _PRIORITY_RULES.get(signal.signal_type, Priority.P2) + + text_lower = signal.raw_text.lower() + + if any(kw in text_lower for kw in _P0_KEYWORDS): + if base in (Priority.P1, Priority.P2): + logger.debug("Upgrading signal %s to P0 due to critical keywords", signal.id) + return Priority.P0 + + if any(kw in text_lower for kw in _P1_KEYWORDS): + if base == Priority.P2: + logger.debug("Upgrading signal %s to P1 due to urgency keywords", signal.id) + return Priority.P1 + + if signal.affected_people and signal.affected_people > 20: + if base == Priority.P2: + return Priority.P1 + if base == Priority.P1: + return Priority.P0 + + return base diff --git a/backend/skills/detect_duplicates.py b/backend/skills/detect_duplicates.py new file mode 100644 index 0000000000000000000000000000000000000000..ca1fb146f1f0b88d6eeb8563d63ab1c10e37673d --- /dev/null +++ b/backend/skills/detect_duplicates.py @@ -0,0 +1,50 @@ +from __future__ import annotations +import logging +from typing import List, Set + +from schemas.signal import NormalizedSignal + +logger = logging.getLogger(__name__) + + +def _tokenize(text: str) -> Set[str]: + return set(text.lower().split()) + + +def _jaccard(a: Set[str], b: Set[str]) -> float: + if not a and not b: + return 1.0 + intersection = len(a & b) + union = len(a | b) + return intersection / union if union > 0 else 0.0 + + +async def detect_duplicates( + signals: List[NormalizedSignal], + threshold: float = 0.75, +) -> List[NormalizedSignal]: + if len(signals) <= 1: + return signals + + unique: List[NormalizedSignal] = [] + tokenized = [_tokenize(s.raw_text) for s in signals] + + for i, signal in enumerate(signals): + is_dup = False + for j, kept in enumerate(unique): + kept_idx = signals.index(kept) + sim = _jaccard(tokenized[i], tokenized[kept_idx]) + if sim >= threshold: + is_dup = True + logger.debug( + "Signal %s is duplicate of %s (jaccard=%.2f)", + signal.id, + kept.id, + sim, + ) + break + if not is_dup: + unique.append(signal) + + logger.info("Dedup: %d → %d signals (removed %d duplicates)", len(signals), len(unique), len(signals) - len(unique)) + return unique diff --git a/backend/skills/export_incident_report.py b/backend/skills/export_incident_report.py new file mode 100644 index 0000000000000000000000000000000000000000..a311073a806faabf516128395981671f2e36cc6a --- /dev/null +++ b/backend/skills/export_incident_report.py @@ -0,0 +1,31 @@ +from __future__ import annotations +import csv +import io +import json +from typing import List + +from schemas.incident import Incident + + +async def export_incident_report(incidents: List[Incident], format: str = "json") -> str: + if format == "json": + data = [inc.model_dump(mode="json") for inc in incidents] + return json.dumps(data, indent=2, default=str) + + if format == "csv": + output = io.StringIO() + if not incidents: + return "" + fieldnames = [ + "id", "session_id", "title", "description", "priority", + "status", "location", "affected_people", "confidence", + "created_at", "human_approved", + ] + writer = csv.DictWriter(output, fieldnames=fieldnames, extrasaction="ignore") + writer.writeheader() + for inc in incidents: + row = inc.model_dump(mode="json") + writer.writerow({k: row.get(k, "") for k in fieldnames}) + return output.getvalue() + + raise ValueError(f"Unsupported format: {format}. Use 'json' or 'csv'.") diff --git a/backend/skills/extract_location.py b/backend/skills/extract_location.py new file mode 100644 index 0000000000000000000000000000000000000000..9939e28e32c771285880a81cd54593d692c7a0a9 --- /dev/null +++ b/backend/skills/extract_location.py @@ -0,0 +1,64 @@ +from __future__ import annotations +import re +from typing import Any, Dict, Optional + +_KNOWN_LOCATIONS: Dict[str, Dict[str, float]] = { + "barrio santa ana": {"lat": 10.4806, "lon": -66.9036}, + "santa ana": {"lat": 10.4806, "lon": -66.9036}, + "calle bolívar": {"lat": 10.4812, "lon": -66.9041}, + "calle bolivar": {"lat": 10.4812, "lon": -66.9041}, + "av. principal": {"lat": 10.4795, "lon": -66.9028}, + "avenida principal": {"lat": 10.4795, "lon": -66.9028}, + "escuela simón bolívar": {"lat": 10.4820, "lon": -66.9050}, + "centro comunitario": {"lat": 10.4808, "lon": -66.9033}, + "calle 5": {"lat": 10.4801, "lon": -66.9043}, + "puente": {"lat": 10.4790, "lon": -66.9020}, +} + +_LOCATION_PATTERNS = [ + r"(?:calle|carrera|avenida|av\.|blvd\.?)\s+[\w\s]+", + r"barrio\s+[\w\s]+", + r"sector\s+[\w\s]+", + r"entre\s+[\w\s]+\s+y\s+[\w\s]+", + r"esquina\s+[\w\s]+", + r"cerca\s+(?:de\s+)?[\w\s]+", +] + + +async def extract_location(text: str) -> Dict[str, Any]: + text_lower = text.lower() + + for loc_name, coords in _KNOWN_LOCATIONS.items(): + if loc_name in text_lower: + return { + "location_name": loc_name.title(), + "coordinates": coords, + "confidence": 0.90, + "method": "known_location_lookup", + } + + for pattern in _LOCATION_PATTERNS: + match = re.search(pattern, text_lower, re.IGNORECASE) + if match: + location_text = match.group().strip() + return { + "location_name": location_text.title(), + "coordinates": None, + "confidence": 0.65, + "method": "regex_extraction", + } + + if "santa ana" in text_lower or "barrio" in text_lower: + return { + "location_name": "Barrio Santa Ana", + "coordinates": {"lat": 10.4806, "lon": -66.9036}, + "confidence": 0.75, + "method": "context_inference", + } + + return { + "location_name": None, + "coordinates": None, + "confidence": 0.0, + "method": "not_found", + } diff --git a/backend/skills/fetch_amd_metrics.py b/backend/skills/fetch_amd_metrics.py new file mode 100644 index 0000000000000000000000000000000000000000..9f38ea9083c06bce1b4a0f071bedef814eff41af --- /dev/null +++ b/backend/skills/fetch_amd_metrics.py @@ -0,0 +1,86 @@ +from __future__ import annotations +import asyncio +from datetime import datetime +from typing import Optional + +from schemas.amd import AMDPerformanceMetric + + +_DEMO_METRICS = AMDPerformanceMetric( + timestamp=datetime.utcnow(), + gpu_utilization=87.4, + memory_used_gb=182.3, + memory_total_gb=192.0, + tokens_per_second=2340.5, + requests_processed=128, + avg_latency_ms=312.7, + model_name="Qwen/Qwen2.5-72B-Instruct", + rocm_version="6.1.0", + power_watts=680.2, +) + + +async def fetch_amd_metrics( + vllm_base_url: str, + demo_mode: bool = True, +) -> AMDPerformanceMetric: + if demo_mode: + await asyncio.sleep(0.01) + return AMDPerformanceMetric( + timestamp=datetime.utcnow(), + gpu_utilization=_DEMO_METRICS.gpu_utilization, + memory_used_gb=_DEMO_METRICS.memory_used_gb, + memory_total_gb=_DEMO_METRICS.memory_total_gb, + tokens_per_second=_DEMO_METRICS.tokens_per_second, + requests_processed=_DEMO_METRICS.requests_processed, + avg_latency_ms=_DEMO_METRICS.avg_latency_ms, + model_name=_DEMO_METRICS.model_name, + rocm_version=_DEMO_METRICS.rocm_version, + power_watts=_DEMO_METRICS.power_watts, + ) + + try: + import httpx + + async with httpx.AsyncClient(timeout=5) as client: + base = vllm_base_url.rstrip("/v1").rstrip("/") + resp = await client.get(f"{base}/metrics") + resp.raise_for_status() + text = resp.text + + def parse_metric(name: str, default: float = 0.0) -> float: + for line in text.splitlines(): + if line.startswith(name) and not line.startswith("#"): + parts = line.split() + if len(parts) >= 2: + try: + return float(parts[1]) + except ValueError: + pass + return default + + return AMDPerformanceMetric( + timestamp=datetime.utcnow(), + gpu_utilization=parse_metric("vllm:gpu_cache_usage_perc") * 100, + memory_used_gb=parse_metric("vllm:gpu_memory_used_bytes") / (1024 ** 3), + memory_total_gb=192.0, + tokens_per_second=parse_metric("vllm:tokens_per_second"), + requests_processed=int(parse_metric("vllm:num_requests_running")), + avg_latency_ms=parse_metric("vllm:e2e_request_latency_seconds_sum") * 1000, + model_name="Qwen/Qwen2.5-72B-Instruct", + rocm_version=None, + power_watts=None, + ) + except Exception: + return AMDPerformanceMetric( + timestamp=datetime.utcnow(), + gpu_utilization=0.0, + memory_used_gb=0.0, + memory_total_gb=192.0, + tokens_per_second=0.0, + requests_processed=0, + avg_latency_ms=0.0, + model_name="unavailable", + rocm_version=None, + power_watts=None, + ) diff --git a/backend/skills/generate_dispatch_message.py b/backend/skills/generate_dispatch_message.py new file mode 100644 index 0000000000000000000000000000000000000000..ac2ff884760f0fc0be18fac3b36263c5caf4346a --- /dev/null +++ b/backend/skills/generate_dispatch_message.py @@ -0,0 +1,46 @@ +from __future__ import annotations +from typing import Any, List, Optional + +from schemas.dispatch import DispatchMessage +from schemas.incident import Incident, Priority +from schemas.resource import ResourceRecommendation + +_BRIGADE_MAP = { + Priority.P0: "Brigada Alfa — Rescate Crítico", + Priority.P1: "Brigada Beta — Respuesta Urgente", + Priority.P2: "Brigada Gamma — Apoyo Logístico", + Priority.P3: "Brigada Delta — Monitoreo", +} + + +async def generate_dispatch_message( + incident: Incident, + resources: List[ResourceRecommendation], + channel: str = "radio", + vllm_client: Any = None, +) -> DispatchMessage: + brigade = _BRIGADE_MAP.get(incident.priority, "Brigada General") + location_str = incident.location or "ubicación desconocida" + people_str = f" — {incident.affected_people} personas afectadas" if incident.affected_people else "" + + resource_lines = [] + for r in resources[:3]: + qty = f"{r.quantity}x " if r.quantity else "" + resource_lines.append(f"{qty}{r.description}") + resource_summary = ", ".join(resource_lines) if resource_lines else "evaluando recursos" + + message = ( + f"ALERTA {incident.priority.value} — {location_str.title()}: " + f"{incident.description[:120]}{people_str}. " + f"Recursos necesarios: {resource_summary}. " + f"Coordinar con: {brigade}. " + f"ID incidente: {incident.id[:8]}. CAMBIO." + ) + + return DispatchMessage( + incident_id=incident.id, + channel=channel, + message=message, + brigade_target=brigade, + approved=False, + ) diff --git a/backend/skills/normalize_signal.py b/backend/skills/normalize_signal.py new file mode 100644 index 0000000000000000000000000000000000000000..3f2f819bd4420be1e7f8732fe0312d9946b26356 --- /dev/null +++ b/backend/skills/normalize_signal.py @@ -0,0 +1,99 @@ +from __future__ import annotations +import json +import logging +import re +from datetime import datetime +from typing import Any, Dict, Optional + +logger = logging.getLogger(__name__) + +_SIGNAL_KEYWORDS: Dict[str, list] = { + "person_trapped": ["atrapado", "trapped", "encerrado", "no puede salir", "rescatar", "techo", "rooftop"], + "medical_emergency": ["herido", "injured", "médico", "medical", "paramédico", "ambulancia", "fractura", "inconsciente", "sangre"], + "structural_damage": ["derrumbe", "collapse", "pared", "wall", "edificio", "building", "escombros", "debris", "grieta"], + "flood": ["inundación", "flood", "agua", "water", "nivel", "sube", "corriente", "creciente"], + "missing_person": ["desaparecido", "missing", "no aparece", "perdido", "lost", "buscar", "paradero"], + "resource_request": ["necesitamos", "need", "falta", "sin", "without", "suministros", "supplies", "comida", "food", "agua"], + "safe_status": ["estamos bien", "safe", "a salvo", "sin heridos", "no hay heridos", "refugiados", "shelter"], + "fire": ["fuego", "fire", "incendio", "humo", "smoke", "llamas", "flames"], +} + + +def _infer_signal_type(text: str) -> str: + text_lower = text.lower() + scores: Dict[str, int] = {} + for stype, keywords in _SIGNAL_KEYWORDS.items(): + score = sum(1 for kw in keywords if kw in text_lower) + if score > 0: + scores[stype] = score + if not scores: + return "unknown" + return max(scores, key=lambda k: scores[k]) + + +def _extract_affected_people(text: str) -> Optional[int]: + patterns = [ + r"(\d+)\s*(?:personas|people|familias|families|vecinos|residents|niños|adults|adultos)", + r"(?:unas?|aproximadamente|about|around)\s+(\d+)", + r"(\d+)\s*(?:heridos|injured|atrapados|trapped)", + ] + for pattern in patterns: + match = re.search(pattern, text, re.IGNORECASE) + if match: + return int(match.group(1)) + return None + + +async def normalize_signal( + raw_text: str, + modality: str, + report_id: str, + vllm_client: Any = None, +) -> Dict[str, Any]: + from skills.extract_location import extract_location + + signal_type = _infer_signal_type(raw_text) + location_data = await extract_location(raw_text) + affected = _extract_affected_people(raw_text) + + confidence = 0.75 + if location_data["confidence"] > 0.8: + confidence += 0.05 + if signal_type != "unknown": + confidence += 0.05 + if affected is not None: + confidence += 0.05 + confidence = min(confidence, 1.0) + + if vllm_client is not None: + try: + prompt = ( + f"Extract structured disaster signal data from this report:\n\n\"{raw_text}\"\n\n" + f"Return JSON with keys: signal_type, description, location, affected_people (int or null), confidence (0-1).\n" + f"signal_type must be one of: structural_damage, person_trapped, medical_emergency, flood, fire, missing_person, resource_request, safe_status, unknown." + ) + result = await vllm_client.complete_json(prompt) + if result and "signal_type" in result: + signal_type = result.get("signal_type", signal_type) + confidence = float(result.get("confidence", confidence)) + if result.get("affected_people"): + affected = result["affected_people"] + if result.get("location") and not location_data["location_name"]: + location_data["location_name"] = result["location"] + except Exception as exc: + logger.warning("LLM normalization failed, using heuristics: %s", exc) + + description = raw_text[:200] if len(raw_text) > 200 else raw_text + + return { + "source_report_id": report_id, + "signal_type": signal_type, + "description": description, + "location": location_data.get("location_name"), + "coordinates": location_data.get("coordinates"), + "affected_people": affected, + "raw_text": raw_text, + "confidence": round(confidence, 3), + "modality": modality, + "created_at": datetime.utcnow().isoformat(), + } diff --git a/backend/skills/recommend_resources.py b/backend/skills/recommend_resources.py new file mode 100644 index 0000000000000000000000000000000000000000..a6093ea55d7a603fcc2cf213b1b308c693d461c4 --- /dev/null +++ b/backend/skills/recommend_resources.py @@ -0,0 +1,97 @@ +from __future__ import annotations +import uuid +from typing import Any, List + +from schemas.incident import Incident, Priority +from schemas.resource import ResourceRecommendation, ResourceType + +_RESOURCE_MAP = { + "person_trapped": [ + (ResourceType.RESCUE_TEAM, "Equipo de rescate urbano/acuático", 2, "immediate"), + (ResourceType.MEDICAL, "Paramédicos con equipo de trauma", 2, "immediate"), + (ResourceType.TRANSPORT, "Lancha de rescate o helicóptero", 1, "immediate"), + ], + "medical_emergency": [ + (ResourceType.MEDICAL, "Unidad médica de emergencia", 1, "immediate"), + (ResourceType.TRANSPORT, "Ambulancia o transporte médico", 1, "immediate"), + ], + "structural_damage": [ + (ResourceType.STRUCTURAL, "Equipo de evaluación estructural", 1, "within_hour"), + (ResourceType.RESCUE_TEAM, "Brigada de rescate entre escombros", 1, "within_hour"), + ], + "flood": [ + (ResourceType.RESCUE_TEAM, "Equipo de rescate acuático", 2, "immediate"), + (ResourceType.TRANSPORT, "Lanchas de evacuación", 3, "immediate"), + (ResourceType.WATER, "Agua potable embotellada", 200, "within_hour"), + (ResourceType.FOOD, "Raciones alimentarias de emergencia", 100, "within_hour"), + ], + "resource_request": [ + (ResourceType.FOOD, "Alimentos no perecederos", 50, "within_hour"), + (ResourceType.WATER, "Agua potable", 100, "within_hour"), + (ResourceType.SHELTER, "Kits de refugio temporal", 10, "within_day"), + ], + "missing_person": [ + (ResourceType.COMMUNICATION, "Equipo de comunicación y rastreo", 1, "within_hour"), + (ResourceType.RESCUE_TEAM, "Brigada de búsqueda y rescate", 1, "within_hour"), + ], + "fire": [ + (ResourceType.RESCUE_TEAM, "Cuerpo de bomberos", 2, "immediate"), + (ResourceType.MEDICAL, "Equipo médico para quemados", 1, "immediate"), + (ResourceType.WATER, "Agua para extinción", 1000, "immediate"), + ], + "safe_status": [ + (ResourceType.SHELTER, "Registro en refugio temporal", 1, "within_day"), + ], + "unknown": [ + (ResourceType.COMMUNICATION, "Equipo de evaluación inicial", 1, "within_hour"), + ], +} + + +async def recommend_resources( + incident: Incident, + vllm_client: Any = None, +) -> List[ResourceRecommendation]: + signal_type_str = "unknown" + if incident.signal_ids: + description_lower = incident.description.lower() + for stype in _RESOURCE_MAP: + if stype.replace("_", " ") in description_lower or stype in description_lower: + signal_type_str = stype + break + if signal_type_str == "unknown": + if "atrapado" in description_lower or "trapped" in description_lower: + signal_type_str = "person_trapped" + elif "médico" in description_lower or "medical" in description_lower or "herido" in description_lower: + signal_type_str = "medical_emergency" + elif "inundación" in description_lower or "flood" in description_lower or "agua" in description_lower: + signal_type_str = "flood" + elif "derrumbe" in description_lower or "collapse" in description_lower: + signal_type_str = "structural_damage" + elif "falta" in description_lower or "necesitamos" in description_lower or "supplies" in description_lower: + signal_type_str = "resource_request" + + templates = _RESOURCE_MAP.get(signal_type_str, _RESOURCE_MAP["unknown"]) + + if incident.priority == Priority.P0: + urgency_override = "immediate" + elif incident.priority == Priority.P1: + urgency_override = "immediate" + else: + urgency_override = None + + recommendations: List[ResourceRecommendation] = [] + for rtype, desc, qty, urgency in templates: + effective_urgency = urgency_override if urgency_override and urgency != "immediate" else urgency + recommendations.append( + ResourceRecommendation( + id=str(uuid.uuid4()), + incident_id=incident.id, + resource_type=rtype, + description=desc, + quantity=qty, + urgency=effective_urgency, + rationale=f"Requerido por incidente {incident.priority.value}: {incident.title[:60]}", + ) + ) + return recommendations diff --git a/backend/skills/transcribe_audio.py b/backend/skills/transcribe_audio.py new file mode 100644 index 0000000000000000000000000000000000000000..a040aaee081bac65335f01e2ece3bbe7c2402dc0 --- /dev/null +++ b/backend/skills/transcribe_audio.py @@ -0,0 +1,70 @@ +from __future__ import annotations +from typing import Any, Dict + +_DEMO_TRANSCRIPTIONS = [ + { + "transcription": "Aquí en la calle Bolívar con Sucre, el agua ya llegó al segundo piso. Hay una señora mayor que no puede caminar atrapada en el edificio amarillo, necesitamos ayuda urgente, por favor.", + "confidence": 0.94, + "duration_s": 18.2, + "language": "es", + }, + { + "transcription": "Somos diez familias en el techo de la escuela Simón Bolívar. Los niños están bien por ahora pero el agua sube. Necesitamos lanchas y comida. Llevamos cuatro horas aquí.", + "confidence": 0.91, + "duration_s": 22.7, + "language": "es", + }, + { + "transcription": "This is a rescue call from Santa Ana district. We have a man with a broken leg and possible spinal injury on the corner of Av. Principal and Calle 5. He cannot be moved without a stretcher. Medical team needed immediately.", + "confidence": 0.97, + "duration_s": 15.9, + "language": "en", + }, + { + "transcription": "El puente de la entrada del barrio colapsó. No pueden entrar camiones ni ambulancias por esa vía. Solo se puede acceder por la carretera vieja del norte, pero está muy deteriorada.", + "confidence": 0.89, + "duration_s": 19.4, + "language": "es", + }, + { + "transcription": "Reportando desde el centro comunitario. Aquí hay unas sesenta personas refugiadas pero ya se acabó el agua potable y los alimentos. Necesitamos suministros urgentes para los niños y adultos mayores.", + "confidence": 0.93, + "duration_s": 24.1, + "language": "es", + }, +] + + +async def transcribe_audio(file_path: str, demo_mode: bool = True) -> Dict[str, Any]: + if demo_mode: + idx = abs(hash(file_path)) % len(_DEMO_TRANSCRIPTIONS) + result = _DEMO_TRANSCRIPTIONS[idx].copy() + result["file_path"] = file_path + return result + + try: + import httpx + from core.config import get_settings + + settings = get_settings() + async with httpx.AsyncClient(timeout=60) as client: + resp = await client.post( + f"{settings.vllm_base_url}/audio/transcriptions", + headers={"Authorization": f"Bearer {settings.vllm_api_key}"}, + data={"model": "whisper-1"}, + files={"file": open(file_path, "rb")}, + ) + resp.raise_for_status() + data = resp.json() + return { + "transcription": data.get("text", ""), + "confidence": 0.9, + "duration_s": data.get("duration", 0.0), + "language": data.get("language", "unknown"), + "file_path": file_path, + } + except Exception: + idx = abs(hash(file_path)) % len(_DEMO_TRANSCRIPTIONS) + result = _DEMO_TRANSCRIPTIONS[idx].copy() + result["file_path"] = file_path + return result diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/backend/tests/__pycache__/__init__.cpython-312.pyc b/backend/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a98d37801686ca10eef8a5d8e383945d07ce4cd Binary files /dev/null and b/backend/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/backend/tests/__pycache__/test_api.cpython-312-pytest-9.0.3.pyc b/backend/tests/__pycache__/test_api.cpython-312-pytest-9.0.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf5414727f2b59b88a58d6b5071438b9ff247fd9 Binary files /dev/null and b/backend/tests/__pycache__/test_api.cpython-312-pytest-9.0.3.pyc differ diff --git a/backend/tests/__pycache__/test_schemas.cpython-312-pytest-9.0.3.pyc b/backend/tests/__pycache__/test_schemas.cpython-312-pytest-9.0.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2fafe6d22ec85387023eabedf104ac5a1d4d922 Binary files /dev/null and b/backend/tests/__pycache__/test_schemas.cpython-312-pytest-9.0.3.pyc differ diff --git a/backend/tests/__pycache__/test_skills.cpython-312-pytest-9.0.3.pyc b/backend/tests/__pycache__/test_skills.cpython-312-pytest-9.0.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2af559c941379516378323d64843465b3aa83fa4 Binary files /dev/null and b/backend/tests/__pycache__/test_skills.cpython-312-pytest-9.0.3.pyc differ diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py new file mode 100644 index 0000000000000000000000000000000000000000..53b0ea9e219bfaa637ce5b800af2d8ccef8e5f87 --- /dev/null +++ b/backend/tests/test_api.py @@ -0,0 +1,100 @@ +from __future__ import annotations +import pytest +from fastapi.testclient import TestClient + + +@pytest.fixture(scope="module") +def client(): + import sys + import os + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + from main import app + with TestClient(app) as c: + yield c + + +def test_root(client): + resp = client.get("/") + assert resp.status_code == 200 + data = resp.json() + assert data["name"] == "ReliefLensAI" + assert data["status"] == "ready" + + +def test_health(client): + resp = client.get("/health") + assert resp.status_code == 200 + data = resp.json() + assert data["status"] == "healthy" + + +def test_demo_scenario(client): + resp = client.get("/api/demo/scenario") + assert resp.status_code == 200 + data = resp.json() + assert "scenario_name" in data + assert "reports" in data + + +def test_demo_run(client): + resp = client.post("/api/demo/run") + assert resp.status_code == 200 + data = resp.json() + assert "session_id" in data + assert "total_incidents" in data + assert data["status"] == "ready" + + +def test_amd_performance(client): + resp = client.get("/api/amd/performance") + assert resp.status_code == 200 + data = resp.json() + assert "tokens_per_second" in data + assert data["tokens_per_second"] > 0 + + +def test_list_incidents_empty(client): + resp = client.get("/api/incidents") + assert resp.status_code == 200 + assert isinstance(resp.json(), list) + + +def test_get_incident_not_found(client): + resp = client.get("/api/incidents/nonexistent-id") + assert resp.status_code == 404 + + +def test_crisis_room_creation(client): + import uuid + from datetime import datetime + session_id = str(uuid.uuid4()) + payload = { + "batch": { + "session_id": session_id, + "scenario_name": "Test Flood", + "reports": [ + { + "id": str(uuid.uuid4()), + "session_id": session_id, + "report_type": "text", + "content": "Hay personas atrapadas en el techo de la escuela en Barrio Santa Ana, necesitamos rescate urgente", + "metadata": {}, + "created_at": datetime.utcnow().isoformat(), + }, + { + "id": str(uuid.uuid4()), + "session_id": session_id, + "report_type": "text", + "content": "Estamos bien en el centro comunitario, tenemos a 20 personas refugiadas pero falta agua", + "metadata": {}, + "created_at": datetime.utcnow().isoformat(), + }, + ], + } + } + resp = client.post("/api/crisis-room", json=payload) + assert resp.status_code == 200 + data = resp.json() + assert data["session_id"] == session_id + assert data["total_incidents"] > 0 + assert data["status"] == "ready" diff --git a/backend/tests/test_schemas.py b/backend/tests/test_schemas.py new file mode 100644 index 0000000000000000000000000000000000000000..d58a5d0943421c0c5c48040f725e4eb3318d09ad --- /dev/null +++ b/backend/tests/test_schemas.py @@ -0,0 +1,116 @@ +from __future__ import annotations +import pytest +from datetime import datetime + +from schemas.report import ReportInput, ReportType, UploadBatch +from schemas.signal import NormalizedSignal, SignalType +from schemas.incident import Incident, IncidentStatus, Priority, EvidenceItem +from schemas.resource import ResourceRecommendation, ResourceType +from schemas.dispatch import DispatchMessage +from schemas.amd import AMDPerformanceMetric +from schemas.crisis_room import CrisisRoomSummary + + +def test_report_input_defaults(): + r = ReportInput(session_id="s1", report_type=ReportType.TEXT, content="Hello") + assert r.id + assert r.report_type == ReportType.TEXT + assert r.metadata == {} + + +def test_upload_batch(): + r = ReportInput(session_id="s1", report_type=ReportType.TEXT, content="Test") + batch = UploadBatch(reports=[r]) + assert len(batch.reports) == 1 + + +def test_normalized_signal(): + sig = NormalizedSignal( + source_report_id="r1", + signal_type=SignalType.FLOOD, + description="Flooding in sector 4", + raw_text="Water is rising", + confidence=0.85, + modality="text", + created_at=datetime.utcnow(), + ) + assert sig.id + assert sig.signal_type == SignalType.FLOOD + + +def test_incident(): + inc = Incident( + session_id="s1", + title="Flood incident", + description="Major flood", + priority=Priority.P0, + confidence=0.9, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ) + assert inc.status == IncidentStatus.NEW + assert not inc.human_approved + + +def test_resource_recommendation(): + rec = ResourceRecommendation( + incident_id="i1", + resource_type=ResourceType.RESCUE_TEAM, + description="Rescue team needed", + urgency="immediate", + rationale="People trapped", + ) + assert rec.id + + +def test_dispatch_message(): + msg = DispatchMessage( + incident_id="i1", + channel="radio", + message="ALERTA P0 - Santa Ana: personas atrapadas", + ) + assert not msg.approved + + +def test_amd_metrics(): + m = AMDPerformanceMetric( + timestamp=datetime.utcnow(), + gpu_utilization=87.4, + memory_used_gb=182.3, + memory_total_gb=192.0, + tokens_per_second=2340.5, + requests_processed=128, + avg_latency_ms=312.7, + model_name="Qwen/Qwen2.5-72B-Instruct", + rocm_version="6.1.0", + power_watts=680.2, + ) + assert m.gpu_utilization == 87.4 + + +def test_crisis_room_summary(): + now = datetime.utcnow() + inc = Incident( + session_id="s1", + title="Test", + description="desc", + priority=Priority.P0, + confidence=0.9, + created_at=now, + updated_at=now, + ) + summary = CrisisRoomSummary( + session_id="s1", + scenario_name="Test Flood", + total_reports=5, + total_signals=4, + total_incidents=2, + incidents_by_priority={"P0": 1, "P1": 1, "P2": 0, "P3": 0}, + critical_incidents=[inc], + resource_recommendations=[], + dispatch_messages=[], + processing_time_seconds=1.23, + created_at=now, + status="ready", + ) + assert summary.total_reports == 5 diff --git a/backend/tests/test_skills.py b/backend/tests/test_skills.py new file mode 100644 index 0000000000000000000000000000000000000000..c75896f0f21169f34a41be5f6a647b6d5b43985c --- /dev/null +++ b/backend/tests/test_skills.py @@ -0,0 +1,228 @@ +from __future__ import annotations +import pytest +import pytest_asyncio +from datetime import datetime + +from schemas.signal import NormalizedSignal, SignalType + + +@pytest.mark.asyncio +async def test_transcribe_audio_demo(): + from skills.transcribe_audio import transcribe_audio + result = await transcribe_audio("audio_001.mp3", demo_mode=True) + assert "transcription" in result + assert len(result["transcription"]) > 10 + assert 0 <= result["confidence"] <= 1 + + +@pytest.mark.asyncio +async def test_caption_image_demo(): + from skills.caption_image import caption_image + result = await caption_image("image_001.jpg", demo_mode=True) + assert "caption" in result + assert len(result["caption"]) > 10 + assert "objects_detected" in result + + +@pytest.mark.asyncio +async def test_extract_location_known(): + from skills.extract_location import extract_location + result = await extract_location("Hay inundación en Barrio Santa Ana") + assert result["location_name"] is not None + assert result["confidence"] > 0.5 + + +@pytest.mark.asyncio +async def test_extract_location_unknown(): + from skills.extract_location import extract_location + result = await extract_location("No location mentioned here xyz abc") + assert result["confidence"] >= 0 + + +@pytest.mark.asyncio +async def test_normalize_signal_demo(): + from skills.normalize_signal import normalize_signal + result = await normalize_signal( + raw_text="Hay personas atrapadas en Barrio Santa Ana, al menos 5 heridos", + modality="text", + report_id="r_test_001", + vllm_client=None, + ) + assert "signal_type" in result + assert "confidence" in result + assert result["source_report_id"] == "r_test_001" + + +@pytest.mark.asyncio +async def test_detect_duplicates(): + from skills.detect_duplicates import detect_duplicates + now = datetime.utcnow() + signals = [ + NormalizedSignal( + source_report_id="r1", + signal_type=SignalType.FLOOD, + description="Flooding in Santa Ana", + raw_text="Flooding in Santa Ana barrio water rising fast", + confidence=0.9, + modality="text", + created_at=now, + ), + NormalizedSignal( + source_report_id="r2", + signal_type=SignalType.FLOOD, + description="Flooding in Santa Ana", + raw_text="Flooding in Santa Ana barrio water rising fast", + confidence=0.85, + modality="text", + created_at=now, + ), + NormalizedSignal( + source_report_id="r3", + signal_type=SignalType.PERSON_TRAPPED, + description="Person trapped on roof", + raw_text="There is a person trapped on the roof of the school building", + confidence=0.92, + modality="text", + created_at=now, + ), + ] + unique = await detect_duplicates(signals, threshold=0.75) + assert len(unique) == 2 + + +@pytest.mark.asyncio +async def test_classify_priority_person_trapped(): + from skills.classify_priority import classify_priority + from schemas.incident import Priority + now = datetime.utcnow() + signal = NormalizedSignal( + source_report_id="r1", + signal_type=SignalType.PERSON_TRAPPED, + description="Person trapped", + raw_text="Hay una persona atrapada en el edificio, no puede salir", + confidence=0.9, + modality="text", + created_at=now, + ) + priority = await classify_priority(signal) + assert priority == Priority.P0 + + +@pytest.mark.asyncio +async def test_classify_priority_safe_status(): + from skills.classify_priority import classify_priority + from schemas.incident import Priority + now = datetime.utcnow() + signal = NormalizedSignal( + source_report_id="r1", + signal_type=SignalType.SAFE_STATUS, + description="We are safe", + raw_text="Estamos bien, a salvo en el centro comunitario sin heridos", + confidence=0.8, + modality="text", + created_at=now, + ) + priority = await classify_priority(signal) + assert priority == Priority.P3 + + +@pytest.mark.asyncio +async def test_recommend_resources(): + from skills.recommend_resources import recommend_resources + from schemas.incident import Incident, Priority + now = datetime.utcnow() + incident = Incident( + session_id="s1", + title="Flood — Santa Ana", + description="inundación severa, personas atrapadas, agua subiendo", + priority=Priority.P0, + confidence=0.9, + signal_ids=["sig1"], + created_at=now, + updated_at=now, + ) + recs = await recommend_resources(incident) + assert len(recs) > 0 + assert any(r.urgency == "immediate" for r in recs) + + +@pytest.mark.asyncio +async def test_generate_dispatch_message(): + from skills.generate_dispatch_message import generate_dispatch_message + from schemas.incident import Incident, Priority + from schemas.resource import ResourceRecommendation, ResourceType + now = datetime.utcnow() + incident = Incident( + session_id="s1", + title="Persona atrapada — Santa Ana", + description="Persona atrapada en techo, agua subiendo", + priority=Priority.P0, + location="Barrio Santa Ana", + confidence=0.95, + affected_people=3, + signal_ids=["sig1"], + created_at=now, + updated_at=now, + ) + resources = [ + ResourceRecommendation( + incident_id=incident.id, + resource_type=ResourceType.RESCUE_TEAM, + description="Equipo rescate acuático", + quantity=2, + urgency="immediate", + rationale="Personas atrapadas", + ) + ] + msg = await generate_dispatch_message(incident, resources) + assert "ALERTA" in msg.message + assert "P0" in msg.message + assert "Santa Ana" in msg.message + + +@pytest.mark.asyncio +async def test_calculate_confidence(): + from skills.calculate_confidence import calculate_confidence + now = datetime.utcnow() + signals = [ + NormalizedSignal(source_report_id="r1", signal_type=SignalType.FLOOD, description="d", raw_text="t", confidence=0.9, modality="text", created_at=now), + NormalizedSignal(source_report_id="r2", signal_type=SignalType.FLOOD, description="d", raw_text="t", confidence=0.8, modality="image", created_at=now), + ] + conf = await calculate_confidence(signals) + assert 0.0 <= conf <= 1.0 + + +@pytest.mark.asyncio +async def test_fetch_amd_metrics_demo(): + from skills.fetch_amd_metrics import fetch_amd_metrics + metrics = await fetch_amd_metrics("http://localhost:8000/v1", demo_mode=True) + assert metrics.tokens_per_second > 0 + assert metrics.gpu_utilization > 0 + + +@pytest.mark.asyncio +async def test_export_incident_report_json(): + from skills.export_incident_report import export_incident_report + from schemas.incident import Incident, Priority + import json + now = datetime.utcnow() + incidents = [ + Incident(session_id="s1", title="Test", description="desc", priority=Priority.P1, confidence=0.8, created_at=now, updated_at=now) + ] + output = await export_incident_report(incidents, format="json") + data = json.loads(output) + assert len(data) == 1 + assert data[0]["priority"] == "P1" + + +@pytest.mark.asyncio +async def test_export_incident_report_csv(): + from skills.export_incident_report import export_incident_report + from schemas.incident import Incident, Priority + now = datetime.utcnow() + incidents = [ + Incident(session_id="s1", title="CSV Test", description="desc", priority=Priority.P2, confidence=0.7, created_at=now, updated_at=now) + ] + output = await export_incident_report(incidents, format="csv") + assert "CSV Test" in output + assert "P2" in output diff --git a/demo_data/scenario_flood_santa_ana.json b/demo_data/scenario_flood_santa_ana.json new file mode 100644 index 0000000000000000000000000000000000000000..a7b2d62fc707e87e22c2f03d06d135f8fcbf0c95 --- /dev/null +++ b/demo_data/scenario_flood_santa_ana.json @@ -0,0 +1,202 @@ +{ + "scenario_name": "Inundación Barrio Santa Ana", + "description": "Simulacro de respuesta a inundación severa en el Barrio Santa Ana. El río Tuy desbordó sus márgenes debido a lluvias torrenciales de 48 horas. Aproximadamente 450 familias afectadas.", + "location": { + "name": "Barrio Santa Ana", + "city": "Caracas", + "country": "Venezuela", + "coordinates": {"lat": 10.4806, "lon": -66.9036} + }, + "event_time": "2024-01-15T12:00:00Z", + "reports": [ + { + "id": "rpt_001", + "report_type": "text", + "content": "URGENTE: Familia atrapada en techo de casa calle Bolívar #45. Abuela de 78 años con diabetes no puede moverse. Agua llegó al segundo piso. Necesitamos lancha y paramédicos YA!!", + "metadata": {"source": "whatsapp", "timestamp": "2024-01-15T14:23:00Z", "sender": "vecino_001", "priority_hint": "P0"} + }, + { + "id": "rpt_002", + "report_type": "text", + "content": "Soy profesora de la Escuela Simón Bolívar. Tenemos 87 niños y 12 adultos refugiados en el segundo piso. El primer piso está completamente inundado. Ya no tenemos comida ni agua potable. El agua sigue subiendo. Por favor envíen ayuda.", + "metadata": {"source": "sms", "timestamp": "2024-01-15T14:31:00Z", "sender": "docente_sboli", "priority_hint": "P1"} + }, + { + "id": "rpt_003", + "report_type": "text", + "content": "CRÍTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferretería Los Andes. Parece tener herida en la cabeza. Está respirando pero no responde. Necesitamos ambulancia de emergencia inmediatamente.", + "metadata": {"source": "llamada_radio", "timestamp": "2024-01-15T14:38:00Z", "sender": "patrulla_07", "priority_hint": "P0"} + }, + { + "id": "rpt_004", + "report_type": "text", + "content": "El puente peatonal de la entrada norte al barrio colapsó hace 20 minutos. El único acceso vehicular ahora es por la carretera vieja del norte pero tiene muchos baches y barro. Ambulancias y camiones pesados no pueden pasar. Sugiero coordinar por vía aérea o lancha.", + "metadata": {"source": "radio_brigada", "timestamp": "2024-01-15T14:45:00Z", "sender": "lider_brigada_norte", "priority_hint": "P1"} + }, + { + "id": "rpt_005", + "report_type": "text", + "content": "Reportando desde el Centro Comunitario Bolivariano. Tenemos 62 personas evacuadas incluyendo 23 niños menores de 10 años y 8 adultos mayores. Ya se agotó completamente el agua potable. Los alimentos alcanzan para 6 horas más. Solicitamos suministros de emergencia urgentes.", + "metadata": {"source": "whatsapp", "timestamp": "2024-01-15T14:52:00Z", "sender": "coordinador_cc", "priority_hint": "P2"} + }, + { + "id": "rpt_006", + "report_type": "text", + "content": "Three people stranded on roof at corner of Calle 5 and Av. Principal. We have been here for 6 hours. One elderly woman has heart condition and needs medication. Water level is about 1.8 meters and still rising slowly. Please send boat rescue.", + "metadata": {"source": "whatsapp", "timestamp": "2024-01-15T15:02:00Z", "sender": "resident_eng_001", "priority_hint": "P0"} + }, + { + "id": "rpt_007", + "report_type": "text", + "content": "La subestación eléctrica de la calle Sucre está completamente inundada. Cables de alta tensión en contacto con el agua. Hay riesgo grave de electrocución en toda la zona norte del barrio. Urge corte de energía inmediato y señalización del área.", + "metadata": {"source": "radio_defensa_civil", "timestamp": "2024-01-15T15:09:00Z", "sender": "bombero_carlos", "priority_hint": "P1"} + }, + { + "id": "rpt_008", + "report_type": "text", + "content": "Sector Las Palmas: derrumbe parcial del edificio de apartamentos El Mirador. Una pared lateral colapsó. Hay 4 apartamentos comprometidos. Escuchamos voces pidiendo ayuda desde el segundo piso. Se necesita equipo de rescate especializado y evaluación estructural urgente.", + "metadata": {"source": "telegram", "timestamp": "2024-01-15T15:17:00Z", "sender": "vecino_laspalmas", "priority_hint": "P1"} + }, + { + "id": "rpt_009", + "report_type": "text", + "content": "Tenemos 15 familias en el techo del Mercado Municipal Santa Ana. Somos aproximadamente 45 personas. Hay una señora embarazada de 8 meses con contracciones. Necesitamos evacuación médica urgente para ella primero. Los demás podemos esperar un poco más.", + "metadata": {"source": "whatsapp", "timestamp": "2024-01-15T15:24:00Z", "sender": "familia_mercado", "priority_hint": "P0"} + }, + { + "id": "rpt_010", + "report_type": "text", + "content": "Desaparecido: niño de 7 años, Andrés Rodríguez, con camiseta roja y pantalón azul. Fue visto por última vez en el parque principal a las 12:30pm. Su familia está desesperada. Si alguien lo ve por favor contactar al número 0412-5678901.", + "metadata": {"source": "whatsapp_grupo", "timestamp": "2024-01-15T15:31:00Z", "sender": "mama_andres", "priority_hint": "P1"} + }, + { + "id": "rpt_011", + "report_type": "text", + "content": "Desde el sector El Progreso informamos que el nivel del agua comenzó a bajar levemente en las últimas 2 horas. Tenemos a 28 personas en el refugio de la iglesia Nuestra Señora. Todos están bien, sin heridos. Tenemos suficiente comida por ahora pero necesitaremos agua potable mañana.", + "metadata": {"source": "radio_comunal", "timestamp": "2024-01-15T15:38:00Z", "sender": "padre_iglesia", "priority_hint": "P3"} + }, + { + "id": "rpt_012", + "report_type": "text", + "content": "La farmacia Santa Ana tiene medicamentos flotando por el agua. Se perdieron insulinas y medicamentos de cadena de frío. Hay al menos 15 pacientes del barrio que necesitan insulina diariamente incluyendo la señora del techo de la calle Bolívar. Solicitar provisión de medicamentos de emergencia.", + "metadata": {"source": "telegram", "timestamp": "2024-01-15T15:45:00Z", "sender": "farmacia_santaana", "priority_hint": "P2"} + }, + { + "id": "rpt_013", + "report_type": "text", + "content": "URGENTE: Familia atrapada en techo de casa calle Bolívar #45. Abuela de 78 años con diabetes no puede moverse. Agua llegó al segundo piso. Necesitamos lancha y paramédicos YA!!", + "metadata": {"source": "facebook", "timestamp": "2024-01-15T15:52:00Z", "sender": "vecino_002", "priority_hint": "P0", "note": "duplicate_of_rpt_001"} + }, + { + "id": "rpt_014", + "report_type": "text", + "content": "CRÍTICO: Hombre inconsciente encontrado flotando en Av. Principal cerca de la ferretería Los Andes. Parece tener herida en la cabeza. Está respirando pero no responde. Necesitamos ambulancia de emergencia inmediatamente.", + "metadata": {"source": "instagram", "timestamp": "2024-01-15T15:58:00Z", "sender": "testigo_anonimo", "priority_hint": "P0", "note": "duplicate_of_rpt_003"} + }, + { + "id": "rpt_015", + "report_type": "text", + "content": "Situación estable en el refugio del Liceo Andrés Bello. 34 personas alojadas, 12 son adultos mayores. Tenemos agua y comida para el día de hoy. Sin heridos ni emergencias médicas activas. Necesitaremos colchonetas y frazadas para esta noche ya que bajan las temperaturas.", + "metadata": {"source": "radio_defensa_civil", "timestamp": "2024-01-15T16:05:00Z", "sender": "coord_liceo", "priority_hint": "P3"} + }, + { + "id": "rpt_016", + "report_type": "audio", + "content": "audio_rpt_016_calle_bolivar.mp3", + "metadata": {"source": "llamada_emergencia", "timestamp": "2024-01-15T14:25:00Z", "duration_seconds": 18, "transcription_hint": "persona_atrapada_calle_bolivar"} + }, + { + "id": "rpt_017", + "report_type": "audio", + "content": "audio_rpt_017_escuela.mp3", + "metadata": {"source": "llamada_emergencia", "timestamp": "2024-01-15T14:35:00Z", "duration_seconds": 23, "transcription_hint": "ninos_escuela_simon_bolivar"} + }, + { + "id": "rpt_018", + "report_type": "audio", + "content": "audio_rpt_018_puente.mp3", + "metadata": {"source": "radio_brigada", "timestamp": "2024-01-15T14:48:00Z", "duration_seconds": 19, "transcription_hint": "puente_colapsado_acceso"} + }, + { + "id": "rpt_019", + "report_type": "audio", + "content": "audio_rpt_019_centro_comunitario.mp3", + "metadata": {"source": "llamada_emergencia", "timestamp": "2024-01-15T14:55:00Z", "duration_seconds": 24, "transcription_hint": "centro_comunitario_suministros"} + }, + { + "id": "rpt_020", + "report_type": "audio", + "content": "audio_rpt_020_mercado.mp3", + "metadata": {"source": "llamada_emergencia", "timestamp": "2024-01-15T15:27:00Z", "duration_seconds": 16, "transcription_hint": "mercado_embarazada_evacuacion"} + }, + { + "id": "rpt_021", + "report_type": "image", + "content": "img_rpt_021_vista_aerea_santaana.jpg", + "metadata": {"source": "dron_defensa_civil", "timestamp": "2024-01-15T14:20:00Z", "resolution": "4K", "description_hint": "aerial_flood_overview"} + }, + { + "id": "rpt_022", + "report_type": "image", + "content": "img_rpt_022_calle_bolivar_techo.jpg", + "metadata": {"source": "whatsapp", "timestamp": "2024-01-15T14:24:00Z", "description_hint": "family_on_roof_bolivar"} + }, + { + "id": "rpt_023", + "report_type": "image", + "content": "img_rpt_023_escuela_inundada.jpg", + "metadata": {"source": "docente_sboli", "timestamp": "2024-01-15T14:33:00Z", "description_hint": "school_shelter_crowded"} + }, + { + "id": "rpt_024", + "report_type": "image", + "content": "img_rpt_024_derrumbe_mirador.jpg", + "metadata": {"source": "vecino_laspalmas", "timestamp": "2024-01-15T15:18:00Z", "description_hint": "building_collapse_debris"} + }, + { + "id": "rpt_025", + "report_type": "image", + "content": "img_rpt_025_subestacion_electrica.jpg", + "metadata": {"source": "bombero_carlos", "timestamp": "2024-01-15T15:10:00Z", "description_hint": "flooded_electrical_substation"} + }, + { + "id": "rpt_026", + "report_type": "image", + "content": "img_rpt_026_ambulancia_atascada.jpg", + "metadata": {"source": "patrulla_07", "timestamp": "2024-01-15T14:40:00Z", "description_hint": "ambulance_blocked_flood"} + }, + { + "id": "rpt_027", + "report_type": "image", + "content": "img_rpt_027_balsa_improvisada.jpg", + "metadata": {"source": "vecino_003", "timestamp": "2024-01-15T15:35:00Z", "description_hint": "makeshift_raft_rescue"} + }, + { + "id": "rpt_028", + "report_type": "image", + "content": "img_rpt_028_nino_solo_escuela.jpg", + "metadata": {"source": "dron_defensa_civil", "timestamp": "2024-01-15T15:55:00Z", "description_hint": "child_alone_fence_school"} + }, + { + "id": "rpt_029", + "report_type": "csv", + "content": "lat,lon,location_name,status,persons_count,priority\n10.4812,-66.9041,Calle Bolivar 45,atrapados,4,P0\n10.4820,-66.9050,Escuela Simon Bolivar,refugio,99,P1\n10.4795,-66.9028,Av Principal ferreteria,emergencia_medica,1,P0\n10.4808,-66.9033,Centro Comunitario,refugio,62,P2\n10.4801,-66.9043,Calle 5 esquina Av Principal,atrapados,3,P0\n10.4818,-66.9055,Mercado Municipal,atrapados,45,P0\n10.4800,-66.9030,Edificio El Mirador,derrumbe,8,P1\n10.4790,-66.9020,Puente norte,colapsado,0,P1\n10.4815,-66.9048,Subestacion electrica Sucre,peligro_electrico,0,P1\n10.4825,-66.9060,Liceo Andres Bello,refugio_estable,34,P3\n10.4797,-66.9038,Iglesia Nuestra Senora,refugio_estable,28,P3", + "metadata": {"source": "sistema_gis_defensa_civil", "timestamp": "2024-01-15T15:00:00Z", "format": "csv_locations"} + } + ], + "expected_outcomes": { + "total_reports": 29, + "expected_p0_incidents": 4, + "expected_p1_incidents": 5, + "expected_p2_incidents": 3, + "expected_p3_incidents": 2, + "duplicates_to_detect": ["rpt_013 duplicates rpt_001", "rpt_014 duplicates rpt_003"], + "key_locations": [ + "Calle Bolivar #45 — familia atrapada, abuela diabetica", + "Escuela Simon Bolivar — 87 ninos refugiados", + "Av. Principal — emergencia medica hombre inconsciente", + "Centro Comunitario — 62 evacuados sin agua", + "Mercado Municipal — embarazada con contracciones" + ] + } +} diff --git a/scripts/run_backend.sh b/scripts/run_backend.sh new file mode 100755 index 0000000000000000000000000000000000000000..f06987d5b7eee96316467ddff7e4fd76438e9f97 --- /dev/null +++ b/scripts/run_backend.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd "$(dirname "$0")/../backend" +source venv/bin/activate +uvicorn main:app --host 0.0.0.0 --port 8080 --reload diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000000000000000000000000000000000000..af37eb44b8c0542afaeccaf4cf007a080cd3565a --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +echo "Setting up ReliefLensAI backend..." +cd "$(dirname "$0")/../backend" +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +cp .env.example .env +mkdir -p data +echo "Backend setup complete!"