Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ next-env.d.ts
.DS_Store
.vercel
coverage
.current-issue.md
.implementation-plan.md
.implement-config
CLAUDE.md
43 changes: 43 additions & 0 deletions backend/migrations/20260513_userid_text_to_uuid.rollback.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- Rollback: revert user_id uuid FK migration
-- Run this ONLY if the forward migration needs to be undone.
-- This will NOT restore data that was deleted by ON DELETE CASCADE/SET NULL.

BEGIN;

-- workflow_shares
ALTER TABLE public.workflow_shares DROP CONSTRAINT IF EXISTS workflow_shares_shared_by_user_id_fkey;
ALTER TABLE public.workflow_shares ALTER COLUMN shared_by_user_id TYPE text;

-- hidden_workflows
ALTER TABLE public.hidden_workflows DROP CONSTRAINT IF EXISTS hidden_workflows_user_id_fkey;
ALTER TABLE public.hidden_workflows ALTER COLUMN user_id TYPE text;

-- workflows
ALTER TABLE public.workflows DROP CONSTRAINT IF EXISTS workflows_user_id_fkey;
ALTER TABLE public.workflows ALTER COLUMN user_id TYPE text;

-- tabular_review_chats
ALTER TABLE public.tabular_review_chats DROP CONSTRAINT IF EXISTS tabular_review_chats_user_id_fkey;
ALTER TABLE public.tabular_review_chats ALTER COLUMN user_id TYPE text;

-- tabular_reviews
ALTER TABLE public.tabular_reviews DROP CONSTRAINT IF EXISTS tabular_reviews_user_id_fkey;
ALTER TABLE public.tabular_reviews ALTER COLUMN user_id TYPE text;

-- chats
ALTER TABLE public.chats DROP CONSTRAINT IF EXISTS chats_user_id_fkey;
ALTER TABLE public.chats ALTER COLUMN user_id TYPE text;

-- documents
ALTER TABLE public.documents DROP CONSTRAINT IF EXISTS documents_user_id_fkey;
ALTER TABLE public.documents ALTER COLUMN user_id TYPE text;

-- project_subfolders
ALTER TABLE public.project_subfolders DROP CONSTRAINT IF EXISTS project_subfolders_user_id_fkey;
ALTER TABLE public.project_subfolders ALTER COLUMN user_id TYPE text;

-- projects
ALTER TABLE public.projects DROP CONSTRAINT IF EXISTS projects_user_id_fkey;
ALTER TABLE public.projects ALTER COLUMN user_id TYPE text;

COMMIT;
144 changes: 144 additions & 0 deletions backend/migrations/20260513_userid_text_to_uuid.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
-- Migration: convert user_id text columns to uuid with FK to auth.users
--
-- APPLY CAREFULLY — this is a breaking schema change.
-- Run in a transaction; it will abort on the first invalid value.
--
-- Pre-flight check (run manually before applying):
-- SELECT table_name, user_id
-- FROM (
-- SELECT 'projects' AS table_name, user_id FROM public.projects
-- UNION ALL
-- SELECT 'documents', user_id FROM public.documents
-- UNION ALL
-- SELECT 'project_subfolders', user_id FROM public.project_subfolders
-- UNION ALL
-- SELECT 'chats', user_id FROM public.chats
-- UNION ALL
-- SELECT 'tabular_reviews',user_id FROM public.tabular_reviews
-- UNION ALL
-- SELECT 'workflows', user_id FROM public.workflows WHERE user_id IS NOT NULL
-- UNION ALL
-- SELECT 'hidden_workflows',user_id FROM public.hidden_workflows
-- UNION ALL
-- SELECT 'tabular_review_chats', user_id FROM public.tabular_review_chats
-- UNION ALL
-- SELECT 'workflow_shares (shared_by)', shared_by_user_id FROM public.workflow_shares
-- ) t
-- WHERE t.user_id !~ '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$';
--
-- If that returns any rows, fix or remove them before applying this migration.

BEGIN;

-- ---------------------------------------------------------------------------
-- projects
-- ---------------------------------------------------------------------------
ALTER TABLE public.projects
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.projects
ADD CONSTRAINT projects_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- project_subfolders
-- ---------------------------------------------------------------------------
ALTER TABLE public.project_subfolders
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.project_subfolders
ADD CONSTRAINT project_subfolders_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- documents
-- ---------------------------------------------------------------------------
ALTER TABLE public.documents
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.documents
ADD CONSTRAINT documents_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- chats
-- ---------------------------------------------------------------------------
ALTER TABLE public.chats
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.chats
ADD CONSTRAINT chats_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- tabular_reviews
-- ---------------------------------------------------------------------------
ALTER TABLE public.tabular_reviews
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.tabular_reviews
ADD CONSTRAINT tabular_reviews_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- tabular_review_chats
-- ---------------------------------------------------------------------------
ALTER TABLE public.tabular_review_chats
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.tabular_review_chats
ADD CONSTRAINT tabular_review_chats_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- workflows (user_id is nullable — system workflows have NULL)
-- ON DELETE SET NULL rather than CASCADE: deleting a user orphans their
-- workflows rather than deleting them, preserving shared workflow access
-- for other users who have workflow_shares rows referencing these workflows.
-- ---------------------------------------------------------------------------
ALTER TABLE public.workflows
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.workflows
ADD CONSTRAINT workflows_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE SET NULL;

-- ---------------------------------------------------------------------------
-- hidden_workflows
-- ---------------------------------------------------------------------------
ALTER TABLE public.hidden_workflows
ALTER COLUMN user_id TYPE uuid USING user_id::uuid;

ALTER TABLE public.hidden_workflows
ADD CONSTRAINT hidden_workflows_user_id_fkey
FOREIGN KEY (user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

-- ---------------------------------------------------------------------------
-- workflow_shares (shared_by_user_id)
-- ---------------------------------------------------------------------------
ALTER TABLE public.workflow_shares
ALTER COLUMN shared_by_user_id TYPE uuid USING shared_by_user_id::uuid;

ALTER TABLE public.workflow_shares
ADD CONSTRAINT workflow_shares_shared_by_user_id_fkey
FOREIGN KEY (shared_by_user_id)
REFERENCES auth.users(id)
ON DELETE CASCADE;

COMMIT;
Loading