¿Necesitas ayuda? Escriba su cadena de búsqueda. Se requiere un mínimo de 4 caracteres.

Abrir lista de categorías

Descripcion General de la Base de Datos del Modulo de Usuarios

Nivel: N4 – CCO / Desarrollo
Esquema completo de la base de datos del Nucleo 1: Usuarios y Perfiles en Supabase (PostgreSQL). Define tablas, columnas, relaciones, RLS y triggers. Este documento es el plano de construccion para el desarrollador.

Referencia normativa: Instructivo Maestro de Usuarios (el QUE) | Stack Tecnologico (el CON QUE) | Arquitectura Global de Datos (el DONDE)


1. Vision general del Nucleo 1

El Nucleo 1 es el centro de todo el ERP. La tabla public.profiles es la Celula Madre: todas las demas tablas de todos los nucleos la referencian. Sin usuario, no hay pedido, no hay cuota, no hay expediente.

                          ┌───────────────────┐
                          │  auth.users        │  ← Supabase Auth (login/password)
                          │  (gestionado por   │
                          │   Supabase)        │
                          └─────────┬─────────┘
                                    │ auth.uid()
                          ┌─────────▼─────────┐
                          │  public.profiles   │  ← CELULA MADRE (nosotros)
                          │  (datos del usuario)│
                          └─────────┬─────────┘
                                    │ profile_id (FK)
          ┌──────────┬──────────┬───┴───┬──────────┬──────────┐
          │          │          │       │          │          │
     ┌────▼───┐ ┌───▼────┐ ┌──▼──┐ ┌──▼───┐ ┌───▼───┐ ┌───▼────┐
     │ roles  │ │ tallas │ │datos│ │metad │ │direcc │ │contac  │
     │usuario │ │        │ │banc │ │instr │ │iones  │ │emergen │
     └────────┘ └────────┘ └─────┘ └──────┘ └───────┘ └────────┘

2. Tabla maestra: public.profiles

Se crea automaticamente cuando un usuario se registra via Supabase Auth. El trigger on_auth_user_created copia el auth.uid() y crea la fila basica.

ColumnaTipoRequeridoDescripcionEjemplo
iduuidPKMismo UUID que auth.users.ida1b2c3d4-…
cedulavarchar(20)UnicoCedula (V-12345678) o RIF (J-12345678-9)V-25123456
tipo_personaenumSi‘natural’ o ‘juridica’natural
nombrevarchar(100)SiPrimer nombreCarlos
segundo_nombrevarchar(100)NoSegundo nombreAugusto
apellidovarchar(100)SiPrimer apellidoRodriguez
segundo_apellidovarchar(100)NoSegundo apellidoPerez
emailvarchar(255)UnicoCorreo principal (mismo de auth)carlos@email.com
telefonovarchar(20)NoNumero con codigo de pais+58 412 1234567
fecha_nacimientodateNoFecha de nacimiento1998-03-15
generoenumNo‘masculino’, ‘femenino’, ‘otro’, ‘no_especifica’masculino
foto_urltextNoURL de la foto en Supabase Storagehttps://…storage/avatars/abc.jpg
estatusenumSi‘activo’, ‘suspendido’, ‘inactivo’, ‘graduado’, ‘retirado’activo
nivel_fidelidadvarchar(50)NoNivel en programa de puntosCopiloto
puntosintegerDefault 0Puntos acumulados de fidelidad1250
perfil_completadointegerDefault 0Porcentaje de completitud del perfil (0-100)85
created_attimestamptzAutoFecha de creacion2024-01-15T10:30:00Z
updated_attimestamptzAutoUltima modificacion2026-06-03T14:00:00Z

3. Tablas satelite

3.1 user_roles (roles del usuario)

Un usuario puede tener multiples roles simultaneos (ej: Alumno CIA + Cliente Aerotienda + Cliente Bistro). Ver Maestro, Seccion 3.

ColumnaTipoDescripcion
iduuid (PK)ID unico del registro
profile_iduuid (FK → profiles)A quien pertenece este rol
rolenum‘alumno_cia’, ‘alumno_cc’, ‘cliente_aerotienda’, ‘cliente_bistro’, ‘cliente_nautica’, ‘instructor’, ‘empleado’, ‘proveedor’
activobooleanSi el rol esta vigente o fue desactivado
asignado_porenum‘automatico’ (por trigger), ‘manual’ (por admin)
fecha_asignaciontimestamptzCuando se activo el rol
fecha_desactivaciontimestamptzCuando se desactivo (null si activo)

3.2 user_tallas (tallas de uniformes)

ColumnaTipoDescripcion
profile_iduuid (FK, PK)1 registro por usuario
camisavarchar(10)XS, S, M, L, XL, XXL
pantalonvarchar(10)28, 30, 32, 34, 36…
zapatosvarchar(10)38, 39, 40, 41, 42…
gorravarchar(10)S, M, L

3.3 user_direcciones (direcciones)

ColumnaTipoDescripcion
iduuid (PK)Un usuario puede tener varias direcciones
profile_iduuid (FK)A quien pertenece
tipoenum‘principal’, ‘envio’, ‘trabajo’, ‘otro’
direcciontextDireccion completa
ciudadvarchar(100)Ciudad
estadovarchar(100)Estado/provincia
paisvarchar(50)Default ‘Venezuela’
codigo_postalvarchar(10)Codigo postal
es_principalbooleanDefault false. Solo una puede ser true

3.4 user_datos_bancarios

ColumnaTipoDescripcion
iduuid (PK)Puede tener varias cuentas
profile_iduuid (FK)A quien pertenece
bancovarchar(100)Nombre del banco
tipo_cuentaenum‘ahorro’, ‘corriente’, ‘pago_movil’
numero_cuentavarchar(30)Numero de cuenta (encriptado en reposo)
titularvarchar(200)Nombre del titular
cedula_titularvarchar(20)Cedula del titular (puede ser otra persona)
es_principalbooleanCuenta predeterminada para pagos/reembolsos

3.5 user_contacto_emergencia

ColumnaTipoDescripcion
profile_iduuid (FK, PK)1 contacto por usuario
nombrevarchar(200)Nombre completo del contacto
parentescovarchar(50)Madre, padre, esposo/a, hermano/a, otro
telefonovarchar(20)Numero de contacto
emailvarchar(255)Correo del contacto (opcional)

3.6 metadata_instructores

Solo para usuarios con rol instructor. Ver Modulo de Instructores.

ColumnaTipoDescripcion
profile_iduuid (FK, PK)El instructor en profiles
numero_licenciavarchar(50)Numero de licencia INAC
tipo_licenciavarchar(50)PPL, CPL, ATP, Instructor
horas_vuelo_totalesdecimalHoras de vuelo acumuladas
especialidadvarchar(100)Tierra, vuelo, simulador, mixto
tarifa_horadecimalTarifa por hora de instruccion
disponiblebooleanSi acepta nuevos alumnos

4. Politicas de seguridad (RLS)

Cada tabla tiene reglas que controlan quien puede ver y editar que. Esto se aplica a nivel de base de datos — ni el frontend ni el backend pueden saltarselas.

4.1 profiles

OperacionQuien puedeRegla SQL simplificada
SELECT (ver)Tu propio perfil + adminsauth.uid() = id OR has_role('admin')
UPDATE (editar)Tu propio perfil (campos permitidos)auth.uid() = id (no puede cambiar cedula ni estatus)
INSERT (crear)Solo el trigger de authSe crea automaticamente al registrarse
DELETE (borrar)NadieProhibido. Se cambia estatus a ‘inactivo’

4.2 user_roles

OperacionQuien puedeLogica
SELECTEl propio usuario + admins + coordinadoresVer tus roles o los de tu grupo
INSERT/UPDATESolo admins y triggers automaticosUn alumno no puede asignarse roles
DELETENadieSe desactiva (activo = false)

4.3 Datos sensibles

TablaSELECTINSERT/UPDATERazon
user_datos_bancariosSolo el dueno + finanzasSolo el duenoDatos financieros privados
user_contacto_emergenciaEl dueno + RRHH + coordinadorSolo el duenoDato personal sensible
metadata_instructoresEl instructor + coordinador CIA + adminSolo admin + coordinador CIADatos operativos del instructor

5. Triggers y automatizaciones

TriggerSe activa cuandoQue hace
on_auth_user_createdUn usuario se registra via Supabase AuthCrea la fila en profiles con el UUID, email y estatus ‘activo’
on_profile_updatedSe edita profilesActualiza updated_at. Recalcula perfil_completado
on_role_assignedSe inserta en user_rolesNotifica al usuario. Si es ‘alumno_cia’, crea fila en historial_academico
on_payment_completedSe registra un pago (Nucleo 5)Suma puntos de fidelidad. Verifica si sube de nivel
on_document_expiredCron job diarioRevisa expedientes. Crea alerta si un documento vence en 30/15/5 dias
on_mora_detectedCuota pasa fecha de vencimientoCambia estatus de compromiso. Si acumula 3 cuotas: suspende al usuario

6. SQL de creacion (referencia)

Script simplificado para crear las tablas principales. El script completo se ejecutara al iniciar la Fase 1 de desarrollo.

-- =============================================
-- NUCLEO 1: USUARIOS Y PERFILES
-- =============================================

-- 1. Enums
CREATE TYPE persona_tipo AS ENUM ('natural', 'juridica');
CREATE TYPE estatus_tipo AS ENUM ('activo', 'suspendido', 'inactivo', 'graduado', 'retirado');
CREATE TYPE genero_tipo AS ENUM ('masculino', 'femenino', 'otro', 'no_especifica');
CREATE TYPE rol_tipo AS ENUM (
  'alumno_cia', 'alumno_cc', 
  'cliente_aerotienda', 'cliente_bistro', 'cliente_nautica',
  'instructor', 'empleado', 'proveedor',
  'admin', 'coordinador', 'gerente'
);

-- 2. Tabla maestra
CREATE TABLE public.profiles (
  id              uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
  cedula          varchar(20) UNIQUE,
  tipo_persona    persona_tipo DEFAULT 'natural',
  nombre          varchar(100) NOT NULL,
  segundo_nombre  varchar(100),
  apellido        varchar(100) NOT NULL,
  segundo_apellido varchar(100),
  email           varchar(255) UNIQUE NOT NULL,
  telefono        varchar(20),
  fecha_nacimiento date,
  genero          genero_tipo,
  foto_url        text,
  estatus         estatus_tipo DEFAULT 'activo',
  nivel_fidelidad varchar(50) DEFAULT 'Pasajero',
  puntos          integer DEFAULT 0,
  perfil_completado integer DEFAULT 0,
  created_at      timestamptz DEFAULT now(),
  updated_at      timestamptz DEFAULT now()
);

-- 3. Roles (muchos a muchos)
CREATE TABLE public.user_roles (
  id                uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  profile_id        uuid REFERENCES profiles(id) ON DELETE CASCADE,
  rol               rol_tipo NOT NULL,
  activo            boolean DEFAULT true,
  asignado_por      varchar(20) DEFAULT 'manual',
  fecha_asignacion  timestamptz DEFAULT now(),
  fecha_desactivacion timestamptz,
  UNIQUE(profile_id, rol)
);

-- 4. Trigger: crear profile al registrarse
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
  INSERT INTO public.profiles (id, email, nombre, apellido)
  VALUES (
    NEW.id,
    NEW.email,
    COALESCE(NEW.raw_user_meta_data->>'nombre', ''),
    COALESCE(NEW.raw_user_meta_data->>'apellido', '')
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

-- 5. RLS
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can view own profile"
  ON profiles FOR SELECT
  USING (auth.uid() = id);

CREATE POLICY "Users can update own profile"
  ON profiles FOR UPDATE
  USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

CREATE POLICY "Admins can view all profiles"
  ON profiles FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM user_roles
      WHERE profile_id = auth.uid()
      AND rol IN ('admin', 'coordinador', 'gerente')
      AND activo = true
    )
  );

7. Conexion con otros Nucleos

NucleoTablaComo se conecta con profiles
2 – Comercialpedidospedidos.user_id → profiles.id
4 – Produccioncronogramascronogramas.alumno_id → profiles.id
5 – Finanzascompromisos, cuotascompromisos.user_id → profiles.id
6 – Documentalexpedientesexpedientes.user_id → profiles.id
7 – RRHHempleadosempleados.profile_id → profiles.id
8 – Soporteticketstickets.created_by → profiles.id

Regla: Ninguna tabla de ningun Nucleo puede guardar nombre, cedula o email directamente. Siempre referencian a profiles.id con Foreign Key. Un solo lugar donde vive la identidad.


8. Referencia

DocumentoRelacion
Instructivo Maestro de UsuariosLas reglas de negocio que este schema implementa
Stack TecnologicoPostgreSQL, Supabase, RLS — las herramientas
Arquitectura Global de DatosLos 8 Nucleos y como se conectan
Automatizacion de RolesLos triggers que asignan roles automaticamente
Diseno de InterfazLas pantallas que consumen estas tablas

Centro de soporte