68 lines
2.8 KiB
SQL
68 lines
2.8 KiB
SQL
-- ============================================================================
|
|
-- OrbiQuant IA - Trading Platform
|
|
-- Schema: auth
|
|
-- File: tables/09-login_attempts.sql
|
|
-- Description: Login attempt tracking for rate limiting and security monitoring
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE auth.login_attempts (
|
|
-- Primary Key
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Attempt Information
|
|
email CITEXT,
|
|
user_id UUID,
|
|
|
|
-- Request Context
|
|
ip_address INET NOT NULL,
|
|
user_agent TEXT,
|
|
|
|
-- Attempt Result
|
|
success BOOLEAN NOT NULL,
|
|
failure_reason VARCHAR(100),
|
|
|
|
-- Additional Details
|
|
attempted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Metadata
|
|
metadata JSONB DEFAULT '{}'::jsonb,
|
|
|
|
-- Audit Fields
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Check Constraints
|
|
CONSTRAINT login_attempt_has_identifier CHECK (
|
|
email IS NOT NULL OR user_id IS NOT NULL
|
|
),
|
|
CONSTRAINT failure_reason_consistency CHECK (
|
|
(success = false AND failure_reason IS NOT NULL) OR
|
|
(success = true AND failure_reason IS NULL)
|
|
)
|
|
);
|
|
|
|
-- Indexes for Performance
|
|
CREATE INDEX idx_login_attempts_email ON auth.login_attempts(email, created_at DESC);
|
|
CREATE INDEX idx_login_attempts_user_id ON auth.login_attempts(user_id, created_at DESC);
|
|
CREATE INDEX idx_login_attempts_ip ON auth.login_attempts(ip_address, created_at DESC);
|
|
CREATE INDEX idx_login_attempts_created ON auth.login_attempts(created_at DESC);
|
|
CREATE INDEX idx_login_attempts_failures ON auth.login_attempts(email, ip_address, created_at DESC)
|
|
WHERE success = false;
|
|
CREATE INDEX idx_login_attempts_success ON auth.login_attempts(email, created_at DESC)
|
|
WHERE success = true;
|
|
CREATE INDEX idx_login_attempts_metadata ON auth.login_attempts USING gin(metadata);
|
|
|
|
-- Table Comments
|
|
COMMENT ON TABLE auth.login_attempts IS 'Login attempt tracking for rate limiting, brute force detection, and security monitoring';
|
|
|
|
-- Column Comments
|
|
COMMENT ON COLUMN auth.login_attempts.id IS 'Unique identifier for the login attempt';
|
|
COMMENT ON COLUMN auth.login_attempts.email IS 'Email address used in login attempt';
|
|
COMMENT ON COLUMN auth.login_attempts.user_id IS 'User ID if resolved from email';
|
|
COMMENT ON COLUMN auth.login_attempts.ip_address IS 'IP address of the login attempt';
|
|
COMMENT ON COLUMN auth.login_attempts.user_agent IS 'User agent string from the request';
|
|
COMMENT ON COLUMN auth.login_attempts.success IS 'Whether the login attempt was successful';
|
|
COMMENT ON COLUMN auth.login_attempts.failure_reason IS 'Reason for login failure (invalid_password, account_locked, etc.)';
|
|
COMMENT ON COLUMN auth.login_attempts.attempted_at IS 'Timestamp when login was attempted';
|
|
COMMENT ON COLUMN auth.login_attempts.metadata IS 'Additional attempt metadata as JSON';
|
|
COMMENT ON COLUMN auth.login_attempts.created_at IS 'Timestamp when record was created';
|