## Scope This change is a **pure structural refactoring** of the backend and frontend codebase. No API contracts, database schemas, or user-facing behaviors change. ### In Scope 1. **Schema extraction** (`apps/api/src/schemas/`) - Extract Pydantic models from API routers into dedicated schema modules - Schemas to extract: `tool_type`, `tool_instance`, `config_profile`, `user`, `user_config`, `project`, `ssh_key`, `git_repository`, `health` - Each API router imports schemas from `src.schemas.*` instead of defining inline 2. **Docker service package** (`apps/api/src/services/docker/`) - Split `services/docker.py` monolith into focused modules: - `docker/compose.py` — compose file generation, modification, validation - `docker/container.py` — container lifecycle (status, IP, network, logs) - `docker/config_staging.py` — config file staging for instances - `docker/tunnel.py` — tunnel URL extraction (moved from `services/tunnel.py`) - `docker/__init__.py` — re-exports for backward compatibility - Update all imports across the backend 3. **Instance lifecycle extraction** (`apps/api/src/services/instance_lifecycle.py`) - Extract instance creation, start, stop, restart, and deletion logic from `api/tool_instances.py` - The API router becomes thin: validates auth, calls service, returns response - Service functions are async and receive `AsyncSession`, models, and raw parameters 4. **Config profile service extraction** (`apps/api/src/services/config_profiles.py`) - Extract business logic from `api/config_profiles.py`: CRUD helpers, validation, default profile management - API router delegates to service functions 5. **Auth dependency refactor** (`apps/api/src/auth/dependencies.py`) - Add `get_current_user` dependency that returns a `User` model directly - Update API routers to use `user: User = Depends(get_current_user)` where the full user object is needed - Keep `get_current_user_id` for endpoints that only need the ID 6. **Frontend reorganization** - Move components into `features/` directories by domain: - `features/git/` — CommitDialog, FileBrowser, FileEditor, GitToolbar, MergeDialog, WorkspaceSidebar - `features/dashboard/` — ActiveSessionsList, DashboardSummary, ProjectsSection, QuickCreateForm, RecentSessionsSection - `features/project/` — RepositoriesSettingsTab - `features/tool-workshop/` — ToolTypesTab (already exists) - Rename API files from snake_case to kebab-case: - `tool_types.ts` → `tool-types.ts` - `ssh_keys.ts` → `ssh-keys.ts` - `git_repositories.ts` → `git-repositories.ts` - Rename page files to `*Page.tsx`: - `dashboard.tsx` → `DashboardPage.tsx` - `projects.tsx` → `ProjectsPage.tsx` - etc. ### Out of Scope - Any new features or behavioral changes - Database schema changes (no migrations) - API contract changes (same endpoints, same request/response shapes) - Frontend UI behavior changes (same components, same interactions) - Removing or modifying the `ConfigProfileInclude` model (already exists as a relation) - Extracting `ConfigMount` into a separate model (current dev uses JSON arrays; this is a schema decision, not a refactor) - Changes to `tool_definition_manifest` or `workspace` models ## Acceptance Criteria 1. All existing tests pass without modification (behavior unchanged) 2. All existing API endpoints return identical responses for identical requests 3. All frontend pages render identically 4. `docker compose up` starts successfully 5. Backend `ruff check` passes 6. Frontend `npm run typecheck` passes 7. Frontend `npm run build` passes 8. File sizes are reduced: no API router > 500 lines, no service > 400 lines ## Preconditions - Current `dev` branch is stable and all behavioral forward-ports are complete - All legacy `ToolConfig`/`ConfigFolder` code has been removed - Database migrations are at a single head