michangarrito/database/schemas/04-auth.sql
rckrdmrd 48dea7a5d0 feat: Initial commit - michangarrito
Marketplace móvil para negocios locales mexicanos.

Estructura inicial:
- apps/backend (NestJS API)
- apps/frontend (React Web)
- apps/mobile (Expo/React Native)
- apps/mcp-server (Claude MCP Server)
- apps/whatsapp-service (WhatsApp Business API)
- database/ (PostgreSQL DDL)
- docs/ (Documentación)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:41:02 -06:00

85 lines
2.3 KiB
SQL

-- =============================================================================
-- MICHANGARRITO - 04 AUTH
-- =============================================================================
-- Autenticación y usuarios
-- =============================================================================
-- Usuarios
CREATE TABLE IF NOT EXISTS auth.users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
-- Identificación
phone VARCHAR(20) NOT NULL,
email VARCHAR(100),
name VARCHAR(100) NOT NULL,
-- Autenticación
pin_hash VARCHAR(255),
biometric_enabled BOOLEAN DEFAULT false,
biometric_key TEXT,
-- Rol
role VARCHAR(20) NOT NULL DEFAULT 'owner',
permissions JSONB DEFAULT '{}',
-- Estado
status VARCHAR(20) DEFAULT 'active',
last_login_at TIMESTAMPTZ,
failed_attempts INTEGER DEFAULT 0,
locked_until TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(tenant_id, phone)
);
CREATE INDEX idx_users_tenant ON auth.users(tenant_id);
CREATE INDEX idx_users_phone ON auth.users(phone);
CREATE TRIGGER update_users_updated_at
BEFORE UPDATE ON auth.users
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- Sesiones
CREATE TABLE IF NOT EXISTS auth.sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL,
refresh_token_hash VARCHAR(255),
device_type VARCHAR(20),
device_info JSONB,
ip_address VARCHAR(45),
expires_at TIMESTAMPTZ NOT NULL,
refresh_expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
last_activity_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_sessions_user ON auth.sessions(user_id);
CREATE INDEX idx_sessions_token ON auth.sessions(token_hash);
-- Códigos OTP
CREATE TABLE IF NOT EXISTS auth.otp_codes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
phone VARCHAR(20) NOT NULL,
code VARCHAR(6) NOT NULL,
purpose VARCHAR(20) NOT NULL,
attempts INTEGER DEFAULT 0,
max_attempts INTEGER DEFAULT 3,
expires_at TIMESTAMPTZ NOT NULL,
used_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_otp_phone ON auth.otp_codes(phone, purpose);