-- ============================================================================ -- OrbiQuant IA - Trading Platform -- Schema: auth -- File: tables/03-oauth_accounts.sql -- Description: OAuth provider accounts linked to users -- ============================================================================ CREATE TABLE auth.oauth_accounts ( -- Primary Key id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Foreign Key to Users user_id UUID NOT NULL, -- OAuth Provider Information provider auth.oauth_provider NOT NULL, provider_account_id VARCHAR(255) NOT NULL, provider_email CITEXT, -- OAuth Tokens access_token TEXT, refresh_token TEXT, token_expires_at TIMESTAMPTZ, -- Provider Profile Data profile_data JSONB DEFAULT '{}'::jsonb, -- Audit Fields linked_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_used_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Foreign Key Constraints CONSTRAINT fk_oauth_accounts_user FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE, -- Unique Constraint: One provider account per user CONSTRAINT unique_user_provider UNIQUE (user_id, provider), -- Unique Constraint: Provider account can only link to one user CONSTRAINT unique_provider_account UNIQUE (provider, provider_account_id) ); -- Indexes for Performance CREATE INDEX idx_oauth_accounts_user_id ON auth.oauth_accounts(user_id); CREATE INDEX idx_oauth_accounts_provider ON auth.oauth_accounts(provider); CREATE INDEX idx_oauth_accounts_provider_email ON auth.oauth_accounts(provider_email); CREATE INDEX idx_oauth_accounts_last_used ON auth.oauth_accounts(last_used_at DESC); CREATE INDEX idx_oauth_accounts_profile_data ON auth.oauth_accounts USING gin(profile_data); -- Table Comments COMMENT ON TABLE auth.oauth_accounts IS 'OAuth provider accounts linked to users for social authentication'; -- Column Comments COMMENT ON COLUMN auth.oauth_accounts.id IS 'Unique identifier for the OAuth account'; COMMENT ON COLUMN auth.oauth_accounts.user_id IS 'Reference to the user account'; COMMENT ON COLUMN auth.oauth_accounts.provider IS 'OAuth provider (google, facebook, etc.)'; COMMENT ON COLUMN auth.oauth_accounts.provider_account_id IS 'User ID from the OAuth provider'; COMMENT ON COLUMN auth.oauth_accounts.provider_email IS 'Email address from OAuth provider'; COMMENT ON COLUMN auth.oauth_accounts.access_token IS 'OAuth access token (encrypted)'; COMMENT ON COLUMN auth.oauth_accounts.refresh_token IS 'OAuth refresh token (encrypted)'; COMMENT ON COLUMN auth.oauth_accounts.token_expires_at IS 'Access token expiration timestamp'; COMMENT ON COLUMN auth.oauth_accounts.profile_data IS 'Profile data from OAuth provider as JSON'; COMMENT ON COLUMN auth.oauth_accounts.linked_at IS 'Timestamp when account was linked'; COMMENT ON COLUMN auth.oauth_accounts.last_used_at IS 'Timestamp when last used for authentication'; COMMENT ON COLUMN auth.oauth_accounts.created_at IS 'Timestamp when record was created'; COMMENT ON COLUMN auth.oauth_accounts.updated_at IS 'Timestamp when record was last updated';