Skip to content

v2.3.0 Implementation Plan: coordinated delivery of all milestone issues #279

@hessius

Description

@hessius

Purpose

This issue is the implementation guide for v2.3.0. It defines the exact order work should proceed across the milestone issues, which components are shared, what to build first to avoid rework, and how features compose together.

v2.3.0 focuses on shot analysis intelligence, beginner guidance, and run experience — transforming MeticAI from a profile generation tool into an iterative brewing coach. It builds directly on v2.2.0's profile editing (#257), shot analysis view (#259), catalogue management (#192), and temporary profile infrastructure (pour-over).

Issue Map

# Title Type Stream Status
#175 Refactor ShotHistoryView monolith Frontend refactor A ⬜ Not started
#186 Accessibility pass (ARIA, landmarks, keyboard) Frontend quality A ⬜ Not started
#95 Recommend existing profiles during generation Feature (Profile) B ⬜ Not started
#258 AI analysis → profile editing pipeline Feature (Analysis) C ⬜ Not started
#281 Temporary variable adjustments when running a shot Feature (Run) D ⬜ Not started
#261 Espresso Compass taste input Feature (Analysis) E ⬜ Not started
#260 Dial-In Guide for Beginners Feature (Home) E ⬜ Not started

Implementation Streams

Five independent work streams enable high parallelism:

Stream A (Frontend Quality):     #175 (refactor) ──→ #186 (a11y)
Stream B (Profile Intelligence): #95  (recommend profiles) [standalone]
Stream C (Analysis Pipeline):    #258 (analysis → edit pipeline) [standalone]
Stream D (Run Experience):       #281 (temporary variable adjustments) [standalone]
Stream E (Brewing Coach):        #261 (compass) ──→ #260 (dial-in wizard)

Cross-version Dependencies (all satisfied by v2.2.0 PR #262)

2.3 Issue Depends on v2.2 Feature v2.2 Status
#258 #257PUT /api/profile/{name}/edit endpoint ✅ Built
#95 #192 — Profile catalogue with managed profiles ✅ Built
#260 #259 — Shot analysis view + recent shots endpoints ✅ Built
#281 #257PUT /api/profile/{name}/edit endpoint ✅ Built
#281 temp_profile_service.py — Temporary profile lifecycle (pour-over) ✅ Built
#281 coffee.py:105-145 — Adjustable vs info variable classification ✅ Built

Intra-milestone Dependencies

Issue Must complete first Reason
#186 (a11y) #175 (refactor) a11y attributes must target the final sub-component structure, not the pre-refactor monolith
#260 (dial-in) #261 (compass) Dial-in wizard Step 5 uses the TasteCompassInput component from #261

Note: #281 has no intra-milestone dependencies. It modifies RunShotView.tsx (not ShotHistoryView.tsx), so it is independent of all other streams.

Phased Implementation Order

Phase 1: ShotHistoryView Refactor (#175)

  • Extract ShotList.tsx — shot selection list with search, filtering, date grouping
  • Extract ShotDetail.tsx — individual shot view (chart + metadata + analysis)
  • Extract ShotComparison.tsx — side-by-side comparison mode
  • Create ShotHistoryView/ directory with barrel export
  • Slim ShotHistoryView.tsx to orchestration (<1,000 lines)
  • Visual regression: zero pixel differences before/after
  • bun run build + bun run lint + bun run test:run all pass

Current state: 2,545 lines. Chart extraction already complete (no direct recharts imports). Remaining work is pure sub-component decomposition.

Phase 2: Profile Recommendations (#95)

Can run in parallel with Phase 1

  • POST /api/profiles/recommend endpoint with profile scoring
  • "Matching Profiles" section in FormView.tsx after roast + ≥2 tags
  • 0–3 recommended profiles with match score + rationale
  • "Use This" → profile detail; "Generate New" → current generation flow
  • "Find similar" button in ProfileCatalogueView.tsx
  • i18n, unit tests, frontend tests

Phase 3: Analysis → Profile Edit Pipeline (#258)

Can run in parallel with Phases 1–2

  • POST /api/shots/analyze-recommendations — structured JSON recommendations from Gemini
  • POST /api/profile/{name}/apply-recommendations — batch-applies patchable recommendations
  • Extended prompt in prompt_builder.py with RECOMMENDATIONS_JSON format
  • RecommendationSelectionDialog.tsx — grouped checkboxes, confidence badges, value previews
  • "Apply Recommendations" button in ExpertAnalysisView.tsx
  • i18n, unit tests, frontend tests

Phase 4: Temporary Variable Adjustments (#281)

Can run in parallel with Phases 1–3 — standalone

  • POST /api/machine/run-profile-with-overrides endpoint in scheduling.py
    • "temporary" mode: fetch profile JSON → apply variable overrides → temp_profile_service.create_and_load() → register cleanup
    • "save_original" mode: call existing PUT /api/profile/{name}/edit → run normally
    • "save_as_new" mode: clone profile → apply overrides → save with new name → run
  • Extend temp_profile_service.py if needed for variable-override use case
  • VariableAdjustPanel.tsx — expandable panel showing adjustable variables (filter info_ prefix)
    • Per-variable type controls (pressure, flow, weight, power, time)
    • +/- controls or slider per variable type
    • Modified variables visually distinguished (amber highlight, "modified" badge)
    • Reset button to restore saved values
  • Integrate into RunShotView.tsx — show panel after profile selection
    • Save-mode selector (Run / Save & Run / Save as New & Run)
    • "Save as New" prompts for profile name
    • If no variables modified, normal run flow unchanged
  • Cleanup lifecycle: automatic cleanup after shot completion, abort, and on error
  • i18n: all new UI strings translated (6 locales)
  • Mobile-responsive variable adjustment panel
  • Backend + frontend tests

Key infrastructure to reuse:

  • temp_profile_service.py — temp profile lifecycle (create → load → cleanup)
  • pour_over.py + PourOverView.tsx — reference implementation of the full temp profile UX pattern
  • PUT /api/profile/{name}/edit — variable update logic (key/value matching)
  • coffee.py:105-145 — adjustable vs info variable classification

Phase 5: Espresso Compass Taste Input (#261)

Can start in parallel; must complete before Phase 6

  • TasteCompassInput.tsx — interactive 2D draggable compass
  • Strength slider (1–5) + quick taste tags (positive/negative)
  • Extend POST /api/shots/analyze-llm with optional taste parameters
  • Extend cache key with taste data hash
  • Add Espresso Compass knowledge to analysis prompt
  • 6th "Taste-Based Recommendations" section when taste data provided
  • i18n, unit tests, frontend tests

Phase 6: Dial-In Guide for Beginners (#260)

Depends on Phase 5 (#261) — largest feature in the milestone

  • dialin_service.py — session management + AI integration
  • dialin.py models — DialInSession, DialInIteration, TasteFeedback
  • 6 API endpoints (POST /api/dialin/session, etc.)
  • DialInWizard.tsx — 7-step wizard with state machine
  • 7 step components (CoffeeStep, ProfileStep, PrepStep, BrewStep, TasteStep, RecommendStep, HistoryStep)
  • 'dial-in' ViewState + "Dial In" button on home page
  • Dial-in-specific Gemini prompt template
  • i18n, unit tests, frontend tests

Phase 7: Accessibility Pass (#186)

Depends on Phase 1; should be last to cover all new components including #281's VariableAdjustPanel

  • Sub-phase 1: Landmarks & structure (<main>, <nav>, <aside>, skip nav, tab roles)
  • Sub-phase 2: Live regions (aria-live on metrics, shot completion, machine state)
  • Sub-phase 3: Interactive elements (aria-label, aria-describedby, keyboard handlers)
  • Sub-phase 4: Charts & visualization (role="img", text summaries, keyboard legends)
  • Sub-phase 5: Testing (axe-core in Playwright, screen reader manual test, keyboard walkthrough)

Shared Components

Component Built in Consumed by
TasteCompassInput #261 #260 (DialInTasteStep)
RecommendationSelectionDialog #258 Standalone (ExpertAnalysisView)
VariableAdjustPanel #281 RunShotView; potentially reusable for profile editing
DialInWizard + step components #260 Standalone (StartView)
useAnnounce hook #186 All components with dynamic updates
ShotList, ShotDetail, ShotComparison #175 ShotHistoryView, potentially #260

v2.2.0 Compatibility Items

These should be verified before v2.2.0 merges:

  1. PUT /api/profile/{name}/edit response format — must return enough metadata for Integrate AI shot analysis recommendations with profile editing pipeline #258's apply-recommendations to chain (updated profile JSON, change summary)
  2. GET /api/shots/recent metadata — must include enough shot info for Add Dial-In Guide for Beginners to Home Page #260's dial-in wizard to reuse
  3. parseStructuredAnalysis() extensibility — must handle N sections (not hardcoded to 5) for Integrate Espresso Afficionados Compass Guide for taste-based shot analysis #261's 6th section
  4. GET /api/machine/profiles detail level — must return full parameters (temperature, variables, stages) for Recommend existing profiles during generation and in catalogue #95's scoring and feat: temporary variable adjustments when running a shot #281's variable adjustment panel
  5. temp_profile_service.py extensibility — must support arbitrary profile JSON overrides (not just pour-over templates) for feat: temporary variable adjustments when running a shot #281's temporary variable adjustments

Risk Assessment

Risk Impact Mitigation
#260 (Dial-In) is very large (~20+ new files) Schedule slip Sub-phase: steps 1–3 can ship independently of 4–7
Compass UI (#261) is complex touch/drag component UX quality Prototype early; consider existing React 2D picker lib
#186 a11y pass touches nearly every component Merge conflicts Schedule last; one focused sprint
Gemini structured JSON output (#258) may be inconsistent Reliability Response validation + retry with format correction prompt
#281 temp profile cleanup on abort/error Data integrity Reuse proven pour-over cleanup pattern; add startup orphan cleanup for "MeticAI Override:" prefix

Done When

  • All Phase 1–7 checkboxes above completed
  • All unit tests pass (backend + frontend)
  • TypeScript build clean with zero errors
  • Lint passes with zero errors
  • All new strings have i18n keys in 6 locales
  • Accessibility: axe-core audit passes with zero critical/serious violations

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions