79 lines
3.3 KiB
SQL
79 lines
3.3 KiB
SQL
-- ============================================================================
|
|
-- OrbiQuant IA - Trading Platform
|
|
-- Schema: auth
|
|
-- File: tables/06-phone_verifications.sql
|
|
-- Description: Phone number verification tokens and tracking
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE auth.phone_verifications (
|
|
-- Primary Key
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Foreign Key to Users
|
|
user_id UUID NOT NULL,
|
|
|
|
-- Phone and Verification Code
|
|
phone_number VARCHAR(20) NOT NULL,
|
|
verification_code VARCHAR(10) NOT NULL,
|
|
channel auth.phone_channel NOT NULL DEFAULT 'sms',
|
|
|
|
-- Token Lifecycle
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
verified_at TIMESTAMPTZ,
|
|
is_verified BOOLEAN NOT NULL DEFAULT false,
|
|
|
|
-- Attempt Tracking
|
|
send_attempts INTEGER NOT NULL DEFAULT 0,
|
|
verification_attempts INTEGER NOT NULL DEFAULT 0,
|
|
max_attempts INTEGER NOT NULL DEFAULT 3,
|
|
|
|
-- Metadata
|
|
ip_address INET,
|
|
user_agent TEXT,
|
|
|
|
-- Audit Fields
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Foreign Key Constraints
|
|
CONSTRAINT fk_phone_verifications_user FOREIGN KEY (user_id)
|
|
REFERENCES auth.users(id)
|
|
ON DELETE CASCADE,
|
|
|
|
-- Check Constraints
|
|
CONSTRAINT valid_expiration CHECK (expires_at > created_at),
|
|
CONSTRAINT verified_consistency CHECK (
|
|
(is_verified = true AND verified_at IS NOT NULL) OR
|
|
(is_verified = false AND verified_at IS NULL)
|
|
),
|
|
CONSTRAINT valid_attempts CHECK (
|
|
send_attempts >= 0 AND
|
|
verification_attempts >= 0 AND
|
|
verification_attempts <= max_attempts
|
|
)
|
|
);
|
|
|
|
-- Indexes for Performance
|
|
CREATE INDEX idx_phone_verifications_user_id ON auth.phone_verifications(user_id);
|
|
CREATE INDEX idx_phone_verifications_phone ON auth.phone_verifications(phone_number);
|
|
CREATE INDEX idx_phone_verifications_expires ON auth.phone_verifications(expires_at);
|
|
CREATE INDEX idx_phone_verifications_pending ON auth.phone_verifications(user_id, is_verified, expires_at)
|
|
WHERE is_verified = false;
|
|
|
|
-- Table Comments
|
|
COMMENT ON TABLE auth.phone_verifications IS 'Phone number verification codes and tracking for user phone confirmation';
|
|
|
|
-- Column Comments
|
|
COMMENT ON COLUMN auth.phone_verifications.id IS 'Unique identifier for the verification record';
|
|
COMMENT ON COLUMN auth.phone_verifications.user_id IS 'Reference to the user account';
|
|
COMMENT ON COLUMN auth.phone_verifications.phone_number IS 'Phone number to be verified';
|
|
COMMENT ON COLUMN auth.phone_verifications.verification_code IS 'Verification code sent via SMS';
|
|
COMMENT ON COLUMN auth.phone_verifications.expires_at IS 'Code expiration timestamp';
|
|
COMMENT ON COLUMN auth.phone_verifications.verified_at IS 'Timestamp when phone was verified';
|
|
COMMENT ON COLUMN auth.phone_verifications.is_verified IS 'Whether the phone has been verified';
|
|
COMMENT ON COLUMN auth.phone_verifications.send_attempts IS 'Number of times code was sent';
|
|
COMMENT ON COLUMN auth.phone_verifications.verification_attempts IS 'Number of verification attempts';
|
|
COMMENT ON COLUMN auth.phone_verifications.max_attempts IS 'Maximum allowed verification attempts';
|
|
COMMENT ON COLUMN auth.phone_verifications.ip_address IS 'IP address when verification was requested';
|
|
COMMENT ON COLUMN auth.phone_verifications.user_agent IS 'User agent when verification was requested';
|
|
COMMENT ON COLUMN auth.phone_verifications.created_at IS 'Timestamp when verification was created';
|