template-saas-database-v2/migrations/V20260120_001__migrate_auth_sessions_structure_DOWN.sql
rckrdmrd 27de049441 [TEMPLATE-SAAS-DB] chore: Update audit schema and add migrations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 04:38:47 -06:00

115 lines
3.9 KiB
PL/PgSQL

-- ============================================
-- Migration: V20260120_001 - DOWN (Rollback)
-- Description: Revert auth.sessions structure to legacy
-- Changes (reversed):
-- - Rename token_hash -> session_token (VARCHAR(255) -> VARCHAR(64))
-- - Change status (ENUM) -> is_active (BOOLEAN)
-- - Remove device_name, browser, os, location columns
-- - Remove revoked_at, revoked_reason columns
-- ============================================
-- DOWN Migration (Rollback)
BEGIN;
-- ============================================
-- 1. Add is_active column back
-- ============================================
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'auth' AND table_name = 'sessions' AND column_name = 'status'
) AND NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'auth' AND table_name = 'sessions' AND column_name = 'is_active'
) THEN
-- Add is_active column
ALTER TABLE auth.sessions ADD COLUMN is_active BOOLEAN DEFAULT TRUE;
-- Migrate data back: status = 'active' -> true, else -> false
UPDATE auth.sessions
SET is_active = (status = 'active');
-- Set NOT NULL
ALTER TABLE auth.sessions ALTER COLUMN is_active SET NOT NULL;
-- Drop status column
ALTER TABLE auth.sessions DROP COLUMN status;
-- Recreate indexes with is_active
DROP INDEX IF EXISTS auth.idx_sessions_user;
DROP INDEX IF EXISTS auth.idx_sessions_tenant;
DROP INDEX IF EXISTS auth.idx_sessions_expires;
CREATE INDEX idx_sessions_user ON auth.sessions(user_id) WHERE is_active = true;
CREATE INDEX idx_sessions_tenant ON auth.sessions(tenant_id) WHERE is_active = true;
CREATE INDEX idx_sessions_expires ON auth.sessions(expires_at) WHERE is_active = true;
RAISE NOTICE 'Reverted status enum to is_active boolean';
END IF;
END $$;
-- ============================================
-- 2. Rename token_hash -> session_token
-- ============================================
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'auth' AND table_name = 'sessions' AND column_name = 'token_hash'
) THEN
-- Drop index
DROP INDEX IF EXISTS auth.idx_sessions_token;
-- Rename column
ALTER TABLE auth.sessions RENAME COLUMN token_hash TO session_token;
-- WARNING: This will truncate data if any tokens are > 64 chars
-- In production, verify data before running this
ALTER TABLE auth.sessions ALTER COLUMN session_token TYPE VARCHAR(64);
-- Recreate index
CREATE INDEX idx_sessions_token ON auth.sessions(session_token);
RAISE NOTICE 'Renamed token_hash to session_token and shrunk to VARCHAR(64)';
END IF;
END $$;
-- ============================================
-- 3. Remove new columns
-- ============================================
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS device_name;
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS browser;
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS os;
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS location;
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS revoked_at;
ALTER TABLE auth.sessions DROP COLUMN IF EXISTS revoked_reason;
-- ============================================
-- 4. Restore original cleanup function
-- ============================================
CREATE OR REPLACE FUNCTION auth.cleanup_expired_sessions()
RETURNS INTEGER AS $$
DECLARE
deleted_count INTEGER;
BEGIN
WITH deleted AS (
DELETE FROM auth.sessions
WHERE expires_at < NOW() - INTERVAL '7 days'
OR (is_active = false AND updated_at < NOW() - INTERVAL '30 days')
RETURNING *
)
SELECT COUNT(*) INTO deleted_count FROM deleted;
RETURN deleted_count;
END;
$$ LANGUAGE plpgsql;
RAISE NOTICE 'Rollback of V20260120_001 completed';
COMMIT;