2757ef3b4f
Recovers and adapts the structural refactoring from overwritten
main merge (b6f89f9) to current dev reality.
Scope:
- Schema extraction into apps/api/src/schemas/
- Docker service split into services/docker/ package
- Instance lifecycle extraction from api/tool_instances.py
- Config profile service extraction from api/config_profiles.py
- Auth dependency refactor (get_current_user)
- Frontend reorganization into features/ dirs + kebab-case naming
Exclusions (already in dev): seeding, defaults, unique constraint,
SSH key mounting, terminal backend, tunnel regex, session auto-numbering.
53 lines
3.2 KiB
Markdown
53 lines
3.2 KiB
Markdown
## Why
|
|
|
|
The `main` branch was previously merged into `dev` (commit `b6f89f9`) bringing a large structural refactoring: schema extraction, service splitting, auth dependency pattern changes, and frontend reorganization. This merge was later overwritten when `dev` was reset to a pre-merge clean state (`51a399c`).
|
|
|
|
We have since forward-ported all behavioral features (built-in tool type seeding, config profile defaults, unique constraints, SSH key mounting, terminal backend, etc.) onto the clean `dev` base. **The codebase now works functionally but lacks the structural cleanliness of the refactoring.**
|
|
|
|
Monolithic files make the backend harder to navigate, test, and maintain:
|
|
- `api/tool_instances.py` is ~3000 lines (mixing HTTP handling with Docker orchestration)
|
|
- `api/config_profiles.py` is ~1000 lines (mixing HTTP handling with business logic)
|
|
- `services/docker.py` is a monolith of ~600 lines covering compose, container, and tunnel logic
|
|
- Frontend API files use inconsistent naming (`tool_types.ts` vs `tool-types.ts`)
|
|
- Frontend components are flat in `components/` instead of organized by feature domain
|
|
|
|
## What Changes
|
|
|
|
Redo the structural refactoring from `b6f89f9`, **adapted to current dev reality**:
|
|
|
|
1. **Backend schema extraction** — Extract Pydantic request/response schemas from API routers into `apps/api/src/schemas/`
|
|
2. **Backend service splits** — Split `services/docker.py` into `services/docker/` package; extract `services/instance_lifecycle.py` and `services/config_profiles.py`
|
|
3. **Auth dependency refactor** — Change from `get_current_user_id` + manual `_get_user` calls to `get_current_user` dependency returning `User` directly
|
|
4. **Frontend reorganization** — Move components into `features/` directories; rename API files to kebab-case
|
|
|
|
**No behavioral changes.** This is a pure structural refactor. All existing endpoints, models, and UI flows remain identical.
|
|
|
|
## Capabilities
|
|
|
|
### New Capabilities
|
|
- None (pure refactor)
|
|
|
|
### Modified Capabilities
|
|
- `backend-structure`: Cleaner module boundaries, smaller files, separated concerns
|
|
- `frontend-structure`: Feature-organized components, consistent file naming
|
|
|
|
## Impact
|
|
|
|
- **Backend**: `apps/api/src/schemas/*` (new), `apps/api/src/services/docker/*` (new package), `apps/api/src/services/instance_lifecycle.py` (new), `apps/api/src/services/config_profiles.py` (new)
|
|
- **Backend**: `apps/api/src/api/*.py` (reduced in size, imports change)
|
|
- **Backend**: `apps/api/src/auth/dependencies.py` (new `get_current_user`)
|
|
- **Frontend**: `apps/web/src/components/features/*` (new directories), `apps/web/src/api/*` (renamed to kebab-case)
|
|
- **Frontend**: `apps/web/src/pages/*` (renamed to `*Page.tsx`)
|
|
|
|
## Exclusions (Already Done)
|
|
|
|
The following behavioral features from `b6f89f9` are **already present** in current `dev` and out of scope for this refactor:
|
|
- Built-in tool type seeding (`src/seeds/builtin_tool_types.py`)
|
|
- Config profile default management (endpoints + `UserConfig` properties)
|
|
- Config profile unique constraint (`uq_config_profiles_user_name`)
|
|
- SSH key mounting in instance lifecycle
|
|
- Terminal backend (WebSocket, session management)
|
|
- Tunnel URL regex fix
|
|
- Session auto-numbering
|
|
- Config profile resolver (`services/config_profile_resolver.py`)
|