> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ionworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 2026 07 23 schedule channel context auto watch

# Schedule Channel Context + Auto-Watch Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use
> superpowers:subagent-driven-development (recommended) or
> superpowers:executing-plans to implement this plan task-by-task. Steps use
> checkbox (`- [ ]`) syntax for tracking.

**Goal:** Enrich the Schedule channel dropdown with availability + ratings, and
auto-watch `requested_by` when a scheduled plan links to a started measurement.

**Architecture:** Frontend-only Autocomplete enrichment from existing lab
status. Backend injects `UserWatchedMeasurementService` into measurement create
(link path) and planned-measurement PATCH (in\_progress path); watch failures
are logged and never fail the primary operation.

**Tech Stack:** React/MUI Autocomplete, RTK Query lab status, FastAPI services,
pytest, vitest.

**Spec:**
`docs/superpowers/specs/2026-07-23-schedule-channel-context-auto-watch-design.md`

***

## File map

| File                                                                | Responsibility                           |
| ------------------------------------------------------------------- | ---------------------------------------- |
| `frontend/src/sections/lab/schedule-channel-options.ts`             | Pure flatten + ratings helpers           |
| `frontend/src/sections/lab/schedule-channel-options.test.ts`        | Unit tests for helpers                   |
| `frontend/src/sections/lab/schedule-planned-measurement-dialog.tsx` | Use helpers + `renderOption`             |
| `backend/src/services/cell_measurements.py`                         | Auto-watch after successful link         |
| `backend/src/services/planned_measurements.py`                      | Auto-watch on transition to in\_progress |
| `backend/tests/fixtures/cell_fixtures.py`                           | Optional `watch_service` mock            |
| `backend/tests/test_services/test_cell_measurements.py`             | Link → watch tests                       |
| `backend/tests/test_services/test_planned_measurements.py`          | PATCH → watch tests                      |
| `dev-docs/planned-measurements.md`                                  | Note auto-watch behavior                 |

***

### Task 1: Frontend channel option helpers + dialog

**Files:**

* Create: `frontend/src/sections/lab/schedule-channel-options.ts`

* Create: `frontend/src/sections/lab/schedule-channel-options.test.ts`

* Modify: `frontend/src/sections/lab/schedule-planned-measurement-dialog.tsx`

* [ ] **Step 1: Write failing vitest for flatten + ratings label**

Export `ScheduleChannelOption`, `channelRatingsLabel`,
`flattenLabChannelsForSchedule`. Test: free channel with `max_amps=40`,
`min_volts=0`, `max_volts=5` → ratings `"40 A · 0–5 V"` and `state: 'free'`.

* [ ] **Step 2: Implement helpers**

Reuse `formatRatingRange` from `wall-scope.ts`. Flatten site→cycler→channel
with `id`, `label`, `outOfCommission`, `state`, amp/volt fields.

* [ ] **Step 3: Wire dialog Autocomplete**

Use helpers; `renderOption` shows label, ratings secondary line, trailing
`CHANNEL_STATE_STYLES[state].label` (Lab-wall title case). Keep
out-of-commission disabled. Preserve next-available helper.

* [ ] **Step 4: Run** `just test-frontend-unit` filtered to the new test file
  (or project vitest command for that path). Expect PASS.

***

### Task 2: Auto-watch on measurement link (primary path)

**Files:**

* Modify: `backend/src/services/cell_measurements.py`

* Modify: `backend/tests/fixtures/cell_fixtures.py` (add `watch_service` mock)

* Modify: `backend/tests/test_services/test_cell_measurements.py`

* [ ] **Step 1: Write failing tests**

On successful `link_started_measurement` return with `requested_by`, assert
`watch_service.watch(requested_by, measurement_id)` awaited once.

When link returns `None`, watch not called.

When watch raises, measurement create still succeeds.

* [ ] **Step 2: Implement**

Inject `UserWatchedMeasurementService` into `CellMeasurementService` +
`get_cell_measurement_service`. After successful link, call watch inside
try/except (log, continue). Prefer nested try so link success is not rolled
back by watch failure (watch after link, separate except).

* [ ] **Step 3: Run**
  `just test-backend tests/test_services/test_cell_measurements.py -k "planned"`
  Expect PASS. Fix fixture constructors that construct the service.

***

### Task 3: Auto-watch on planned PATCH to in\_progress

**Files:**

* Modify: `backend/src/services/planned_measurements.py`

* Modify: `backend/tests/test_services/test_planned_measurements.py`

* [ ] **Step 1: Write failing tests**

`scheduled` → `in_progress` + `started_measurement_id`: watch called with
`requested_by` and that measurement id.

Already `in_progress` update (e.g. to completed): watch not called for
auto-start.

Watch failure does not fail update.

* [ ] **Step 2: Implement**

Inject watch service. After successful update, if
`existing.status is not in_progress` and updated status is `in_progress` and
`started_measurement_id` is set, auto-watch with try/except.

* [ ] **Step 3: Run**
  `just test-backend tests/test_services/test_planned_measurements.py -k "in_progress or watch"`
  Expect PASS.

***

### Task 4: Docs

**Files:**

* Modify: `dev-docs/planned-measurements.md`

* [ ] **Step 1:** Document that successful link / in\_progress transition
  auto-watches `requested_by` (best-effort, non-blocking).

***

## Execution note

User requested implement immediately; execute inline in this session. Do not
create intermediate commits unless the user asks — leave working tree ready for
review/commit.
