Files
hackathon-acapulquitos-boys…/server/schema_supabase.sql

128 lines
5.1 KiB
SQL

-- ── Esquema Supabase PostgreSQL (migrado de SQLite) ──────────────
-- Tabla users (Persona A)
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
phone TEXT,
password_hash TEXT NOT NULL,
fcm_token TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Tabla addresses (Persona A)
CREATE TABLE IF NOT EXISTS addresses (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
alias TEXT,
lat DOUBLE PRECISION NOT NULL,
lng DOUBLE PRECISION NOT NULL,
route_id TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Tabla notification_preferences (Persona A)
CREATE TABLE IF NOT EXISTS notification_preferences (
user_id BIGINT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
notify_proximity BOOLEAN DEFAULT TRUE,
notify_breakdown BOOLEAN DEFAULT TRUE,
notify_delay BOOLEAN DEFAULT TRUE,
notify_route_start BOOLEAN DEFAULT TRUE
);
-- Tabla notification_templates (Persona A)
CREATE TABLE IF NOT EXISTS notification_templates (
id BIGSERIAL PRIMARY KEY,
trigger_event TEXT UNIQUE,
title TEXT,
body TEXT
);
-- ── Tablas del módulo B ───────────────────────────────────────
-- Tabla truck_status
CREATE TABLE IF NOT EXISTS truck_status (
route_id TEXT PRIMARY KEY,
current_position_id INTEGER DEFAULT 1,
last_update TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
status TEXT DEFAULT 'EN_RUTA'
);
-- Tabla rutas
CREATE TABLE IF NOT EXISTS rutas (
id TEXT PRIMARY KEY,
nombre TEXT NOT NULL,
turno TEXT NOT NULL DEFAULT 'mañana'
);
-- Tabla puntos_ruta
CREATE TABLE IF NOT EXISTS puntos_ruta (
id BIGSERIAL PRIMARY KEY,
ruta_id TEXT NOT NULL REFERENCES rutas(id),
orden INTEGER NOT NULL,
nombre TEXT NOT NULL,
lat DOUBLE PRECISION NOT NULL,
lng DOUBLE PRECISION NOT NULL,
tiempo_estimado_min INTEGER NOT NULL
);
-- Tabla notificaciones
CREATE TABLE IF NOT EXISTS notificaciones (
id BIGSERIAL PRIMARY KEY,
tipo TEXT NOT NULL,
ruta_id TEXT NOT NULL,
address_id BIGINT,
mensaje TEXT NOT NULL,
eta_minutos INTEGER,
creada_en TEXT NOT NULL
);
-- ── Índices para performance ──────────────────────────────────
CREATE INDEX IF NOT EXISTS idx_addresses_user_id ON addresses(user_id);
CREATE INDEX IF NOT EXISTS idx_addresses_route_id ON addresses(route_id);
CREATE INDEX IF NOT EXISTS idx_puntos_ruta_ruta_id ON puntos_ruta(ruta_id);
CREATE INDEX IF NOT EXISTS idx_notificaciones_ruta_id ON notificaciones(ruta_id);
-- ── RLS (Row Level Security) ──────────────────────────────────
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE addresses ENABLE ROW LEVEL SECURITY;
ALTER TABLE notification_preferences ENABLE ROW LEVEL SECURITY;
ALTER TABLE notificaciones ENABLE ROW LEVEL SECURITY;
-- Policy: users solo ven su propio perfil
CREATE POLICY "Users can view own profile" ON users
FOR SELECT USING (auth.uid()::TEXT = id::TEXT);
-- Policy: addresses solo de usuario autenticado
CREATE POLICY "Users can view own addresses" ON addresses
FOR SELECT USING (user_id = auth.uid()::BIGINT);
-- Policy: notification_preferences solo de usuario autenticado
CREATE POLICY "Users can view own preferences" ON notification_preferences
FOR SELECT USING (user_id = auth.uid()::BIGINT);
-- ── Seed data ──────────────────────────────────────────────────
INSERT INTO rutas (id, nombre, turno) VALUES
('RUTA-01', 'Ruta 01 — Sector Centro', 'mañana')
ON CONFLICT (id) DO NOTHING;
INSERT INTO puntos_ruta (ruta_id, orden, nombre, lat, lng, tiempo_estimado_min) VALUES
('RUTA-01', 1, 'Estación Central', 20.5238, -100.8143, 0),
('RUTA-01', 2, 'Col. Independencia', 20.5255, -100.8090, 8),
('RUTA-01', 3, 'Blvd. A. López Mateos', 20.5271, -100.8021, 18),
('RUTA-01', 4, 'Col. Jardines del Bosque', 20.5290, -100.7965, 28),
('RUTA-01', 5, 'Mercado Hidalgo', 20.5310, -100.7910, 38)
ON CONFLICT DO NOTHING;
INSERT INTO truck_status (route_id, current_position_id, status) VALUES
('RUTA-01', 1, 'EN_RUTA')
ON CONFLICT (route_id) DO NOTHING;
INSERT INTO notification_templates (trigger_event, title, body) VALUES
('ruta_iniciada', 'Ruta iniciada', 'El camión ha comenzado su ruta. Prepárate.'),
('aproximandose', '¡Camión cerca!', 'El camión llega en ~{eta} minutos. Saca tu basura.'),
('falla_mecanica', 'Aviso de servicio', 'El camión reportó una falla. Te notificaremos cuando se reanude.'),
('ruta_tarde', 'Cambio de horario', 'El camión de la mañana pasará en el turno de la tarde.'),
('completado', 'Ruta completada', 'El camión completó su paso por tu zona. ¡Hasta mañana!')
ON CONFLICT (trigger_event) DO NOTHING;