Skip to content

Extract Behavior CRUD out of the crud/__init__.py monolith - #2455

Merged
akwasigroch merged 1 commit into
mainfrom
refactor/extract-behavior-crud
Aug 12, 2026
Merged

Extract Behavior CRUD out of the crud/__init__.py monolith#2455
akwasigroch merged 1 commit into
mainfrom
refactor/extract-behavior-crud

Conversation

@akwasigroch

@akwasigroch akwasigroch commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Purpose

crud/__init__.py is a 1946-line monolith that the codebase is splitting one entity at a time, following #2411, #2412, #2438, #2439, #2441, #2442, #2449, #2450 and #2451. This takes the Behavior block out. Per apps/backend/AGENTS.md the package only shrinks from here — nothing new goes back into __init__.py.

What Changed

  • Moved get_behavior, get_behaviors, get_behaviors_detail, create_behavior, update_behavior and delete_behavior into a new crud/behavior.py (141 lines). _BEHAVIOR_RELATED_FIELDS moved with them; nothing else in __init__.py used it.
  • crud/__init__.py drops 118 lines.
  • Nothing is re-exported, matching the earlier splits. All 13 call sites now use from rhesis.backend.app.crud import behavior as behavior_crud.
  • Nothing dropped — all six functions have live callers.
  • get_behavior had a redundant function-local QueryBuilder import; it is now module-level, matching crud/source.py. _check_and_raise_if_deleted stays local, also matching source.py.
  • The module docstring records why get_behaviors_detail exists: get_behaviors is a plain get_items with no eager loading, so the list endpoint calls the detail variant instead. That variant runs two queries — IDs first with filter/sort/limit, then an eager load scoped to those IDs — and re-applies the sort in Python because WHERE id IN (...) does not preserve order. Dropping that re-sort returns the right page in the wrong order with no error.

Additional Context

Testing

Pure move — behaviour is unchanged, so the existing suite is the check.

cd apps/backend
uv run pytest ../../tests/backend/routes/test_behavior.py ../../tests/backend/utils/test_query_builder_load.py ../../tests/backend/services/test_test_generation_pipeline.py ../../tests/backend/crud/
# 166 passed, 2 skipped, 1 xfailed

uv run pytest ../../tests/backend/services ../../tests/backend/utils ../../tests/backend/security ../../tests/backend/auth
# 3518 passed, 4 skipped, 1 xfailed

Ruff clean on all 7 touched files. A repo-wide grep for crud.get_behavior, crud.get_behaviors, crud.get_behaviors_detail, crud.create_behavior, crud.update_behavior and crud.delete_behavior returns nothing.

Worth a reviewer's eye: tests/backend/services/test_test_generation_pipeline.py patched the module-level name ...test_generation_pipeline.crud and set crud.get_behaviors.return_value. After the move that patch still applies cleanly but stubs nothing, so the tests would have reached a real DB call through a MagicMock session and passed for the wrong reason. Retargeted to behavior_crud.

Move the six behavior functions out of crud/__init__.py into
crud/behavior.py, following the split already done for tag, task, source
and others. _BEHAVIOR_RELATED_FIELDS moves with them -- nothing else in
__init__.py referenced it. Consumers import the module directly; nothing
is re-exported.

Nothing was dropped: all six functions still have callers.

test_test_generation_pipeline.py patched the module-level `crud` name in
test_generation_pipeline to stub get_behaviors, so those patch targets now
point at `behavior_crud`.

@peqy peqy Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Clean extraction into crud/behavior.py and the call sites/tests were updated correctly (especially the patch() retargeting). Ship it.

@akwasigroch
akwasigroch merged commit 7c21a21 into main Aug 12, 2026
16 of 17 checks passed
@akwasigroch
akwasigroch deleted the refactor/extract-behavior-crud branch August 12, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant