From c0626e061eda24e906d391930927812ad0d4e751 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Sat, 11 Apr 2026 20:22:20 -0400 Subject: [PATCH] fix: remove account_id injection from nested POST handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Child objects in the nested endpoint inherit account context from their parent via the FK relationship and do not carry their own account_id column (e.g. event_badge, journal_entry). Injecting account_id into data_to_insert would cause INSERT failures for any child whose table has no account_id column but whose model has the field (from the view). The original code set account_id in obj_data before model instantiation, where the root_validator immediately stripped it — a harmless no-op. The previous commit turned that dead line into a live injection by moving it after serialization, which would break journal_entry creates on non-bypass auth. Removed entirely. Co-Authored-By: Claude Sonnet 4.6 --- app/routers/api_crud_v3_nested.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/routers/api_crud_v3_nested.py b/app/routers/api_crud_v3_nested.py index 82c2e2b..2c97633 100644 --- a/app/routers/api_crud_v3_nested.py +++ b/app/routers/api_crud_v3_nested.py @@ -330,18 +330,11 @@ async def post_child_obj( # (Matches the flat V3 POST pattern in api_crud_v3.py.) sanitize_payload(data_to_insert, input_model, ignore_extra=x_ae_ignore_extra_fields) - # Enforce account ownership AFTER sanitize_payload so the integer account_id goes - # straight to the DB without conflicting with Vision ID string constraints in the model. - # Guard: skip if the model explicitly excludes account_id from DB writes (e.g. event_badge, - # event_device — the column does not exist in those tables). - if not account.super and account.auth_method != 'bypass' and account.account_id: - if 'account_id' in input_model.__fields__: - excluded = getattr(input_model, 'fields_to_exclude_from_db', []) - if 'account_id' not in excluded: - data_to_insert['account_id'] = account.account_id - # Re-inject parent FK last — overrides anything sanitize_payload or the model may have # set — ensuring the child is always linked to the correct parent. + # Note: account_id is intentionally NOT injected here. Child objects in the nested + # endpoint inherit account context from their parent via the FK relationship; they do + # not carry their own account_id column (e.g. event_badge, journal_entry). data_to_insert[f'{parent_obj_type}_id'] = resolved_parent_id if sql_insert_result := sql_insert(data=data_to_insert, table_name=table_name_insert):