Skip to content

Code audit cleanup: dead code, drift fix, and router/file decomposition#251

Merged
d3mocide merged 9 commits into
mainfrom
claude/bold-brahmagupta-0jolwe
Jun 25, 2026
Merged

Code audit cleanup: dead code, drift fix, and router/file decomposition#251
d3mocide merged 9 commits into
mainfrom
claude/bold-brahmagupta-0jolwe

Conversation

@d3mocide

@d3mocide d3mocide commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Code Audit Cleanup

Full-stack audit (dead code, monolithic files, broken chains). Findings and rationale tracked in docs/CODE_AUDIT.md. Worked in priority order.

Items

  • 1. Delete dead PhotoTab.tsx — orphaned component, never imported (photo logging lives in ScanTab).
  • 2. De-dupe gramsForUnit — was copy-pasted across IngredientBuilder, ScanTab, NutritionCalculatorCard and had drifted (calculator passed serving_size_g || undefined, others raw → divergent gram math). Centralized into lib/portions.ts as gramsForFoodUnit; added tests.
  • 3. Split api/goals.py — grab-bag router hosting goals + preferences + 8 /settings/* routes. Moved all /settings/* handlers into new api/user_settings.py. Paths unchanged.
  • 4. Decompose routes/health.tsx (1509→54 LOC) + routes/meals.tsx (1506→91 LOC) into components/health/ and components/meals/ folders, following the existing today//settings/ pattern. Pure code motion.
  • 5. Extract get_today (325→140 LOC) into a new services/today_metrics.py (compute_daily_totals, build_recent_meals, fetch_biometrics_latest, compute_streak). DB calls stay sequential on the single session.
  • 6. Shared ui/Field primitive — intentionally skipped. The Field/ModalField/SliderField variants are distinct components sharing only the .eyebrow label idiom (already a shared CSS class); a unified primitive would be a prop-bloated kitchen-sink. Rationale in the tracking doc.

Verification

  • Frontend: pnpm type-check clean, pnpm lint 0 errors (2 pre-existing HydrationCard warnings, untouched), pnpm test 119 passing (incl. 5 new).
  • Backend: mypy luma --ignore-missing-imports clean across all 78 modules.

Note: backend pytest requires a TimescaleDB instance not available in this environment; backend changes #3 and #5 are verbatim code moves verified by mypy + import/compile checks. Route paths and handler logic are unchanged.

🤖 Generated with Claude Code

claude added 9 commits June 24, 2026 22:17
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
PhotoTab was orphaned — never imported. Photo logging lives in ScanTab
via its barcode/photo scanMode toggle. LogSheet only wires quick/voice/
search/scan tabs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
gramsForUnit was copy-pasted in IngredientBuilder, ScanTab, and
NutritionCalculatorCard, and had drifted (the calculator copy passed
serving_size_g || undefined while the others passed serving_size_g raw),
risking divergent gram calculations between the scanner and calculator.

Extract a single gramsForFoodUnit(food, unit, qty) into portions.ts with
a minimal FoodForPortion structural type, normalizing the serving-size
handling via ?? undefined. Add tests covering the hm: household-measure
path and null serving_size_g.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
goals.py was a grab-bag hosting goals, dietary preferences, and 8
unrelated /settings/* routes (measurements, AI pricing/config/providers/
usage, HAE/LLM metrics, HAE import token). Move all /settings/* handlers
into a new api/user_settings.py router (named to avoid clashing with the
config 'settings' symbol) and register it at the same API prefix.

Route paths are unchanged — purely a code-organization split. goals.py
now owns only goals + preferences. mypy clean across all 77 modules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
health.tsx was a 1509-line monolith holding 20 components. Split into a
components/health/ folder mirroring the existing today/ and settings/
patterns:
- types.ts: shared interfaces + supplement field/preset constants
- shared.tsx: EmptyState, ActivePill, ModalField
- MedicationsTab.tsx, SupplementsTab.tsx, InteractionsTab.tsx, SimulationsTab.tsx

The route file drops to 54 lines (tab bar + orchestration). No behavior
change — pure code motion. type-check/lint/test all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
meals.tsx was a 1506-line monolith. Each of its three in-file tabs is
self-contained (no cross-tab helper sharing), so split cleanly into
components/meals/{FoodsTab,JournalTab,CalculatorTab}.tsx. The route file
drops to 91 lines (tab bar + orchestration; Plan/Recipes tabs already
delegate to their own routes). No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
get_today was a single ~325-line handler. Move its self-contained pieces
into luma/services/today_metrics.py:
- compute_daily_totals: meal + active-supplement nutrient totals
- build_recent_meals: recent-meal card shaping (pure)
- fetch_biometrics_latest: point-in-time + cumulative activity
- compute_streak: the ~90-line on-track streak grading

The handler drops to ~140 lines and reads as an orchestrator. Logic is
unchanged (verbatim moves); all DB calls remain sequential on the single
session per the AsyncSession concurrency rule. mypy clean across 78 modules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
The Field/ModalField/SliderField variants are distinct components sharing
only the .eyebrow label idiom (already a shared CSS class). A unified
primitive would be a prop-bloated kitchen-sink that reads worse than the
local components, so this item is intentionally left as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
The water-preset inputs are editable local state synced from server data.
Replace the syncing useEffect (which tripped react-hooks/set-state-in-effect
and exhaustive-deps) with React's 'adjust state during render when a key
changes' pattern, keyed on the serialized presets + unit system. Seed the
tracked key with null so the first render with already-cached data still
syncs. Frontend lint is now warning-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHx71BawqCkwRmP189JJAT
@d3mocide d3mocide marked this pull request as ready for review June 25, 2026 02:14
@d3mocide d3mocide merged commit 0f9ea0a into main Jun 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants