Commit cb28c16
committed
refactor(api): split api/workspaces.py 1,407 → 142 LOC into services/ (closes #25)
The eval flagged api/workspaces.py as a 1,400+ LOC monolith co-locating
database access, dict transformation, workspace resolution, project
assignment heuristics, CLI session handling, and HTTP response formatting
in one file (Section 5.2). The get_workspace_tabs handler alone spanned
~450 lines; _determine_project_for_conversation was 120+ lines of
cascading fallbacks. Helpers (_read_json_file) were duplicated across
api/workspaces.py and api/composers.py. This refactor extracts the file
into focused service modules and leaves three thin route handlers.
Behaviour-preserving: same JSON response shapes, same URL routes, same
sort orders. All 178 existing tests pass without modification; a small
back-compat shim re-exports _infer_invalid_workspace_aliases,
_determine_project_for_conversation, and _infer_workspace_name_from_context
from api/workspaces so existing test imports continue to work
(production callers should import from services/ directly).
Extraction layout (matches the order in #25's spec for minimal merge-
conflict risk against parallel work):
utils/workspace_descriptor.py — pure helpers; one _read_json_file
consolidating the duplicate copies
from api/workspaces.py and
api/composers.py.
services/workspace_db.py — _open_global_db, _collect_workspace
_entries, _build_composer_id_to_
workspace_id, _collect_invalid_
workspace_ids.
services/workspace_resolver.py — _determine_project_for_conversation,
_infer_invalid_workspace_aliases,
_create_project_name_to_workspace_id
_map, _create_workspace_path_to_id_
map, _get_workspace_display_name,
_infer_workspace_name_from_context,
_get_project_from_file_path.
services/cli_tabs.py — _get_cli_workspace_tabs (the
CLI-session branch of the tabs route).
services/workspace_listing.py — list_workspace_projects (the entire
body of GET /api/workspaces).
services/workspace_tabs.py — assemble_workspace_tabs (the entire
body of GET /api/workspaces/<id>/tabs
for non-CLI workspaces).
api/workspaces.py is now 142 LOC: three route handlers that parse the
request, hand off to the service layer, and JSONify the result.
Verified locally:
- 178 unit tests pass without modification.
- mypy clean on the new modules (no new errors on touched files).
- Live smoke on real Cursor workspaceStorage:
* GET / -> HTTP 200
* GET /api/workspaces -> HTTP 200, 2 workspaces
* GET /api/workspaces/global/tabs -> HTTP 200, 5 tabs
* GET /api/search?q=test -> HTTP 200, 7 results
No exceptions, no behaviour change observed.1 parent 95d3140 commit cb28c16
9 files changed
Lines changed: 1335 additions & 1289 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | 21 | | |
26 | 22 | | |
27 | 23 | | |
| |||
0 commit comments