fiddy/docs/03_REFACTOR_1.md

178 lines
9.7 KiB
Markdown

# Refactor 1 - Domain-First Folder Structure
## Purpose
Improve reviewability and long-term maintainability by moving from mostly flat frontend folders to a domain-first structure with clear ownership and lower coupling.
## Scope
- Frontend structure in `apps/web`
- Instruction consistency updates
- Incremental migration with compatibility shims
- No behavior changes intended during structure migration
## Source Of Truth And Alignment
Use this precedence order when guidance conflicts:
1. `PROJECT_INSTRUCTIONS.md` (repo-level source of truth)
2. `.github/copilot-instructions.md` (architecture and coding rules)
3. `docs/03_REFACTOR_1.md` (this execution tracker and decisions for Refactor 1)
Current refactor-alignment decisions:
- Canonical entry->bucket mutation mechanism: `EntryMutationContext`
- Domain-first target layout: `apps/web/features/<domain>/...` and `apps/web/shared/...`
- Compatibility re-exports removed on 2026-02-12; new imports must use feature-owned paths
## Context Compression Guardrails
- At the start of each new session, read this file and the two source-of-truth docs above.
- Before implementation, re-state active decisions from "Current refactor-alignment decisions".
- Add noteworthy changes to "Notes Log" immediately when discovered.
- Do not introduce a second mechanism for any existing concern without logging a decision here first.
## Phase 0 - Architecture Alignment (single mechanism rule)
- [x] Decide one canonical entry->bucket mutation mechanism (`context` OR `event`)
- [x] Remove the non-canonical mechanism and all references
- [x] Verify there is no duplicate refresh trigger path
- [x] Document chosen mechanism in instructions
## Phase 1 - Instruction and Governance Updates
- [x] Update `.github/copilot-instructions.md`
- [x] Update `PROJECT_INSTRUCTIONS.md`
- [x] Add "single mechanism per concern" rule
- [x] Add file-size/complexity refactor thresholds
- [x] Add dead-path cleanup rule
- [x] Add architecture-consistency checklist to PR expectations
## Phase 2 - Folder Structure Scaffolding
- [x] Create `apps/web/features/`
- [x] Create `apps/web/shared/`
- [x] Define domain folders:
- [x] `features/entries`
- [x] `features/buckets`
- [x] `features/groups`
- [x] `features/tags`
- [x] `features/auth`
- [x] Add minimal README/tree notes in new folders (optional but recommended)
## Phase 3 - Incremental Domain Migration
### Entries + Buckets first (highest coupling)
- [x] Move entries UI/components into `features/entries/components`
- [x] Move buckets UI/components into `features/buckets/components`
- [x] Move domain hooks into `features/<domain>/hooks` (or keep centralized with strict naming, pick one and stay consistent)
- [x] Add temporary compatibility re-exports from old paths
### Remaining domains
- [x] Migrate groups
- [x] Migrate tags
- [x] Migrate auth
## Phase 4 - Import and Boundary Cleanup
- [x] Replace legacy imports with new feature paths
- [x] Ensure container vs presentational separation in large panels
- [x] Remove obsolete compatibility re-exports once import migration is complete
- [x] Remove dead files and stale helpers
## Phase 5 - Validation and Non-Regression
- [x] Run typecheck
- [ ] Run lint
- [x] Run relevant unit tests
- [ ] Smoke-test key UI flows:
- [ ] Entry create/update/delete
- [ ] Bucket usage updates
- [ ] Edit modal discard behavior
- [ ] Group switch behavior
## Phase 6 - Consolidation
- [ ] Publish final structure map in docs
- [ ] Confirm all checklist items closed
- [ ] Capture lessons learned and follow-up actions
---
## Notes Log (append as we discover issues)
- [YYYY-MM-DD] Observation:
- Context:
- Impact:
- Decision:
- Follow-up:
- [YYYY-MM-DD] Alignment Snapshot:
- Active mechanism:
- Active folder strategy:
- Remaining migration risk:
- [2026-02-12] Observation:
- Context: Entry->bucket mutation flow had architectural drift (context + custom event mechanism both present).
- Impact: Higher cognitive load and harder debugging/review for regressions.
- Decision: Standardized on `EntryMutationContext`; removed `entry-mutation-events`.
- Follow-up: Keep scanning for duplicate state propagation patterns during domain migration.
- [2026-02-12] Observation:
- Context: During migration edits, a literal `` `r`n `` sequence was accidentally inserted in `entries-panel.tsx`.
- Impact: Broke readability and could have caused compile/runtime issues.
- Decision: Fixed immediately and added note to keep encoding/text clean during scripted edits.
- Follow-up: Keep post-edit grep checks for suspicious escaped literals.
- [2026-02-12] Observation:
- Context: `npx tsc --noEmit` still fails on pre-existing server/test typing issues unrelated to this refactor slice.
- Impact: Full type-green gating cannot yet be used as a migration stop condition.
- Decision: Track failures as known baseline until addressed in separate debt fixes.
- Follow-up: Re-run typecheck after each migration phase and confirm no net-new errors.
- [2026-02-12] Observation:
- Context: Alignment details were spread across multiple docs and easy to miss after context compression.
- Impact: Higher risk of inconsistent implementation choices between sessions.
- Decision: Added explicit source-of-truth precedence and context-compression guardrails in this file.
- Follow-up: Keep the "Current refactor-alignment decisions" block updated whenever a major choice changes.
- [2026-02-12] Observation:
- Context: Hook migration started with entries and buckets domains.
- Impact: Domain ownership is clearer; old import paths still function via compatibility re-exports.
- Decision: Keep compatibility exports in `apps/web/hooks` until remaining domains are migrated.
- Follow-up: Migrate groups/tags/auth hooks and then remove legacy re-exports.
- [2026-02-12] Observation:
- Context: Migrated auth/groups/tags hooks into `apps/web/features/*/hooks` and converted legacy `apps/web/hooks/use-*.ts` files to compatibility re-exports.
- Impact: Domain ownership is now explicit while existing imports remain functional during the transition.
- Decision: Keep compatibility shims until Phase 4 import cleanup is complete.
- Follow-up: Remove compatibility shims in Phase 4 after all legacy component path re-exports are retired.
- [2026-02-12] Alignment Snapshot:
- Active mechanism: `EntryMutationContext`
- Active folder strategy: domain-first features (`apps/web/features/<domain>/{components,hooks}`)
- Remaining migration risk: leftover compatibility imports and large mixed-responsibility panels.
- [2026-02-12] Observation:
- Context: Replaced the final app-level `@/hooks/use-*` import (`apps/web/components/recurring-entries-panel.tsx`) with a feature hook import.
- Impact: Runtime code now reads hooks from feature-owned locations; `apps/web/hooks/use-*.ts` are compatibility shims only.
- Decision: Keep shims temporarily for migration safety.
- Follow-up: Delete hook shims during Phase 4 once no external references remain.
- [2026-02-12] Observation:
- Context: PowerShell write operations introduced BOM and mojibake artifacts in a few migrated files.
- Impact: Increased review noise and risk of accidental text regressions.
- Decision: Normalized touched files to UTF-8 without BOM and replaced unstable glyphs with ASCII-safe equivalents.
- Follow-up: Prefer no-BOM file writes and run a quick mojibake scan after scripted edits.
- [2026-02-12] Observation:
- Context: Removed obsolete compatibility re-export files under `apps/web/components` and `apps/web/hooks/use-*.ts`.
- Impact: Reduced duplicate paths and eliminated stale import targets.
- Decision: Treat `apps/web/features/*` as the only valid home for migrated component/hook implementations.
- Follow-up: Continue Phase 4 by splitting large panels and removing any remaining dead paths.
- [2026-02-12] Observation:
- Context: `apps/web/components/recurring-entries-panel.tsx` and `apps/web/hooks/use-recurring-entries.ts` had no references and were removed.
- Impact: Fewer dead maintenance paths and clearer active surface area.
- Decision: Keep recurring-entry behavior in server/client domain modules only until a routed UI is reintroduced.
- Follow-up: If recurring UI returns, add it directly under `features/entries/components`.
- [2026-02-12] Observation:
- Context: Lint validation is currently blocked because `npm run lint` calls `next lint` (invalid for current Next setup) and direct `eslint` has no config file.
- Impact: Lint cannot be used yet as a gating signal in this repo state.
- Decision: Keep lint checklist unchecked and treat as tooling debt.
- Follow-up: Add/restore ESLint config and update lint script before enforcing lint gates.
- [2026-02-12] Observation:
- Context: Split `features/entries/components/entries-panel.tsx` by extracting `EntriesList`, `EntriesFilterModal`, and `EntriesDiscardModal`.
- Impact: Smaller container panel with clearer behavior vs presentation boundaries and simpler review scope.
- Decision: Keep stateful orchestration in `EntriesPanel` and move UI-heavy rendering to dedicated presentational components.
- Follow-up: Apply the same split pattern to other oversized panels (notably group settings) in a later pass.
## Known Notes (seed)
- [x] Entry->bucket update mechanism currently shows architectural drift (context and event patterns both present in codebase references).
- [x] `entries-panel.tsx` remains large and should be split during migration for reviewability.
- [ ] Preserve behavior while moving files; avoid functional changes in structure-only PRs.
## Exit Criteria
- Single, documented mutation propagation mechanism in use.
- Domain-first structure in place and imports migrated.
- No stale paths or duplicate mechanisms left.
- Validation checks pass (or known pre-existing failures documented separately).