Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@

# ========== Tasks ==========
/tasks:
get:

Check warning on line 169 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: List tasks
operationId: listTasks
Expand Down Expand Up @@ -194,7 +194,7 @@
schema: {$ref: '#/components/schemas/RbacDenied'}
'429': {$ref: '#/components/responses/RateLimited'}

post:

Check warning on line 197 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Create download task
operationId: createTask
Expand Down Expand Up @@ -296,7 +296,7 @@
parameters:
- $ref: '#/components/parameters/TaskId'

get:

Check warning on line 299 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Get task by ID
operationId: getTask
Expand All @@ -315,7 +315,7 @@
'404':
description: Task not found or cross-tenant ID (existence not leaked)

patch:

Check warning on line 318 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Update task (priority only)
operationId: updateTask
Expand Down Expand Up @@ -368,7 +368,7 @@
/tasks/{taskId}/cancel:
parameters:
- $ref: '#/components/parameters/TaskId'
post:

Check warning on line 371 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Cancel task (async)
operationId: cancelTask
Expand Down Expand Up @@ -402,7 +402,7 @@
/tasks/{taskId}/retry:
parameters:
- $ref: '#/components/parameters/TaskId'
post:

Check warning on line 405 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Retry failed subtasks
operationId: retrySubtasks
Expand Down Expand Up @@ -448,7 +448,7 @@
/tasks/{taskId}/upgrade:
parameters:
- $ref: '#/components/parameters/TaskId'
post:

Check warning on line 451 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Upgrade to new revision (incremental)
operationId: upgradeTask
Expand All @@ -472,7 +472,7 @@
/tasks/{taskId}/subtasks:
parameters:
- $ref: '#/components/parameters/TaskId'
get:

Check warning on line 475 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [subtasks]
summary: List subtasks of a task
operationId: listSubtasks
Expand All @@ -495,7 +495,7 @@
/tasks/{taskId}/source-allocation:
parameters:
- $ref: '#/components/parameters/TaskId'
get:

Check warning on line 498 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: View source allocation (multi-source visualization)
operationId: getSourceAllocation
Expand All @@ -509,7 +509,7 @@
/tasks/{taskId}/events:
parameters:
- $ref: '#/components/parameters/TaskId'
get:

Check warning on line 512 in api/openapi.yaml

View workflow job for this annotation

GitHub Actions / OpenAPI lint

operation-description Operation "description" must be present and non-empty string.
tags: [tasks]
summary: Task event log
operationId: getTaskEvents
Expand All @@ -529,6 +529,23 @@
items: {$ref: '#/components/schemas/TaskEvent'}
next_cursor: {type: string, nullable: true}

/tasks/stream:
get:
tags: [tasks]
summary: Live tenant-scoped tasks-list SSE stream (UI-SP5c)
operationId: streamTaskList
responses:
'200':
description: SSE stream of TaskList snapshots (text/event-stream)
content:
text/event-stream:
schema:
type: string
description: |
Each event is `data: <TaskList JSON>\n\n` ({items, total}).
Stream terminates only on client disconnect or controller
shutdown. Keep-alive comment lines (`:keepalive`) may appear.

/tasks/{taskId}/stream:
parameters:
- $ref: '#/components/parameters/TaskId'
Expand Down
21 changes: 21 additions & 0 deletions docs/operator/web-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,24 @@ holds against a second consumer.

Tenant filtering reuses SP3's `list_executors_for_principal` (own-tenant +
shared-infra; `system_admin`/service-token bypass).

### UI-SP5c — Tasks-list SSE follow-on

Third application of the view-free SSE template. The Tasks landing page
(`useTaskList`, consumed by both `TaskList.vue` and the Dashboard "recent
tasks" widget) now talks SSE via `GET /api/v1/tasks/stream` (5 s default
tick; `DLW_TASKS_LIST_STREAM_INTERVAL_SECONDS` overrides; clamped
`[0.5, 60.0]`). The page and composable consumers are unchanged; SP1's
existing tests pass unmodified.

Tenant filtering reuses the existing `list_tasks` aggregation
(`tenant_filtered(select(DownloadTask))`) — same RBAC and slim shape
(`{items: TaskRead[], total: int}`, no subtasks) as the `GET /api/v1/tasks`
endpoint.

**Routing note**: `tasks_list_stream_router` is registered BEFORE
`tasks_router` in `src/dlw/main.py` so the static `/stream` path wins over
the parameterized `/{task_id}` route (FastAPI iterates routers in include
order; this was a first-of-kind issue caught by the SP5c pre-review gate
— SP5/SP5b didn't expose it because their stream paths had no sibling
parameterized routes under the same prefix).
Loading
Loading