feat: tenant isolation Phase 4 — RLS on all remaining tables #136

Merged
chihlasm merged 9 commits from feat/tenant-isolation-phase-4 into main 2026-04-12 04:35:32 +00:00
chihlasm commented 2026-04-12 01:25:43 +00:00 (Migrated from github.com)

Summary

Completes RLS coverage across the entire schema — after this PR every table with account_id has a policy enforced.

  • 31 tables get RLS in a single migration (b3c7e9f2a1d8)
  • Standard policy (29 tables): tenant sees own rows only
  • Platform-visibility policy (2 tables): platform_steps, template_trees — own rows OR PLATFORM_ACCOUNT_ID so global content is readable by all tenants
  • Intentionally skipped: accounts (IS the root table, no account_id column), plan_feature_defaults (platform config, no account_id)

Also fixes a pre-existing bug: script_builder_service.create_session() was missing account_id= on the ScriptBuilderSession constructor, causing NOT NULL violations and 500s on all script builder endpoints.

Tables covered

Standard policy: users, account_invites, account_limit_overrides, account_feature_overrides, subscriptions, ai_chat_sessions, ai_conversations, ai_session_steps, ai_session_embeddings, ai_suggestions, ai_usage, assistant_chats, attachments, copilot_conversations, feedback, file_uploads, fork_points, kb_imports, notifications, notification_configs, notification_logs, psa_activity_logs, psa_member_mappings, script_builder_sessions, script_categories, session_ratings, tree_embeddings, user_folders, user_pinned_trees

Platform-visibility policy: platform_steps, template_trees

Test plan

  • Phase 4 RLS isolation tests: users, script_builder_sessions, ai_session_steps, notifications, platform_steps, template_trees
  • platform_steps and template_trees tests verify global content IS visible to tenants
  • alembic upgrade head on clean DB applies cleanly
  • test_script_builder.py — 500s on session create should now be fixed

🤖 Generated with Claude Code

## Summary Completes RLS coverage across the entire schema — after this PR every table with `account_id` has a policy enforced. - **31 tables** get RLS in a single migration (`b3c7e9f2a1d8`) - **Standard policy** (29 tables): tenant sees own rows only - **Platform-visibility policy** (2 tables): `platform_steps`, `template_trees` — own rows OR `PLATFORM_ACCOUNT_ID` so global content is readable by all tenants - **Intentionally skipped**: `accounts` (IS the root table, no `account_id` column), `plan_feature_defaults` (platform config, no `account_id`) Also fixes a pre-existing bug: `script_builder_service.create_session()` was missing `account_id=` on the `ScriptBuilderSession` constructor, causing `NOT NULL` violations and 500s on all script builder endpoints. ## Tables covered **Standard policy:** `users`, `account_invites`, `account_limit_overrides`, `account_feature_overrides`, `subscriptions`, `ai_chat_sessions`, `ai_conversations`, `ai_session_steps`, `ai_session_embeddings`, `ai_suggestions`, `ai_usage`, `assistant_chats`, `attachments`, `copilot_conversations`, `feedback`, `file_uploads`, `fork_points`, `kb_imports`, `notifications`, `notification_configs`, `notification_logs`, `psa_activity_logs`, `psa_member_mappings`, `script_builder_sessions`, `script_categories`, `session_ratings`, `tree_embeddings`, `user_folders`, `user_pinned_trees` **Platform-visibility policy:** `platform_steps`, `template_trees` ## Test plan - [ ] Phase 4 RLS isolation tests: `users`, `script_builder_sessions`, `ai_session_steps`, `notifications`, `platform_steps`, `template_trees` - [ ] `platform_steps` and `template_trees` tests verify global content IS visible to tenants - [ ] `alembic upgrade head` on clean DB applies cleanly - [ ] `test_script_builder.py` — 500s on session create should now be fixed 🤖 Generated with [Claude Code](https://claude.com/claude-code)
railway-app[bot] commented 2026-04-12 01:25:59 +00:00 (Migrated from github.com)

🚅 Deployed to the resolutionflow-pr-136 environment in selfless-grace

Service Status Web Updated (UTC)
hopeful-liberation Success (View Logs) Web Apr 12, 2026 at 3:50 am
patherly Success (View Logs) Web Apr 12, 2026 at 3:50 am
<!-- railway-bot-comment-version=2 --> <!-- railway-project-id="22b9b58c-271b-42e5-a10e-6fdec8d00134" railway-project-name="selfless-grace" --> 🚅 Deployed to the [resolutionflow-pr-136](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134?environmentId=6cc35d28-7f9e-472e-afd6-dfd08f2eb3a0) environment in **[selfless-grace](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134)** | **Service** | **Status** | **Web** | **Updated** (UTC) | | :--- | :--- | :--- | :--- | | hopeful-liberation | ✅ Success ([View Logs](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134/service/e1db2ee3-d241-4f45-abe4-c9c5fdf483d5?id=076a4d8a-c0af-4def-90b2-997745c7707e&environmentId=6cc35d28-7f9e-472e-afd6-dfd08f2eb3a0)) | [Web](https://hopeful-liberation-resolutionflow-pr-136.up.railway.app) | Apr 12, 2026 at 3:50 am | | patherly | ✅ Success ([View Logs](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134/service/95f556ff-5264-4116-a0c2-618a2fc53ba4?id=3accf7c7-4128-4863-9fae-40076a1f11d3&environmentId=6cc35d28-7f9e-472e-afd6-dfd08f2eb3a0)) | [Web](https://patherly-resolutionflow-pr-136.up.railway.app) | Apr 12, 2026 at 3:50 am |
Sign in to join this conversation.