- test_rls_isolation: add pytestmark for module-scoped event loop to fix
"Future attached to a different loop" with pytest-asyncio 0.23 + asyncpg
module-scoped fixtures
- test_admin_categories_global: global categories use PLATFORM_ACCOUNT_ID
not NULL; update stale assertion
- test_permissions_account: with RLS, cross-tenant tree access returns 404
(invisible) not 403 (forbidden) — update to match actual behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 4 enabled RLS on the users table. All code paths that touch users
(or other RLS-protected tables) before require_tenant_context sets
app.current_account_id must use get_admin_db (BYPASSRLS):
- deps.py: get_current_user and get_current_active_user → get_admin_db
- auth.py: all endpoints → get_admin_db (login, register, refresh, etc.
run before tenant context exists; mutation endpoints also need session
consistency since current_user is in the admin session)
- accounts.py: transfer_ownership, leave_account, delete_account
→ get_admin_db (these mutate current_user directly)
- onboarding.py: dismiss_onboarding → get_admin_db (same reason)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
RLS is now enabled on the users table. The seed script was using the
app-role connection (DATABASE_URL) which has no tenant context at seed
time — all SELECTs return 0 rows and INSERTs are blocked by FORCE RLS.
Falls back to DATABASE_URL if ADMIN_DATABASE_URL is not set (local dev
without roles configured).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both tables have no account_id column — they are globally readable
by all authenticated users and must not have RLS policies.
Also removes the corresponding test cases that assumed these tables
had account_id-based policies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
script_categories is a global lookup table (shared across all tenants).
The account_id column belongs to ScriptTemplate in the same model file,
not ScriptCategory. The Python scan matched the file, not the class.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>