-- ============================================================================ -- OrbiQuant IA - Trading Platform -- Schema: auth -- File: tables/04-sessions.sql -- Description: User session management for authentication -- ============================================================================ CREATE TABLE auth.sessions ( -- Primary Key id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Foreign Key to Users user_id UUID NOT NULL, -- Session Token session_token VARCHAR(255) NOT NULL UNIQUE, -- Session Lifecycle expires_at TIMESTAMPTZ NOT NULL, is_active BOOLEAN NOT NULL DEFAULT true, -- Session Metadata ip_address INET, user_agent TEXT, device_type VARCHAR(50), device_name VARCHAR(100), browser VARCHAR(50), os VARCHAR(50), -- Geolocation country_code VARCHAR(2), city VARCHAR(100), -- Security last_activity_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), invalidated_at TIMESTAMPTZ, invalidation_reason VARCHAR(100), -- Audit Fields created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Foreign Key Constraints CONSTRAINT fk_sessions_user FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE, -- Check Constraints CONSTRAINT valid_session_dates CHECK (expires_at > created_at), CONSTRAINT invalidated_consistency CHECK ( (is_active = false AND invalidated_at IS NOT NULL) OR (is_active = true AND invalidated_at IS NULL) ) ); -- Indexes for Performance CREATE INDEX idx_sessions_user_id ON auth.sessions(user_id); CREATE INDEX idx_sessions_token ON auth.sessions(session_token); CREATE INDEX idx_sessions_expires_at ON auth.sessions(expires_at); CREATE INDEX idx_sessions_active ON auth.sessions(is_active, expires_at) WHERE is_active = true; CREATE INDEX idx_sessions_last_activity ON auth.sessions(last_activity_at DESC); CREATE INDEX idx_sessions_ip_address ON auth.sessions(ip_address); CREATE INDEX idx_sessions_user_active ON auth.sessions(user_id, is_active, expires_at) WHERE is_active = true; -- Table Comments COMMENT ON TABLE auth.sessions IS 'User session management for authentication and activity tracking'; -- Column Comments COMMENT ON COLUMN auth.sessions.id IS 'Unique identifier for the session'; COMMENT ON COLUMN auth.sessions.user_id IS 'Reference to the user account'; COMMENT ON COLUMN auth.sessions.session_token IS 'Unique session token for authentication'; COMMENT ON COLUMN auth.sessions.expires_at IS 'Session expiration timestamp'; COMMENT ON COLUMN auth.sessions.is_active IS 'Whether the session is currently active'; COMMENT ON COLUMN auth.sessions.ip_address IS 'IP address of the session'; COMMENT ON COLUMN auth.sessions.user_agent IS 'User agent string from the browser'; COMMENT ON COLUMN auth.sessions.device_type IS 'Device type (desktop, mobile, tablet)'; COMMENT ON COLUMN auth.sessions.device_name IS 'Device name or model'; COMMENT ON COLUMN auth.sessions.browser IS 'Browser name and version'; COMMENT ON COLUMN auth.sessions.os IS 'Operating system name and version'; COMMENT ON COLUMN auth.sessions.country_code IS 'Country code from IP geolocation'; COMMENT ON COLUMN auth.sessions.city IS 'City from IP geolocation'; COMMENT ON COLUMN auth.sessions.last_activity_at IS 'Timestamp of last session activity'; COMMENT ON COLUMN auth.sessions.invalidated_at IS 'Timestamp when session was invalidated'; COMMENT ON COLUMN auth.sessions.invalidation_reason IS 'Reason for session invalidation'; COMMENT ON COLUMN auth.sessions.created_at IS 'Timestamp when session was created'; COMMENT ON COLUMN auth.sessions.updated_at IS 'Timestamp when session was last updated';