# UI Plan 1 Block 03 — Backend-Backed Static Today Seed

**Status:** Complete on 2026-06-30.
**Goal:** Seed the current day through scheduler domain/application state and query it for the UI.

---

## Block outcome

After this block, the UI should no longer render placeholder timeline data. It should query a deterministic in-memory backend/application composition and receive display-ready Today state from scheduler public APIs.

The UI still does not implement real mutations. The seed represents the state as if real calls had already created/scheduled/logged the tasks.

---

## Chunk 3.1 — Define current-day seed policy

### Tasks

1. Add `app/demo_scheduler_composition.dart` or equivalent.
2. Centralize seed creation in this file, not in widgets.
3. Runtime selected date should default to current owner-local day.
4. Widget tests may inject a fixed clock/date matching the mockup.
5. Use UTC instants for seed storage/query fixture unless a repo timezone resolver already exists.
6. Do not call `DateTime.now()` inside widgets.

### Date handling rule

Use this separation:

- `selectedDate`: `CivilDate.fromDateTime(clock.now())` or equivalent owner-local resolver.
- `seed task instants`: derived from `selectedDate` at fixed local display times.
- tests: use a `FixedClock` to make `selectedDate` deterministic.

If exact local timezone conversion is not available in app code yet, use `FixedOffsetTimeZoneResolver.utc()` and document that local timezone display is a later integration concern. Do not invent a full timezone service in this UI slice.

### Acceptance criteria

- Date and seed data are deterministic under test.
- Runtime does not recreate random tasks on every rebuild.
- Seed data exists only in composition/controller, not widgets.

---

## Chunk 3.2 — Build the static seed domain objects

### Required seed records

Create at least one project:

```dart
ProjectProfile(
  id: 'home',
  name: 'Home',
  colorKey: 'project-home',
)
```

Create owner settings:

```dart
OwnerSettings(
  ownerId: 'owner-1',
  timeZoneId: 'UTC',
  compactModeEnabled: true,
)
```

Create static tasks for the selected date:

| ID | Title | Type | Status | Time | Reward | Difficulty | Notes |
|---|---|---|---|---|---|---|---|
| `clean-coffee-maker` | Clean coffee maker | flexible | planned | 4:15–4:30 PM | medium/high acceptable | veryEasy or easy | Green card; 15 min. |
| `cleaned-kitchen-counter-early` | Cleaned kitchen counter | surprise | completed | visible near 4:45–5:00 PM | medium | medium | Completed gray row; completed at 4:20 PM. |
| `pay-bill` | Pay bill | critical or inflexible per existing semantics | planned | 6:00–6:10 PM | low/level 2 equivalent | medium | Pink required card; next required. |
| `doctor-appointment` | Doctor appointment | inflexible | planned | 6:30–7:15 PM | medium | hard | Blue required appointment card. |
| `free-slot` | Free Slot | freeSlot | planned | 7:15–8:15 PM | notSet | notSet | Purple rest card; no quick actions. |
| `cleaned-kitchen-counter-late` | Cleaned kitchen counter | surprise | completed | visible near 8:15–8:30 PM | medium | medium | Later completed gray row. |

### Implementation notes

- Prefer `Task` or `ProjectProfile.createTask` constructors from `package:scheduler_core/scheduler_core.dart`.
- Use `durationMinutes` matching start/end.
- Use `scheduledStart` and `scheduledEnd` for timeline visibility.
- Use `completedAt` for completed surprise rows.
- Use stable IDs; no random IDs.
- Do not run scheduling algorithms in Flutter just to place these demo records.

### Acceptance criteria

- Seed objects are valid domain objects.
- Seed tasks appear in `GetTodayStateQuery` results.
- The seed can be constructed for any selected date by changing only the date component.

BREAKPOINT: Stop if public scheduler APIs cannot represent the seed without importing `src/` internals.

---

## Chunk 3.3 — Query Today state from application/core APIs

### Tasks

1. Use public `scheduler_core` API to create an in-memory application store.
2. Initialize it with the seed project, settings, and tasks.
3. Create a `GetTodayStateQuery` with a fixed/known timezone resolver.
4. Execute `GetTodayStateRequest` for the selected current day.
5. Store the result in a controller state that supports:
   - loading,
   - data,
   - empty,
   - failure.

Suggested concept:

```dart
final store = InMemoryApplicationUnitOfWork(
  initialProjects: seed.projects,
  initialTasks: seed.tasks,
  initialOwnerSettings: [seed.ownerSettings],
);

final todayQuery = GetTodayStateQuery(
  applicationStore: store,
  timeZoneResolver: const FixedOffsetTimeZoneResolver.utc(),
);
```

Then execute with an `ApplicationOperationContext` using a stable operation id, clock, owner/timezone, and ID generator.

### Design constraints

- UI can map `TodayState` to presentation models, but must not modify canonical schedule state.
- Failures should be surfaced with a simple calm message in the UI if they happen.
- No persistence adapter should be used in this plan.

### Acceptance criteria

- Controller can produce a `TodayScreenData`/equivalent from real `TodayState`.
- Tests can instantiate controller/composition with a fixed clock and receive the six seeded items.
- `pay-bill` is identified as the next required item at the default read time.

---

## Chunk 3.4 — Define UI display models as a thin adapter

### Tasks

Create `models/today_screen_models.dart` or equivalent with small UI-facing models, for example:

```dart
class TodayScreenData {
  final String dateLabel;
  final RequiredBannerModel? requiredBanner;
  final List<TimelineCardModel> cards;
  final TimelineRangeModel timelineRange;
}

class TimelineCardModel {
  final String id;
  final String title;
  final String subtitle;
  final String timeText;
  final TaskVisualKind visualKind;
  final int? durationMinutes;
  final RewardLevel reward;
  final DifficultyLevel difficulty;
  final bool isCompleted;
  final bool isSelectable;
}
```

Use existing read-model values where possible; this class should only bridge domain/read state to Flutter presentation.

### Mapping rules

- `TaskType.flexible` → green flexible visuals.
- `TaskType.critical` or app-selected required type → pink required visuals.
- `TaskType.inflexible` → blue required/appointment visuals.
- `TaskType.freeSlot` → purple rest visuals.
- `TaskStatus.completed` or `TaskType.surprise` completed → gray completed visuals.
- Task card time text should come from scheduled start/end formatting.
- Required banner comes from `TodayState.nextRequiredItem`.

### Acceptance criteria

- Widgets consume `TodayScreenData` or equivalent rather than raw repository state.
- The adapter is small, deterministic, and covered by tests.
- No scheduling placement decisions occur in this adapter.

---

## Chunk 3.5 — Wire seeded state into the shell

### Tasks

1. `FocusFlowApp` receives or creates `DemoSchedulerComposition`.
2. Main screen uses a controller/future builder/listenable to load Today data.
3. Render loading state briefly if needed.
4. Render failure state if query fails.
5. Render empty state only if no cards exist.
6. Render data state into the shell/banner/timeline.

### Acceptance criteria

- On launch, the compact Today screen shows seeded date, required banner, and cards.
- Widget tests can pump the app and find seeded labels.
- Widgets remain free of seed construction.

---

## Block acceptance criteria

- The timeline seed is static, deterministic, and backend-backed.
- The UI reads from application/domain state.
- No Flutter widget owns canonical schedule rules.
- `pay-bill` appears as next required in the banner.
- Six seed items are available to timeline rendering.

## Validation after block

```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

Tests should verify seeded query and UI adapter behavior before timeline polish begins.

---

## Completed implementation

1. Rebuilt `DemoSchedulerComposition` as the static UI Plan 1 seed boundary.
2. Seeded `ProjectProfile`, compact `OwnerSettings`, and six scheduled task
   records through public scheduler domain objects.
3. Queried `GetTodayStateQuery` through an in-memory application store.
4. Added `TodayScreenController` loading/data/empty/failure state.
5. Added `TodayScreenData` and `TimelineCardModel` as thin UI display adapters.

## Verification

1. `flutter analyze`: passed, no issues found.
2. `flutter test`: passed, including seeded Today and visual mapping coverage.
