What problem does this solve?
Two modules have grown into "god-modules" that are hard to navigate and review, and they push against the file-size guidance in CLAUDE.md ("Prefer smaller, focused files… split it into logical pieces rather than continuing to add to it"):
backend/routers/campaigns/core.py — ~18.5 KB of endpoint handlers covering many distinct concerns in one file. (The campaigns package already demonstrates the preferred pattern: focused modules like sessions.py, schedule.py, uploads.py, guests.py, resources.py, categories.py, wiki.py. core.py is the leftover catch-all.)
frontend/src/views/SystemDetailView.jsx — ~1,068 LOC in a single view component, mixing data fetching, multiple sub-sections, and UI state.
What would you like to see?
Decompose both by concern, with no behavior change — pure refactors that keep the public API and rendered UI identical.
routers/campaigns/core.py
- Identify the distinct concerns still living in
core.py (e.g. campaign CRUD, membership/roles, settings, anything that doesn't already belong to a focused sibling module) and split them into focused modules following the established package shape (__init__.py registers routes via add_api_route; handlers live in core.py/topic modules; schemas in _schemas.py; shared helpers in _helpers.py).
- Keep route registration centralized in
__init__.py so the external API surface is unchanged.
views/SystemDetailView.jsx
- Extract logical sections into child components (one component per file, per the repo's one-component-per-file rule), e.g. header/banner, the book/category listing, edit controls, and any modals.
- Keep shared media/gallery UI in
components/media/ if applicable.
- Lift shared state cleanly so children receive props/handlers rather than duplicating fetches.
Testing
- This is a refactor: existing backend (
backend/tests/) and frontend (*.test.jsx) suites must continue to pass unchanged.
- Per the coverage gate, every new/touched file must stay ≥80% line coverage — extracted components/modules may need their own focused tests.
Docs
- No user-facing changes expected.
docs/api.md should only change if a route path moves (it shouldn't — registration stays in __init__.py).
Notes
These two decompositions are independent and could ship as separate PRs (backend split, frontend split) under this tracking issue.
What problem does this solve?
Two modules have grown into "god-modules" that are hard to navigate and review, and they push against the file-size guidance in CLAUDE.md ("Prefer smaller, focused files… split it into logical pieces rather than continuing to add to it"):
backend/routers/campaigns/core.py— ~18.5 KB of endpoint handlers covering many distinct concerns in one file. (The campaigns package already demonstrates the preferred pattern: focused modules likesessions.py,schedule.py,uploads.py,guests.py,resources.py,categories.py,wiki.py.core.pyis the leftover catch-all.)frontend/src/views/SystemDetailView.jsx— ~1,068 LOC in a single view component, mixing data fetching, multiple sub-sections, and UI state.What would you like to see?
Decompose both by concern, with no behavior change — pure refactors that keep the public API and rendered UI identical.
routers/campaigns/core.pycore.py(e.g. campaign CRUD, membership/roles, settings, anything that doesn't already belong to a focused sibling module) and split them into focused modules following the established package shape (__init__.pyregisters routes viaadd_api_route; handlers live incore.py/topic modules; schemas in_schemas.py; shared helpers in_helpers.py).__init__.pyso the external API surface is unchanged.views/SystemDetailView.jsxcomponents/media/if applicable.Testing
backend/tests/) and frontend (*.test.jsx) suites must continue to pass unchanged.Docs
docs/api.mdshould only change if a route path moves (it shouldn't — registration stays in__init__.py).Notes
These two decompositions are independent and could ship as separate PRs (backend split, frontend split) under this tracking issue.