8c69911252
Design-only artifacts for unifying saved tasks on ssh_tasks services. No implementation yet. - proposal: two-path problem (Actions→machine vs widget→service), goals, non-goals, grilling decisions (SSH-only, service_task_runs only, keep override) - design: shared run_saved_task helper, column rename, saved_task_runs dropped, API + frontend changes, 2-slice plan - tasks: backend (shared runner + router) + frontend (Actions page)
106 lines
4.2 KiB
Markdown
106 lines
4.2 KiB
Markdown
# Tasks: Unify Saved Tasks on SSH Services
|
||
|
||
**Change:** `unify-tasks-on-services`
|
||
**Phase:** tasks
|
||
**Date:** 2026-06-19
|
||
|
||
## Review workload forecast
|
||
|
||
| Field | Value |
|
||
|-------|-------|
|
||
| Estimated changed lines | ~600–800 |
|
||
| Chained PRs recommended | Yes (2 PRs) |
|
||
| Chain strategy | stacked-to-main |
|
||
|
||
## Slice 1: Backend — shared runner + service-based tasks
|
||
|
||
**Goal:** One execution path; tasks target ssh_tasks services; one history table.
|
||
|
||
- [ ] **1.1 Add shared `run_saved_task` helper**
|
||
- Files: `backend/src/media_library_viewer_api/services/task_runner.py` (new)
|
||
- Lines: ~90
|
||
- Details: `run_saved_task(store, task, service, *, request_id)` builds the SSH
|
||
client from the service record (promote `_build_ssh_client`), renders the
|
||
command, runs with the service timeout, appends a `service_task_runs` row,
|
||
returns a `TaskRunResult`.
|
||
- [ ] **1.2 Rename saved_tasks column**
|
||
- Files: `services/settings_store.py` (modify)
|
||
- Lines: ~20
|
||
- Details: `default_machine_id` → `default_service_id` (ALTER TABLE RENAME
|
||
COLUMN on startup; update `_row_to_task`, `_normalize_task_payload`,
|
||
`upsert_task`).
|
||
- [ ] **1.3 Drop saved_task_runs**
|
||
- Files: `services/settings_store.py` (modify)
|
||
- Lines: ~-60
|
||
- Details: `DROP TABLE IF EXISTS saved_task_runs`; remove `record_task_run`
|
||
and `list_task_runs` (task flavor).
|
||
- [ ] **1.4 Rewire tasks router**
|
||
- Files: `routers/tasks.py` (modify)
|
||
- Lines: ~70
|
||
- Details: `TaskInput.default_service_id`; `run_task` takes `service_id`
|
||
(override), resolves an ssh_tasks service, calls `run_saved_task`;
|
||
`/api/tasks/{id}/runs` reads `service_task_runs`. Remove
|
||
`_resolve_machine_for_task` and `_client_for_machine`.
|
||
- [ ] **1.5 Widget delegates to shared helper**
|
||
- Files: `widgets/sources.py` (modify)
|
||
- Lines: ~-40
|
||
- Details: `SshTaskWidgetSource.fetch` calls `run_saved_task` instead of its
|
||
inline run+log block.
|
||
- [ ] **1.6 Add `list_service_task_runs` by task (if not present)**
|
||
- Files: `services/settings_store.py` (modify)
|
||
- Lines: ~10
|
||
- Details: Confirm `list_service_task_runs(task_id=...)` covers the tasks
|
||
router needs.
|
||
- [ ] **1.7 Update backend tests**
|
||
- Files: `backend/tests/test_jobs.py`, `test_api.py` (modify)
|
||
- Lines: ~60
|
||
- Details: Update task-run tests to the service model; cover override +
|
||
default + disabled-service paths.
|
||
- [ ] **1.8 Verify**
|
||
- Run: `cd backend && .venv/bin/ruff check . && PYTHONPATH=src .venv/bin/python -m pytest`
|
||
|
||
**Slice 1 total:** ~250 changed lines.
|
||
|
||
## Slice 2: Frontend — Actions page on services
|
||
|
||
**Goal:** Actions page targets ssh_tasks services; reads service_task_runs.
|
||
|
||
- [ ] **2.1 Update types**
|
||
- Files: `frontend/src/types/index.ts` (modify)
|
||
- Lines: ~15
|
||
- Details: `SavedTask` / `SavedTaskInput` `default_service_id`;
|
||
`SavedTaskRun` aligned to `service_task_runs`.
|
||
- [ ] **2.2 Update API client**
|
||
- Files: `frontend/src/api/client.ts` (modify)
|
||
- Lines: ~10
|
||
- Details: `runTask(taskId, serviceId?)` sends `service_id`.
|
||
- [ ] **2.3 Rewire Actions page**
|
||
- Files: `frontend/src/pages/Actions.tsx` (modify)
|
||
- Lines: ~120
|
||
- Details: Task editor "Default service" select lists ssh_tasks services via
|
||
`useServiceInstances("ssh_tasks")`; run dialog "Run on" selects an instance;
|
||
run history reads `service_task_runs`. Remove `useMonitoringSettings`.
|
||
- [ ] **2.4 Update Actions tests**
|
||
- Files: `frontend/src/pages/__tests__/Actions.test.tsx` (modify)
|
||
- Lines: ~30
|
||
- Details: Mock `useServiceInstances`; update fixtures.
|
||
- [ ] **2.5 Docs + changelog**
|
||
- Files: `docs/REQUIREMENTS.md`, `CHANGELOG.md` (modify)
|
||
- Lines: ~30
|
||
- Details: Saved-actions section: tasks target ssh_tasks services; local mode
|
||
dropped; breaking-upgrade note.
|
||
- [ ] **2.6 Verify**
|
||
- Run: `cd frontend && npm run lint && npm run build && npm run test`
|
||
|
||
**Slice 2 total:** ~200 changed lines.
|
||
|
||
## Integration and acceptance
|
||
|
||
- [ ] **3.1 Backend full test run** — `PYTHONPATH=src pytest`, all green.
|
||
- [ ] **3.2 Frontend full build/lint/test**.
|
||
- [ ] **3.3 Manual dev-stack check**:
|
||
- Create an ssh_tasks service; create a task with that default; run from
|
||
Actions; see the run in both the Actions history and the service page.
|
||
- Override the target at run time.
|
||
- SSH task widget uses the same history.
|