SIVIV

Documentación del proyecto

📋 Buscador original
🇻🇪

Sistema de Información de Víctimas

Proyecto de emergencia — Terremoto en Venezuela, junio 2025

Estado: Proyecto archivado. La API se mantiene activa. El buscador público está disponible en /archive.

📖 Contexto

SIVIV nació como respuesta inmediata al terremoto que afectó Venezuela en junio de 2025. Su objetivo era centralizar la información de personas ingresadas en hospitales y centros de atención, permitiendo a familiares buscar a sus seres queridos por nombre, apellido o cédula.

La aplicación se diseñó con tres principios:

Durante su operación, SIVIV procesó más de 500 registros de pacientes distribuidos en múltiples centros de atención en el estado Anzoátegui y zonas aledañas.

🏗️ Arquitectura

Usuario → Cloudflare Pages → Pages Function (proxy) → Supabase (PostgreSQL + RLS)
Capa Tecnología Rol
Frontend Vue 3 + Tailwind CSS (CDN) Buscador público + Panel admin
Proxy / API Cloudflare Pages Function Cache (60s), rate limit (30 req/min), auth admin
Base de datos Supabase (PostgreSQL) Registros + búsqueda full-text (pg_trgm)
Hosting Cloudflare Pages Edge deployment global, SSL, CDN

🔌 API

La API es un proxy sobre Supabase REST, alojado como Cloudflare Pages Function. Se mantiene activa como legado del proyecto.

Base URL

https://siviv.pages.dev/api

Endpoints

La API expone la tabla pacientes de Supabase vía REST:

Método Ruta Descripción Auth
GET /rest/v1/pacientes Listar/buscar pacientes Público
POST /rest/v1/pacientes Insertar paciente Admin Key
DELETE /rest/v1/pacientes?id=eq.X Eliminar paciente Admin Key

Parámetros de búsqueda (GET)

La API acepta todos los operadores de Supabase REST:

GET /api/rest/v1/pacientes?select=nombre,apellido,centro&nombre=ilike.%maria%&limit=10
Parámetro Ejemplo Descripción
selectnombre,apellido,edadColumnas a retornar
nombreilike.%maria%Filtro case-insensitive
or(nombre.ilike.%X%,apellido.ilike.%X%)OR lógico entre condiciones
ordercreated_at.descOrdenamiento
limit50Máx resultados (default 50)

Autenticación (POST / DELETE)

fetch('https://siviv.pages.dev/api/rest/v1/pacientes', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-admin-key': '<ADMIN_KEY>'
  },
  body: JSON.stringify({
    nombre: 'María',
    apellido: 'González',
    edad: 34,
    centro: 'Hospital Central'
  })
})

Cabeceras de respuesta

Header Valor Significado
x-siviv-cacheHIT / MISSCache de 60s en el edge
cache-controlpublic, max-age=60Caché en CDN

🗄️ Esquema de datos

CREATE TABLE public.pacientes (
  id         BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  nombre     TEXT NOT NULL,
  apellido   TEXT NOT NULL,
  edad       INTEGER,
  cedula     TEXT,
  centro     TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Índices para búsqueda rápida
CREATE INDEX idx_pacientes_nombre_trgm   ON pacientes USING GIN (nombre gin_trgm_ops);
CREATE INDEX idx_pacientes_apellido_trgm ON pacientes USING GIN (apellido gin_trgm_ops);
CREATE INDEX idx_pacientes_cedula        ON pacientes (cedula);

-- Seguridad: Row Level Security
ALTER TABLE pacientes ENABLE ROW LEVEL SECURITY;
CREATE POLICY "lectura_publica"  ON pacientes FOR SELECT USING (true);
CREATE POLICY "registro_publico" ON pacientes FOR INSERT WITH CHECK (true);
CREATE POLICY "admin_delete"     ON pacientes FOR DELETE USING (true);

⚠️ Limitaciones

📦 Repositorio

Código fuente disponible en GitHub:

Toyoenohio/SIVIV