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.
7.5 KiB
7.5 KiB
1. Backend Schema Extraction
- 1.1 Create
apps/api/src/schemas/__init__.pywith re-exports - 1.2 Extract
schemas/tool_type.pyfromapi/tool_types.py(ToolTypeCreate, ToolTypeUpdate, validation schemas) - 1.3 Extract
schemas/tool_instance.pyfromapi/tool_instances.py(CreateInstanceRequest, StartInstanceRequest, SessionItemResponse, SessionListResponse) - 1.4 Extract
schemas/config_profile.pyfromapi/config_profiles.py(ConfigProfileCreate, ConfigProfileUpdate, ConfigProfileResponse, DefaultProfilesUpdate, ValidateGitUrlRequest, ValidateGitUrlResponse, GitMountItem, MountItem) - 1.5 Extract
schemas/health.pyfromapi/health.py(DatabaseHealth, DiskHealth, HealthChecks, HealthResponse, DatabaseHealthResponse) - 1.6 Extract
schemas/user.pyfromapi/users.py(UserProfileResponse, UserProfileUpdate) - 1.7 Extract
schemas/user_config.pyfromapi/user_config.py(any request/response schemas) - 1.8 Extract
schemas/project.pyfromapi/projects.py(any request/response schemas) - 1.9 Extract
schemas/ssh_key.pyfromapi/ssh_keys.py(any request/response schemas) - 1.10 Extract
schemas/git_repository.pyfromapi/git_repositories.py(any request/response schemas) - 1.11 Update all API routers to import schemas from
src.schemas.*instead of defining inline - 1.12 Verify
py_compileandruffpass on all schema files
2. Docker Service Package Split
- 2.1 Create
apps/api/src/services/docker/__init__.pywith re-exports for backward compatibility - 2.2 Create
apps/api/src/services/docker/compose.pyfromservices/docker.py:render_compose_template,write_compose_file,_modify_compose_file,_ensure_container_name_in_compose,_ensure_web_bind_address,_ensure_backend_network_in_compose,_sanitize_compose_file,sort_volumes_by_specificity
- 2.3 Create
apps/api/src/services/docker/container.pyfromservices/docker.py:get_container_status,get_container_logs,get_container_id,wait_for_container_running,get_container_ip_on_network,is_container_on_network,connect_container_to_network,get_backend_network_name
- 2.4 Create
apps/api/src/services/docker/config_staging.pyfromservices/docker.py:write_env_file,write_config_files,ensure_instance_directory
- 2.5 Create
apps/api/src/services/docker/tunnel.pyfromservices/tunnel.py:extract_tunnel_url(move tunnel URL regex extraction here),start_tunnel,stop_tunnel,check_tunnel_health,recreate_tunnel
- 2.6 Remove
apps/api/src/services/docker.pyafter verifying all imports updated - 2.7 Update
services/tunnel.pyto delegate URL extraction todocker/tunnel.pyor remove if fully subsumed - 2.8 Update all consumers (
api/tool_instances.py,services/instance_lifecycle.py, etc.) to import fromservices.dockerpackage - 2.9 Verify
py_compileandruffpass
3. Instance Lifecycle Extraction
- 3.1 Create
apps/api/src/services/instance_lifecycle.py:- Extract
create_new_instance,start_existing_instance,stop_existing_instance,restart_existing_instance,delete_existing_instancefromapi/tool_instances.py - Extract helper functions:
_prepare_manifest_instance,_modify_compose_file,_ensure_container_name_in_compose,_ensure_web_bind_address,_ensure_backend_network_in_compose,_sanitize_compose_file,_resolve_git_mounts,_clone_git_repo, etc.
- Extract
- 3.2 Thin
api/tool_instances.pyto ~300 lines:- HTTP routing, auth validation, request parsing
- Delegate to
instance_lifecycle.pyservice functions
- 3.3 Move
sessions_routerfromapi/tool_instances.pytoapi/users.pyor keep as separateapi/sessions.py(align withb6f89f9pattern) - 3.4 Verify all instance endpoints (create, start, stop, restart, delete, list, get) still work
- 3.5 Verify
py_compileandruffpass
4. Config Profile Service Extraction
- 4.1 Create
apps/api/src/services/config_profiles.py:- Extract
get_owned_profile,check_duplicate_name,profile_to_dict,_validate_default_profiles,get_default_profiles,set_default_profiles,get_default_profile_for_tool_type,get_or_create_user_config,list_includes_for_profile,list_mounts_for_profilefromapi/config_profiles.py - Add cycle detection helpers (
_detect_cycle,validate_includes_no_cycle)
- Extract
- 4.2 Thin
api/config_profiles.pyto ~200 lines:- HTTP routing, request parsing
- Delegate to
services/config_profiles.py
- 4.3 Verify all config profile endpoints (CRUD, includes, defaults, preview, validate-git-url) still work
- 4.4 Verify
py_compileandruffpass
5. Auth Dependency Refactor
- 5.1 Add
get_current_usertoapps/api/src/auth/dependencies.py:- Decode session cookie, look up user in DB, return
Usermodel - Raise 401 if missing/invalid session or user not found
- Decode session cookie, look up user in DB, return
- 5.2 Migrate
api/users.pyto useget_current_userinstead ofget_current_user_id+_get_user - 5.3 Migrate
api/tool_instances.pysessions_router to useget_current_userwhere appropriate - 5.4 Migrate other routers incrementally (dashboard, projects, etc.) where the full user object is needed
- 5.5 Keep
get_current_user_idfor endpoints that only need the ID - 5.6 Verify
py_compileandruffpass
6. Frontend Reorganization
- 6.1 Rename API files to kebab-case:
tool_types.ts→tool-types.tsssh_keys.ts→ssh-keys.tsgit_repositories.ts→git-repositories.ts- Update all imports in pages and components
- 6.2 Rename page files to
*Page.tsx:dashboard.tsx→DashboardPage.tsxprojects.tsx→ProjectsPage.tsxsessions.tsx→SessionsPage.tsxsettings.tsx→SettingsPage.tsxssh-keys.tsx→SshKeysPage.tsxterminal.tsx→TerminalPage.tsxtool-workshop.tsx→ToolWorkshopPage.tsxconfig-profiles.tsx→ConfigProfilesPage.tsxgit-repositories.tsx→GitRepositoriesPage.tsxrepo-workspace.tsx→RepoWorkspacePage.tsxworkspaces.tsx→WorkspacesPage.tsxworkspace-detail.tsx→WorkspaceDetailPage.tsxprofile.tsx→ProfilePage.tsxproject-settings.tsx→ProjectSettingsPage.tsxgit-history.tsx→GitHistoryPage.tsx- Update
router.tsximports
- 6.3 Move components into
features/directories:- Create
components/features/git/and move git-related components - Create
components/features/dashboard/and move dashboard components - Create
components/features/project/and move project components - Update all imports
- Create
- 6.4 Verify
npm run typecheckpasses - 6.5 Verify
npm run buildpasses
7. Integration and Verification
- 7.1 Run backend tests:
docker exec hq-api pytest - 7.2 Run backend typecheck:
pyrightor equivalent - 7.3 Run backend lint:
ruff check - 7.4 Run frontend typecheck:
npm run typecheck - 7.5 Run frontend build:
npm run build - 7.6 Run
docker compose up --buildand verify API starts - 7.7 Verify key user flows manually:
- Create a tool instance
- Start/stop an instance
- Create a config profile
- Set a default config profile
- View sessions list
- Open terminal
- 7.8 Verify no 404s or import errors in browser console
8. Documentation
- 8.1 Update
AGENTS.mdor backend README with new module structure - 8.2 Document the
get_current_uservsget_current_user_idpattern for future contributors