Split the adventures router into a package
`backend/app/routers/adventures.py` held 2353 lines and 35 endpoints. It is now a package of 14 modules, the largest 443 lines. The split moves text rather than rewriting it. An AST comparison against the old file confirms all 86 definitions are identical, and the OpenAPI schema still lists the same 35 operations. Names a test replaces now live in `turns.py` only, and other modules reach them as `turns.<name>`. Rebinding a re-exported alias changes the alias and leaves every caller reading the original, so the package root does not re-export them. A patch aimed at the old target raises `AttributeError` instead of passing while doing nothing. Tests and the fixtures in `backend/tools/` say `adventures.turns.<name>`. The same rule keeps the turn lock working. One module owns `_active_turns`, so one lock guards one set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Dix4oGV3njgWRdu7P9t6r
This commit is contained in:
co-authored by
Claude Opus 5
parent
32cd7c1077
commit
2fa812c056
+40
-1
@@ -18,7 +18,7 @@ stage before it is green.
|
||||
| Stage | Work | Status | Landed |
|
||||
|---|---|---|---|
|
||||
| 0 | Hygiene: worktrees, branches, undocumented settings | done, except the branch deletion | 2026-08-29 |
|
||||
| 1 | Split the four largest files | not started | |
|
||||
| 1 | Split the four largest files | tests share one setup; the router is a package; three files left | |
|
||||
| 2 | Remove duplication | not started | |
|
||||
| 3 | SP8: drop the legacy columns | not started | |
|
||||
| 4 | Documentation | not started | |
|
||||
@@ -225,6 +225,45 @@ exactly one module, `turns.py`, and every other module must import the module an
|
||||
reach through it. If two modules import the set by value, the lock guards two
|
||||
different sets and the turn lock stops working.
|
||||
|
||||
### What the router split actually did, 2026-08-29
|
||||
|
||||
`backend/app/routers/adventures.py` is now a package of 14 modules. The largest
|
||||
is `turns.py` at 443 lines. Four modules exist that the table above does not
|
||||
list, because the plan's eleven still mixed unrelated work:
|
||||
|
||||
| Extra module | Why it exists |
|
||||
|---|---|
|
||||
| `deps.py` | Holds the `APIRouter` and the ownership check. It imports nothing else in the package, so every endpoint module can import the router without importing its siblings. |
|
||||
| `scenario_text.py` | Copying a scenario's text and cards has two callers, `crud.create_adventure` and `refresh`. Leaving it in either one made the other import an endpoint module. |
|
||||
| `nodes.py` | Story-tree navigation that four modules use: `last_action`, `next_index`, `next_depth`, `stand_on`, `db_tip`, `delete_turn`. |
|
||||
| `actions.py` | The three action endpoints. They page and delete rather than play a turn, so they do not belong in `crud.py`. |
|
||||
|
||||
Two decisions differ from the plan above.
|
||||
|
||||
**The package root does not re-export `acquire_turn_lock` or `_active_turns`.**
|
||||
The plan said to keep them importable, but that makes a broken patch look like a
|
||||
working one. Rebinding `adventures.generate_turn` changes the alias and leaves
|
||||
every caller reading the original, and the test still passes. Leaving those names
|
||||
off the package root raises `AttributeError` instead. Eighteen test call sites and
|
||||
four in `backend/tools/` now say `adventures.turns.<name>`. The package root still
|
||||
re-exports the pure helpers, so `adventures.ACTION_PAGE`, `adventures.undo_turn`,
|
||||
and `chat.py`'s `from .adventures import SSE_HEADERS, sse` are unchanged.
|
||||
|
||||
**`world_delta_of` lives in `turns.py`.** It reads as a world-state helper and sat
|
||||
beside the world-state endpoints, but `_generate_turn` is its only caller.
|
||||
|
||||
`_active_turns` behaved as the plan warned. Every module reaches it as
|
||||
`turns._active_turns`, and a check confirms the four modules see one set object
|
||||
and one lock.
|
||||
|
||||
One test coupled to the router for an unrelated module: it called
|
||||
`adventures.worldstate.instantiate`. It imports `app.worldstate` directly now.
|
||||
|
||||
The split moved text rather than retyping it. An AST comparison against the
|
||||
pre-split file confirms all 86 definitions are identical, once the `turns.`
|
||||
prefix is normalized away. The 549 tests pass, and the OpenAPI schema still lists
|
||||
the same 35 operations.
|
||||
|
||||
### `worldstate/engine.py` becomes a package
|
||||
|
||||
Split `backend/app/worldstate/engine.py` into four modules under
|
||||
|
||||
Reference in New Issue
Block a user