211 lines
No EOL
10 KiB
Markdown
211 lines
No EOL
10 KiB
Markdown
# Code Removal and Consolidation (LOC Reduction)
|
||
|
||
Owner: Engineering
|
||
Document: code-removal-and-consolodation-spec.md
|
||
Revision: 2.0
|
||
Date: 2025-10-20
|
||
|
||
Purpose
|
||
- Reduce lines of code (LOC) in this TS/Vue project (and any Python utilities) without changing behavior.
|
||
- Remove dead/duplicate code, collapse pass-through layers, and slim public APIs.
|
||
|
||
Success metrics
|
||
- [ ] LOC reduced by 10–30% (cloc baseline vs. final).
|
||
- [ ] Test coverage ≥ baseline; typecheck/lint clean.
|
||
- [ ] Bundle size stable or lower.
|
||
- [ ] No regressions in main user flows.
|
||
|
||
Current status (2025-10-20)
|
||
- Interim verification: typecheck and tests passing locally.
|
||
- Consolidations completed in this pass (see checklist 4):
|
||
- Shopping request types centralized in sdk.
|
||
- UIShoppingListItem removed; grouping works on domain items with refs.
|
||
- Meals composable removed; toMealInput moved to decoders; components now import sdk directly.
|
||
- decodeLookup moved to decoders and reused.
|
||
- Baseline metrics captured (cloc, coverage, build size):
|
||
- cloc saved: cloc.baseline.txt
|
||
- coverage saved (v8): coverage/ (see summary in terminal output)
|
||
- build size: dist size ~1.6M
|
||
- ts-prune saved: ts-prune.baseline.txt
|
||
- depcheck saved: depcheck.baseline.json
|
||
|
||
Status update (2025-10-21)
|
||
- Ran ts-prune and depcheck again to guide safe removals.
|
||
- Notes:
|
||
- ts-prune doesn’t analyze .vue SFC imports, so exports used only by SFCs (e.g., dateformats.ago) appear unused; avoid removing those.
|
||
- Completed a safe API shrink: removed unused exports in domain (Maybe, NonNull) and decoders (decodeRecipes) without changing behavior.
|
||
- Removed an unused ref in MyShoppingPage.vue.
|
||
- depcheck flags core-js as unused; given Vue CLI/babel preset may rely on it for polyfills, defer removal for now.
|
||
- depcheck shows some devDependencies as unused but they are required by the Vue CLI toolchain; defer removal.
|
||
- Resolved typecheck errors after domain ref opt-in changes: updated ShoppingListItem.vue to remove person ref usage and guard optional ingredient access; TS + vue-tsc + tests pass.
|
||
- Verified end-to-end: lint PASS, typecheck PASS, vue-tsc PASS, tests PASS (no regressions).
|
||
- Reduced nullability in public SDK APIs where safe: getRecipe/getMeal/markMealConsumed/getCurrentShoppingList now return non-null and throw on errors; updated call sites accordingly.
|
||
- Domain decoders now return non-null and throw on invalid input (decodeRecipe/decodeMeal/decodeMealRecipe/decodeIngredient/decodeShoppingListItem/decodeShoppingList); list decoders return arrays.
|
||
- Lint/typecheck/vue-tsc/tests: all PASS after decoder contract tightening.
|
||
- Aggressive dependency cleanup: removed node-fetch and undici (unused in Node 18+), removed core-js (build and tests still PASS under current browserslist targets), and dropped Vite types from tsconfig. All checks and build PASS post-removal.
|
||
|
||
Latest analysis artifacts (2025-10-21)
|
||
- ts-prune (current): saved to ts-prune.current.txt; notable false-positives include dateformats.ago and units functions used inside SFCs.
|
||
- depcheck (current): saved to depcheck.current.json; flags core-js and several dev deps as unused. These are likely required by Vue CLI/babel/coverage tooling; defer removal pending deeper validation.
|
||
- Follow-up result: Verified removal of core-js, node-fetch, undici did not impact tests/typecheck/build. Retained Vue CLI/Babel/coverage deps.
|
||
|
||
Scope
|
||
- In: TS/Vue app code, tests, configs, scripts; Python utilities if present.
|
||
- Out: New features, architectural rewrites.
|
||
|
||
Baseline and tooling (TS/Vue/Python)
|
||
- Commands:
|
||
- JS/TS LOC: npx cloc . | tee cloc.baseline.txt
|
||
- Lint/typecheck: npm run lint && npm run typecheck
|
||
- Coverage: npm test -- --coverage
|
||
- Unused TS exports: npx ts-prune
|
||
- Unused deps: npx depcheck
|
||
- Search: rg (ripgrep)
|
||
- Bundle size (Vite): npm run build && du -h dist
|
||
- Python (if present): vulture . and coverage run -m pytest
|
||
|
||
Acceptance
|
||
- [ ] Baselines saved (LOC, coverage, bundle size).
|
||
- [ ] CI green on main before starting.
|
||
|
||
Ordered checklist (actionable)
|
||
|
||
1) Baseline snapshot
|
||
- [x] Run cloc; store cloc.baseline.txt.
|
||
- [x] Run tests with coverage; store coverage report. (added dev dep @vitest/coverage-v8)
|
||
- [x] Run npm run build; record dist size.
|
||
- [x] Run ts-prune and depcheck; save outputs.
|
||
|
||
2) Dead code inventory
|
||
- [ ] ts-prune: list unused exports; verify via rg searches.
|
||
- [x] Refreshed ts-prune; review and mark SFC-used exports to avoid accidental removals.
|
||
- [ ] Find unreferenced files:
|
||
rg -l "export default|export const|export function" |
|
||
while read f; do rg -q "(from|import).*$f" -g "!$f" . || echo "$f"; done
|
||
- [ ] depcheck: identify unused deps/scripts.
|
||
- [ ] Python (optional): vulture . for unused code.
|
||
|
||
3) Delete proven dead code
|
||
- [ ] Remove files/symbols with zero references.
|
||
- [ ] Delete tests/mocks for removed code.
|
||
- [ ] Fix imports; run lint, typecheck, tests, build.
|
||
|
||
Acceptance
|
||
- [ ] LOC decreased; CI green.
|
||
|
||
4) Consolidate duplicated types and logic (repo targets)
|
||
- Shopping requests
|
||
- [x] Export PurchaseExisting/PurchaseRefs (or a single request builder) from src/api/sdk.ts.
|
||
- [x] Reuse in src/composables/useShopping.ts; delete local duplicates.
|
||
- [x] Added PurchaseRequest union in SDK to simplify signatures and centralize request typing.
|
||
- UIShoppingListItem mapping
|
||
- [x] Make itemsToGroups/uniqueMeals accept ShoppingListItemWithRefs.
|
||
- [x] Remove UIShoppingListItem and mapItemToUI; update callers.
|
||
- Meals composable
|
||
- [x] Delete src/composables/useMeals.ts OR keep only toMealInput.
|
||
- [x] Move toMealInput to src/domain/decoders.ts if file removed.
|
||
- [x] Update components to import sdk directly for API calls.
|
||
- Common decoder
|
||
- [x] Move decodeLookup<T>() to src/domain/decoders.ts; import in sdk.ts.
|
||
- Component-local types
|
||
- [ ] Replace ad-hoc component types (e.g., MealCard.vue) with domain types.
|
||
- [x] Align ShoppingListItem.vue template/computed logic with domain changes (optional ingredient refs; removed person ref).
|
||
- Unused refs
|
||
- [x] Remove unused reactive refs/vars (e.g., stray person ref in shopping pages if unused).
|
||
|
||
Acceptance
|
||
- [ ] Single source for purchase request types/builders.
|
||
- [ ] One fewer UI-only item shape in shopping flow.
|
||
- [ ] Meals API calls go through sdk; no pass-through wrappers.
|
||
|
||
5) Shrink public API surface
|
||
- [x] Export only used symbols from domain and sdk modules.
|
||
- [ ] Remove unused overloads/params; prefer narrower interfaces.
|
||
- [ ] Update re-exports; fix imports accordingly.
|
||
- [x] Reduce unnecessary null/undefined on public SDK returns (getRecipe/getMeal/markMealConsumed/getCurrentShoppingList).
|
||
- [x] Narrowed visibility of internal helpers/types (listPersons made internal; PurchaseExisting/PurchaseRefs internal, union type exported).
|
||
- [x] Hide internal-only helpers/types: decoders.decodeMealRecipe/decodeShoppingListItem made module-private; units.UnitKey/equivalentUnits/Quantity/Total are no longer exported.
|
||
|
||
Acceptance
|
||
- [ ] ts-prune emits fewer/no unused export warnings.
|
||
|
||
6) Simplify control flow and inline pass-throughs
|
||
- [x] Inline trivial wrappers where applicable (meals composable removed; components call sdk directly).
|
||
- [ ] Prefer guard clauses over nested branches in remaining hotspots (audit pending).
|
||
- [ ] Remove speculative extension points not used.
|
||
- [ ] Replace small class-style modules with plain functions where LOC decreases.
|
||
|
||
Acceptance
|
||
- [ ] Complexity lower in touched files; tests unchanged.
|
||
|
||
7) Test suite consolidation
|
||
- [x] Remove duplicate tests (e.g., .js vs .ts duplicates), fixtures for deleted code.
|
||
- Removed tests/useAlert.test.js (duplicate of tests/useAlert.test.ts).
|
||
- [ ] Ensure assertions are meaningful; avoid testing implementation details.
|
||
- [ ] Keep or improve branch coverage on critical paths.
|
||
|
||
Acceptance
|
||
- [ ] Coverage ≥ baseline; runtime stable or faster.
|
||
|
||
8) Dependency cleanup
|
||
- [ ] Remove unused npm deps (depcheck) and scripts.
|
||
- [x] Refreshed depcheck results saved; plan conservative removals only after confirming toolchain needs.
|
||
- [ ] Prefer stdlib/small helpers over heavy libs where equal.
|
||
- [ ] npm prune && clean install; verify build.
|
||
|
||
Acceptance
|
||
- [ ] Smaller dependency graph; no new vulns; CI green.
|
||
|
||
9) Docs and examples
|
||
- [ ] Update README/ARCHITECTURE and code comments to reflect removals.
|
||
- [ ] Document canonical modules replacing duplicates.
|
||
- [ ] Add migration notes in CHANGELOG if applicable.
|
||
|
||
Acceptance
|
||
- [ ] Docs consistent; onboarding simpler.
|
||
|
||
10) Final verification
|
||
- [ ] Re-run cloc; save cloc.final.txt and LOC delta.
|
||
- [ ] Re-run tests with coverage; compare to baseline.
|
||
- [ ] Re-run build; record bundle size delta.
|
||
- [ ] Sanity test main user flows locally.
|
||
|
||
Acceptance
|
||
- [ ] All metrics at or better than baseline; no regressions.
|
||
|
||
Quick command reference
|
||
- LOC: npx cloc .
|
||
- Typecheck: npm run typecheck
|
||
- Lint: npm run lint
|
||
- Tests + coverage: npm test -- --coverage
|
||
- Unused TS exports: npx ts-prune
|
||
- Unused deps: npx depcheck
|
||
- Search: rg -n "<pattern>"
|
||
- Build + size: npm run build && du -h dist
|
||
|
||
Exit criteria
|
||
- [ ] Target LOC reduction met with stable quality metrics.
|
||
- [ ] Duplicates removed; canonical modules in place.
|
||
- [ ] No pending deprecations awaiting removal.
|
||
|
||
Next actions (clear, actionable)
|
||
1) Capture baselines
|
||
- [x] Run cloc and save cloc.baseline.txt
|
||
- [x] Run tests with coverage and save report summary
|
||
- [x] Build app and note dist size
|
||
- [x] Run ts-prune and depcheck; save outputs
|
||
2) Component type audit
|
||
- [ ] Replace any ad-hoc component types with domain types (scan components/*)
|
||
3) Unused refs/vars cleanup
|
||
- [x] Scan shopping/meals components for unused refs/variables; remove
|
||
4) Shrink public API surface
|
||
- [x] Use ts-prune results to remove unused exports in domain and sdk
|
||
- [ ] Second pass: validate remaining ts-prune hints against .vue usage; prune safely
|
||
- [ ] Consider reducing parseRecipe nullability (throw on parse failures) if UI updated accordingly
|
||
5) Test suite consolidation
|
||
- [x] De-duplicate tests with .js and .ts counterparts (e.g., prefer TypeScript)
|
||
6) Dependency cleanup
|
||
- [x] Remove unused npm deps (depcheck) and scripts (removed core-js, node-fetch, undici, @babel/eslint-parser). Verified tests/typecheck/build PASS.
|
||
7) Final verification
|
||
- [ ] Re-run cloc/tests/build; record deltas vs. baseline; sanity test user flows
|
||
- [x] Interim verification after dep cleanup: tests/typecheck/vue-tsc/lint/build PASS |