Problem
backend/schema.sql — user_profiles and user_api_keys correctly use uuid references auth.users(id) on delete cascade, but the majority of application tables use a bare text column:
projects.user_id text not null
documents.user_id text not null
chats.user_id text not null
tabular_reviews.user_id text not null
workflows.user_id text
project_subfolders.user_id text not null
workflow_shares.shared_by_user_id text not null
Postgres cannot enforce that stored user IDs correspond to real Supabase users. A data migration error, a bulk import, or a future code bug could silently insert a user ID that doesn't exist in auth.users, and Postgres would accept it without complaint.
Fix
Migrate user_id text columns to uuid references auth.users(id) on delete cascade. This is a breaking schema change — the migration should:
ALTER COLUMN user_id TYPE uuid USING user_id::uuid (fails fast on non-UUID values).
- Verify no rows reference non-existent users before adding the FK.
- Add
ON DELETE CASCADE or ON DELETE SET NULL as appropriate per table.
Problem
backend/schema.sql—user_profilesanduser_api_keyscorrectly useuuid references auth.users(id) on delete cascade, but the majority of application tables use a baretextcolumn:projects.user_id text not nulldocuments.user_id text not nullchats.user_id text not nulltabular_reviews.user_id text not nullworkflows.user_id textproject_subfolders.user_id text not nullworkflow_shares.shared_by_user_id text not nullPostgres cannot enforce that stored user IDs correspond to real Supabase users. A data migration error, a bulk import, or a future code bug could silently insert a user ID that doesn't exist in
auth.users, and Postgres would accept it without complaint.Fix
Migrate
user_id textcolumns touuid references auth.users(id) on delete cascade. This is a breaking schema change — the migration should:ALTER COLUMN user_id TYPE uuid USING user_id::uuid(fails fast on non-UUID values).ON DELETE CASCADEorON DELETE SET NULLas appropriate per table.