From f0ccf313a4afca0b882048499d9209f99865ddcf Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Wed, 15 Apr 2026 12:50:43 +0000 Subject: [PATCH] docs: add lessons 110-111 (RLS backfill audit, axios interceptor pattern) Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 4cfbfce9..c7def325 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -380,6 +380,10 @@ cd backend && pip install httpx && python -m scripts.seed_trees **109. `tree_shares.account_id` must equal `tree.account_id`, not the actor's account:** When creating a `TreeShare`, always use `account_id=tree.account_id` (tree owner's tenant). A super admin in tenant A sharing tenant B's tree must produce a share row in tenant B's RLS context — using `current_user.account_id` instead makes the share invisible to the tree owner after RLS is enforced. +**110. Backfill migrations for `account_id` require a service-code audit:** When a migration adds `account_id` to an existing model via backfill (nullable → backfill → NOT NULL), grep for ALL `ModelClass(` instantiation sites in service code and verify `account_id=` is passed. SQLAlchemy accepts `None` silently with no warning; Phase 4 RLS WITH CHECK only surfaces the problem at runtime as `InsufficientPrivilegeError: new row violates row-level security policy`. Fixed example: `AISessionStep` — all 5 creation sites in `flowpilot_engine.py` were missing `account_id` until April 2026. + +**111. Global Axios interceptor fires before component `.catch()` — fix optional-data endpoints at the source:** The global 5xx handler in `client.ts` fires for ALL non-401 5xx responses, even when a component does `.catch(() => {})`. If an endpoint returns optional UI data (e.g., board filters, PSA config), return `[]` / `{}` on provider failure rather than raising 502. Silencing the error in the component is not enough — the toast appears anyway. See `list_boards` in `integrations.py` for the fixed pattern. + ## RBAC & Permissions - **Role hierarchy:** super_admin > team_admin > engineer > viewer