# SDD Proposal: Repository Restructuring and Modularization ## Overview The Headquarter codebase has grown organically over ~6 months of active development. What began as a lean full-stack application has accumulated structural debt: monolithic files, mixed concerns, duplicated types, inconsistent naming, and a single 2,844-line stylesheet. This proposal plans a phased refactoring to establish clear module boundaries, enforce a ~200-line-per-file target (hard limit 300), and standardize naming conventions across the entire repo. **Motivation:** - Files over 400 lines are difficult to reason about, test, and review - Pages mix data fetching, state management, form logic, and UI rendering - A single stylesheet makes theme changes risky and component isolation impossible - Backend routers contain business logic that should live in services - Duplicate types (`Session`, `ToolInstance`) create drift between API and state layers - Naming inconsistencies make file discovery harder for new contributors **Desired outcome:** A codebase where every file has a single, obvious responsibility; imports follow predictable patterns; and a new developer can locate any functionality within 30 seconds. --- ## Scope ### In Scope 1. **Frontend type consolidation** - Move all domain types from `api/*.ts` into `types/` with clear domain grouping - Remove duplication between `api/sessions.ts` and `state/sessions.tsx` - Standardize type naming and export patterns 2. **Frontend page decomposition** - Extract inline components (e.g., `FileBrowser` from `repo-workspace.tsx`) - Split "list + form + dialog" pages into container + presentational components - Extract reusable loading/error/retry UI patterns into shared components 3. **Frontend style system restructure** - Split `styles.css` into: tokens, global, layout, components, pages, syntax-highlight - Remove unused CSS classes (verified by grep/build) - Keep visual output pixel-identical (no design changes) 4. **Frontend component organization** - Group domain-specific components under `components/features/{domain}/` - Keep generic UI primitives at `components/ui/` - Rename page component files to match exported names (e.g., `git-history.tsx` → `GitHistoryPage.tsx` or rename component) 5. **Backend router decomposition** - Extract business logic from `tool_instances.py`, `git_repositories.py`, `config_profiles.py` - Move helper functions (`_get_user`, `_get_owned_project`) to shared dependencies - Split large routers by sub-resource (CRUD vs. operations vs. files) 6. **Backend service decomposition** - Split `services/docker.py` into compose, container, tunnel, config-staging modules - Ensure no service module exceeds 300 lines 7. **Backend seed data extraction** - Move hardcoded seed data from `main.py` to `seeds/builtin_tool_types.py` 8. **Naming convention standardization** - Frontend React components: PascalCase files matching component name - Frontend hooks: camelCase (`useTheme.ts`) - Frontend utilities/api: kebab-case - Backend modules: snake_case - Document conventions in `docs/development/naming.md` ### Out of Scope (Non-Goals) 1. **No behavior changes** — All user-facing functionality stays identical; this is pure restructuring 2. **No new features** — We are not adding capabilities, only reorganizing existing ones 3. **No technology swaps** — Keeping React 18, Vite, FastAPI, SQLAlchemy, xterm as-is 4. **No test rewrites** — Existing tests should pass after path updates; we are not changing test frameworks or strategies 5. **No database migrations** — Model files stay in place; only code organization changes 6. **No build system changes** — Keep existing vite.config.ts, tsconfig.json, pyproject.toml 7. **No CI/CD changes** — Existing quality gates (typecheck, lint, pytest) must continue to pass 8. **No documentation overhaul** — We will add a naming conventions doc, but not rewrite all docs --- ## Risks and Mitigations | Risk | Likelihood | Impact | Mitigation | |------|-----------|--------|------------| | Import path breakage | High | Medium | Use IDE/automated refactor for import rewrites; run full typecheck after every phase | | CSS regression | Medium | High | Split styles incrementally; verify each page visually after each CSS file split; keep original styles.css as backup during migration | | Lost git history | Medium | Low | Use `git mv` for file moves; avoid copy-delete patterns | | Test failures from path changes | High | Low | Update test imports alongside source imports; run test suite after each phase | | Scope creep | Medium | High | Strict non-goals list; pause between phases; require explicit approval to expand scope | | Merge conflicts with active development | Medium | High | Coordinate timing; prefer short phases with quick PRs; avoid refactoring files with active feature branches | | Reviewer fatigue | Medium | Medium | Auto-forecast at 400 lines; split into chained PRs; each PR limited to one concern | | Accidental behavior change | Low | High | Pure cut-paste with no logic changes; reviewer checks for any non-import diffs | --- ## High-Level Approach We will execute in **5 phases**, each producing an independent, reviewable PR: ### Phase 1: Safe Foundations (est. +200/-150 lines, 1 PR) - Consolidate types: create `types/index.ts` with all domain types - Update imports in all consumers - Extract `FileBrowser` from `repo-workspace.tsx` - Move seed data from `main.py` to `seeds/` - Extract shared auth dependencies ### Phase 2: Style System Restructure (est. +50/-2,700 lines, 1 PR) - Split `styles.css` into 6 files under `styles/` - Update `main.tsx` to import new style entry point - Verify no visual regressions ### Phase 3: Backend Router Decomposition (est. +800/-1,500 lines, 2-3 chained PRs) - PR 3a: Extract shared dependencies and helpers - PR 3b: Split `tool_instances.py` → router + services - PR 3c: Split `git_repositories.py` and `config_profiles.py` ### Phase 4: Frontend Page Decomposition (est. +600/-1,200 lines, 2-3 chained PRs) - PR 4a: Split `tool-workshop.tsx` into feature components - PR 4b: Split `sessions.tsx`, `dashboard.tsx`, `repo-workspace.tsx` - PR 4c: Rename page components and files for consistency ### Phase 5: Testing & Polish (est. +300/-50 lines, 1 PR) - Add tests for extracted components - Document naming conventions - Final cleanup: remove dead code, unused exports **Total estimated churn:** ~2,000 lines added, ~5,700 lines removed (net: files become smaller and more numerous) --- ## Acceptance Criteria ### Overall - [ ] No file in `src/` exceeds 300 lines (exceptions: auto-generated migration files) - [ ] `tsc --noEmit` passes with zero errors - [ ] `eslint` passes with zero warnings - [ ] All existing tests pass (frontend: vitest; backend: pytest) - [ ] No visual regressions in key pages (verified manually or via existing e2e) - [ ] No behavior changes — all user flows work identically ### Per Phase - [ ] Phase 1: All types centralized; zero duplicated type definitions; seed data extracted - [ ] Phase 2: `styles.css` deleted; styles split by concern; no visual regressions - [ ] Phase 3: No router exceeds 300 lines; business logic lives in services; no inline Docker/git ops in routers - [ ] Phase 4: No page exceeds 300 lines; inline components extracted; naming consistent - [ ] Phase 5: Naming convention doc exists; extracted components have basic tests --- ## Review Workload Forecast | Phase | Est. Changed Lines | PR Strategy | |-------|-------------------|-------------| | Phase 1 | ~350 | Single PR | | Phase 2 | ~2,750 | Single PR (mostly CSS reorganization) | | Phase 3a | ~400 | Single PR | | Phase 3b | ~800 | Single PR | | Phase 3c | ~700 | Single PR | | Phase 4a | ~500 | Single PR | | Phase 4b | ~600 | Single PR | | Phase 4c | ~350 | Single PR | | Phase 5 | ~350 | Single PR | **All PRs are under the 400-line review budget.** Phases 2 and 3/4 may require careful review focus due to file move volume, but each PR stays within the limit. --- ## Open Questions 1. Should we adopt CSS Modules for component styles, or keep global CSS with BEM-like naming? 2. Should backend routers be versioned under `api/v1/` now, or keep flat `api/` structure? 3. Should extracted frontend feature components live in `components/features/` or `features/` at root? 4. Do we want to introduce barrel exports (`index.ts`) for each domain module? 5. Should we run this refactor in a feature branch, or merge each phase to main immediately? --- *Proposal prepared for SDD review. Next phase: Spec writing with detailed requirements and scenarios.*