# Implementation Plan: Add Data Waist Link Fix

## Overview

This plan fixes two related bugs that prevent users from fully accessing the visceral fat tracking feature:

1. **Missing waist tab** in the Add Data screen — `TabController` is hard-coded to `length: 3` with no fourth tab for waist/visceral fat tracking.
2. **Incorrect null-guard logic** on profile prompts in the Track Visceral Fat screen — conditions use `userProfile != null && !userProfile.hasX` which evaluates to `false` when no profile row exists, hiding prompts from the exact users who need them.

The implementation follows the exploratory bugfix workflow: write tests to confirm the bugs exist, write preservation tests to protect existing behavior, then implement the fixes and verify both test suites pass.

## Tasks

- [x] 1. Write bug condition exploration tests
  - **Property 1: Bug Condition** - Missing Waist Tab and Hidden Profile Prompts for Null Profile
  - **CRITICAL**: These tests MUST FAIL on unfixed code — failure confirms the bugs exist
  - **DO NOT attempt to fix the tests or the code when they fail**
  - **NOTE**: These tests encode the expected behavior — they will validate the fix when they pass after implementation
  - **GOAL**: Surface counterexamples that demonstrate both bugs exist
  - **Scoped PBT Approach**: Scope to the concrete failing cases:
    - Bug 1: AddDataScreen has only 3 tabs, no 'Waist' tab present
    - Bug 2: TrackVisceralFatScreen with `userProfile: null` hides height/gender prompts
  - Create widget tests in `test/property_tests/` that:
    - Mount `AddDataScreen`, find all `Tab` widgets, assert count is 4 and one has text 'Waist' (will FAIL — only 3 tabs)
    - Mount `TrackVisceralFatScreen` with mocked `HealthDataBloc` emitting `HealthDataLoaded(userProfile: null)`, assert text 'Set Your Height' is found (will FAIL — null-guard hides it)
    - Same null profile setup, assert text 'Set Your Gender' is found (will FAIL — null-guard hides it)
  - Use `bloc_test` or `mockito` with `whenListen` to control BLoC state emissions
  - Run tests on UNFIXED code
  - **EXPECTED OUTCOME**: Tests FAIL (this is correct — it proves both bugs exist)
  - Document counterexamples: "AddDataScreen has 3 tabs not 4; 'Set Your Height' and 'Set Your Gender' not found when userProfile is null"
  - Mark task complete when tests are written, run, and failures are documented
  - _Requirements: 1.1, 1.2, 1.3_

- [x] 2. Write preservation property tests (BEFORE implementing fix)
  - **Property 2: Preservation** - Existing Tabs Unchanged and Prompts Hidden When Profile Fields Set
  - **IMPORTANT**: Follow observation-first methodology
  - Observe on UNFIXED code:
    - AddDataScreen renders Weight, Blood Pressure, Mood tabs with correct icons and text
    - TrackVisceralFatScreen with `UserProfile(heightValue: 170, heightUnit: 'cm', gender: 'male')` hides both prompts
    - TrackVisceralFatScreen with `UserProfile(heightValue: 170, heightUnit: 'cm', gender: null)` hides height prompt, shows gender prompt
    - TrackVisceralFatScreen with `UserProfile(heightValue: null, heightUnit: null, gender: 'female')` shows height prompt, hides gender prompt
    - TrackVisceralFatScreen with `UserProfile(heightValue: null, heightUnit: null, gender: null)` (row exists, all fields null) shows both prompts
    - Dismissing height or gender prompt hides it for the session
  - Write property-based tests:
    - For all `UserProfile` instances where `hasHeight == true`: height prompt is never shown (generate random valid height values/units with `glados`)
    - For all `UserProfile` instances where `hasGender == true`: gender prompt is never shown (generate random gender values)
    - For profile with both fields unset (row exists): both prompts shown
    - Existing 3 tabs (Weight, Blood Pressure, Mood) render with correct icons and labels
    - Prompt dismissal hides prompt regardless of profile state
  - Verify all tests PASS on UNFIXED code (these behaviors already work correctly)
  - **EXPECTED OUTCOME**: Tests PASS (confirms baseline behavior to preserve)
  - Mark task complete when tests are written, run, and passing on unfixed code
  - _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_

- [x] 3. Fix missing waist tab and incorrect null-guard logic on profile prompts

  - [x] 3.1 Add waist/visceral fat tab to AddDataScreen
    - Add import for `track_visceral_fat_screen.dart` and `../models/waist_entry.dart`
    - Change `TabController(length: 3)` to `TabController(length: 4)`
    - Add fourth `Tab` widget after Mood: `Tab(icon: Icon(Icons.straighten), text: 'Waist')`
    - Add fourth `TabBarView` child: `const _WaistEntryTab()`
    - Create `_WaistEntryTab` stateful widget following the pattern of `_WeightEntryTab`:
      - Card with `Icons.straighten` icon (size 64), title 'Track Waist Measurement', description 'Tap to record your waist circumference'
      - `onTap` navigates to `TrackVisceralFatScreen` and refreshes recent entries on return
      - Tips card with waist measurement tips
      - `RecentEntriesTable<WaistEntry>` showing recent waist entries from `DatabaseService`
    - _Bug_Condition: isBugCondition(input) where input.screen == 'AddDataScreen' — waist tab always missing_
    - _Expected_Behavior: tabCount == 4 AND findTab('Waist') != null AND tapping navigates to TrackVisceralFatScreen_
    - _Preservation: Weight, Blood Pressure, and Mood tabs unchanged in position, icons, and content_
    - _Requirements: 2.1, 3.5_

  - [x] 3.2 Fix null-guard logic on profile prompts in TrackVisceralFatScreen
    - Change height prompt condition from:
      `if (userProfile != null && !userProfile.hasHeight && !_heightPromptDismissed)`
      to:
      `if ((userProfile == null || !userProfile.hasHeight) && !_heightPromptDismissed)`
    - Change gender prompt condition from:
      `if (userProfile != null && !userProfile.hasGender && !_genderPromptDismissed)`
      to:
      `if ((userProfile == null || !userProfile.hasGender) && !_genderPromptDismissed)`
    - _Bug_Condition: isBugCondition(input) where input.screen == 'TrackVisceralFatScreen' AND input.userProfileRow == null_
    - _Expected_Behavior: findWidget('Set Your Height') != null AND findWidget('Set Your Gender') != null when profile is null or fields not set_
    - _Preservation: Prompts hidden when hasHeight/hasGender == true; dismissal still works; form, validation, save flow unchanged_
    - _Requirements: 2.2, 2.3, 3.1, 3.2, 3.3, 3.4_

  - [x] 3.3 Verify bug condition exploration tests now pass
    - **Property 1: Expected Behavior** - Missing Waist Tab and Hidden Profile Prompts for Null Profile
    - **IMPORTANT**: Re-run the SAME tests from task 1 — do NOT write new tests
    - The tests from task 1 encode the expected behavior
    - When these tests pass, it confirms the expected behavior is satisfied:
      - AddDataScreen now has 4 tabs including 'Waist'
      - TrackVisceralFatScreen with null userProfile now shows height and gender prompts
    - Run bug condition exploration tests from step 1
    - **EXPECTED OUTCOME**: Tests PASS (confirms bugs are fixed)
    - _Requirements: 2.1, 2.2, 2.3_

  - [x] 3.4 Verify preservation tests still pass
    - **Property 2: Preservation** - Existing Tabs Unchanged and Prompts Hidden When Profile Fields Set
    - **IMPORTANT**: Re-run the SAME tests from task 2 — do NOT write new tests
    - Run preservation property tests from step 2
    - **EXPECTED OUTCOME**: Tests PASS (confirms no regressions)
    - Confirm all tests still pass after fix (no regressions)
    - _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_

- [x] 4. Checkpoint - Ensure all tests pass
  - Run full test suite: `flutter test`
  - Ensure all property tests pass (both bug condition and preservation)
  - Ensure all existing tests pass (no regressions in other screens)
  - Ask the user if questions arise

## Notes

- The fix spans two files: `lib/screens/add_data_screen.dart` (add waist tab) and `lib/screens/track_visceral_fat_screen.dart` (fix null-guard logic)
- The BLoC layer and database service are NOT modified — both bugs are purely in the UI layer
- Property-based tests use `glados` (the existing PBT library in this project)
- Widget tests use `bloc_test` / `mockito` for BLoC mocking with controlled state emissions
- Exploration tests (task 1) are expected to FAIL on unfixed code — this confirms the bugs exist
- Preservation tests (task 2) are expected to PASS on unfixed code — this confirms baseline behavior
- The `_WaistEntryTab` follows the established pattern from `_WeightEntryTab`, `_BloodPressureEntryTab`, and `_MoodEntryTab`
- The null-guard fix inverts the condition: show prompts when profile is missing OR when the specific field is not set

## Task Dependency Graph

```json
{
  "waves": [
    { "id": 0, "tasks": ["1", "2"] },
    { "id": 1, "tasks": ["3.1", "3.2"] },
    { "id": 2, "tasks": ["3.3", "3.4"] },
    { "id": 3, "tasks": ["4"] }
  ]
}
```
