таски готовы

This commit is contained in:
2026-02-23 10:18:56 +03:00
parent f0c85e4c03
commit 008b6d72c9
48 changed files with 3559 additions and 72 deletions

View File

@@ -0,0 +1,109 @@
# Module Contracts: Unified Task Reports by Type
## Backend Report Aggregation Module
# [DEF:ReportsAggregationModule:Module]
# @TIER: CRITICAL
# @SEMANTICS: [reports, aggregation, normalization, task_outcomes]
# @PURPOSE: Aggregate heterogeneous task outcomes into a canonical report model for unified listing and detail retrieval.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> [DEF:TaskManagerModule]
# @RELATION: DEPENDS_ON -> [DEF:TaskPersistenceModule]
# @RELATION: CALLS -> [DEF:ReportsApiContract]
# @INVARIANT: Every returned report MUST include canonical fields {report_id, task_id, task_type, status, updated_at, summary}.
# @PRE: Query parameters are validated and within supported pagination/filter limits.
# @POST: Response contains normalized reports with deterministic ordering and total metadata.
# @POST: Unknown task type is mapped to fallback type "unknown" and remains visible.
# @POST: Partial payloads are rendered with placeholders, never causing report omission.
# [/DEF:ReportsAggregationModule]
---
## Backend Reports API Contract
# [DEF:ReportsApiContract:Module]
# @TIER: CRITICAL
# @SEMANTICS: [api, reports, contracts, pagination]
# @PURPOSE: Define backend HTTP contract for unified report list and report detail endpoints.
# @LAYER: Interface
# @RELATION: DEPENDS_ON -> [DEF:ReportsAggregationModule]
# @RELATION: IMPLEMENTS -> [DEF:Std:API_FastAPI]
# @INVARIANT: Endpoint responses are non-blocking reads and must not start long-running tasks.
# @PRE: Request is authenticated and authorized under existing report/task visibility rules.
# @POST: List endpoint returns {items, total, page, page_size, has_next, applied_filters}.
# @POST: Detail endpoint returns a single normalized report with diagnostics/next actions when available.
# @POST: Validation errors are explicit (400-range) and machine-readable.
# [/DEF:ReportsApiContract]
---
## Frontend Unified Reports Page Contract
<!-- [DEF:UnifiedReportsPage:Component] -->
/**
* @TIER: CRITICAL
* @SEMANTICS: [ui, reports, filtering, detail_panel]
* @PURPOSE: Provide one unified report center with type-distinct visuals and fast operator triage flow.
* @LAYER: UI
* @RELATION: DEPENDS_ON -> [DEF:ReportsApiClient]
* @RELATION: BINDS_TO -> [DEF:ReportTypeProfileRegistry]
* @INVARIANT: Reports list remains readable and interactive under large history and mixed task types.
* @PRE: User is authenticated and has access to report data.
* @POST: User can identify report type from both text label and visual profile.
* @POST: User can filter by type/status and open detail without leaving report context.
* @UX_STATE: Loading -> Skeleton list displayed; filters visible but request controls disabled.
* @UX_STATE: Ready -> List of normalized reports shown with type badges and status indicators.
* @UX_STATE: NoData -> Friendly empty state with explanation when no reports exist at all.
* @UX_STATE: FilteredEmpty -> Message "No reports match your filters" with one-click clear action.
* @UX_STATE: Error -> Inline error block with retry action while preserving filter context.
* @UX_FEEDBACK: On filter apply, list updates with immediate visual acknowledgment.
* @UX_RECOVERY: Retry failed loads, clear filters, and continue reading partial reports with placeholders.
*/
<!-- [/DEF:UnifiedReportsPage] -->
---
## Frontend Reports API Client Contract
# [DEF:ReportsApiClient:Module]
# @TIER: STANDARD
# @SEMANTICS: [frontend, api_client, reports]
# @PURPOSE: Wrap report API requests via existing request helpers and expose typed list/detail fetch methods.
# @LAYER: Infra
# @RELATION: DEPENDS_ON -> [DEF:api_module]
# @RELATION: CALLS -> [DEF:ReportsApiContract]
# @INVARIANT: Native fetch is not used directly; existing wrapper-based request path is preserved.
# @PRE: Valid auth token is present when required by backend.
# @POST: Returns parsed report payload or structured error object for UI-state mapping.
# [/DEF:ReportsApiClient]
---
## Frontend Type Profile Registry Contract
# [DEF:ReportTypeProfileRegistry:Module]
# @TIER: STANDARD
# @SEMANTICS: [presentation, report_types, fallback]
# @PURPOSE: Maintain deterministic mapping from task_type to visual profile metadata and fallback behavior.
# @LAYER: UI
# @RELATION: DEPENDS_ON -> [DEF:UnifiedReportsPage]
# @INVARIANT: Exactly one fallback profile exists and is used for unknown task types.
# @PRE: Input task_type may be known or unknown.
# @POST: Returns profile with display label and variant tokens required for rendering.
# [/DEF:ReportTypeProfileRegistry]
---
## Contract Usage Simulation (Key Scenario)
Scenario traced: Operator finds failed migration quickly and triages.
1. `UnifiedReportsPage` requests filtered list (`status=failed`, `task_type=migration`) through `ReportsApiClient`.
2. `ReportsApiClient` calls `ReportsApiContract` list endpoint.
3. `ReportsAggregationModule` normalizes task records and returns canonical report items.
4. `UnifiedReportsPage` enters `Ready` `@UX_STATE`, rendering migration-specific visual profile.
5. Operator opens one report detail.
6. `ReportsApiContract` detail endpoint returns diagnostics + `next_actions`.
7. UI shows actionable failure context and recovery guidance without changing page context.
Continuity check: No interface mismatch found across contracts for list/filter/detail path.

View File

@@ -0,0 +1,272 @@
openapi: 3.0.3
info:
title: Unified Task Reports API
version: 1.0.0
description: API contract for consolidated task reports across task types.
servers:
- url: /api
paths:
/reports:
get:
summary: List unified task reports
description: Returns paginated normalized reports with filtering and sorting.
operationId: listReports
parameters:
- in: query
name: page
schema:
type: integer
minimum: 1
default: 1
- in: query
name: page_size
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- in: query
name: task_types
description: Comma-separated values
schema:
type: string
example: migration,backup
- in: query
name: statuses
description: Comma-separated values
schema:
type: string
example: failed,in_progress
- in: query
name: time_from
schema:
type: string
format: date-time
- in: query
name: time_to
schema:
type: string
format: date-time
- in: query
name: search
schema:
type: string
maxLength: 200
- in: query
name: sort_by
schema:
type: string
enum: [updated_at, status, task_type]
default: updated_at
- in: query
name: sort_order
schema:
type: string
enum: [asc, desc]
default: desc
responses:
'200':
description: Paginated unified reports
content:
application/json:
schema:
$ref: '#/components/schemas/ReportCollection'
'400':
description: Invalid query parameters
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
'403':
description: Forbidden
/reports/{report_id}:
get:
summary: Get report detail
description: Returns one normalized report with optional diagnostics and next actions.
operationId: getReportDetail
parameters:
- in: path
name: report_id
required: true
schema:
type: string
responses:
'200':
description: Report detail
content:
application/json:
schema:
$ref: '#/components/schemas/ReportDetailView'
'401':
description: Unauthorized
'403':
description: Forbidden
'404':
description: Report not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
TaskType:
type: string
enum:
- llm_verification
- backup
- migration
- documentation
- unknown
ReportStatus:
type: string
enum:
- success
- failed
- in_progress
- partial
ReportSourceRef:
type: object
additionalProperties: true
description: Optional pointers to related domain objects (dashboard/dataset/environment).
ErrorContext:
type: object
properties:
code:
type: string
message:
type: string
next_actions:
type: array
items:
type: string
required: [message]
TaskReport:
type: object
properties:
report_id:
type: string
task_id:
type: string
task_type:
$ref: '#/components/schemas/TaskType'
status:
$ref: '#/components/schemas/ReportStatus'
started_at:
type: string
format: date-time
nullable: true
updated_at:
type: string
format: date-time
summary:
type: string
details:
type: object
nullable: true
additionalProperties: true
error_context:
$ref: '#/components/schemas/ErrorContext'
source_ref:
$ref: '#/components/schemas/ReportSourceRef'
required:
- report_id
- task_id
- task_type
- status
- updated_at
- summary
ReportQueryEcho:
type: object
properties:
page:
type: integer
page_size:
type: integer
task_types:
type: array
items:
$ref: '#/components/schemas/TaskType'
statuses:
type: array
items:
$ref: '#/components/schemas/ReportStatus'
time_from:
type: string
format: date-time
nullable: true
time_to:
type: string
format: date-time
nullable: true
search:
type: string
nullable: true
sort_by:
type: string
enum: [updated_at, status, task_type]
sort_order:
type: string
enum: [asc, desc]
required: [page, page_size, sort_by, sort_order]
ReportCollection:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/TaskReport'
total:
type: integer
minimum: 0
page:
type: integer
minimum: 1
page_size:
type: integer
minimum: 1
has_next:
type: boolean
applied_filters:
$ref: '#/components/schemas/ReportQueryEcho'
required: [items, total, page, page_size, has_next, applied_filters]
ReportDetailView:
type: object
properties:
report:
$ref: '#/components/schemas/TaskReport'
timeline:
type: array
items:
type: object
additionalProperties: true
diagnostics:
type: object
nullable: true
additionalProperties: true
next_actions:
type: array
items:
type: string
required: [report]
ErrorResponse:
type: object
properties:
detail:
type: string
code:
type: string
required: [detail]