# Data Model: Unified Task Reports by Type

**Feature**: [`020-task-reports-design`](specs/020-task-reports-design)  
**Spec**: [`spec.md`](specs/020-task-reports-design/spec.md)  
**Research**: [`research.md`](specs/020-task-reports-design/research.md)

## 1. Entity: TaskReport

Represents a normalized, user-visible report entry for one task execution.

### Fields

| Field | Type | Required | Description |
|---|---|---|---|
| report_id | string | Yes | Stable unique identifier of report entry. |
| task_id | string | Yes | Source task identifier. |
| task_type | enum | Yes | `llm_verification`, `backup`, `migration`, `documentation`, `unknown`. |
| status | enum | Yes | `success`, `failed`, `in_progress`, `partial`. |
| started_at | datetime | No | Task start time if available. |
| updated_at | datetime | Yes | Last known report update timestamp. |
| summary | string | Yes | Short user-facing summary of outcome. |
| details | object | No | Type-specific details block for drill-down. |
| error_context | object | No | Failure/partial context with reason + recommended next action. |
| source_ref | object | No | Optional links to related resource (dataset/dashboard/environment). |

### Validation Rules

- `report_id` and `task_id` must be non-empty.
- `task_type` outside known values must map to `unknown`.
- `status` outside known values must be rejected or mapped by normalization policy.
- `summary` must be present (fallback to default summary if upstream is empty).

### Lifecycle / State Transitions

- `in_progress` → `success`
- `in_progress` → `failed`
- `in_progress` → `partial`
- `partial` may transition to `success` after follow-up action
- Terminal states (`success`, `failed`) are immutable except metadata enrichment

---

## 2. Entity: ReportTypeProfile

Defines presentation semantics used by frontend for each report category.

### Fields

| Field | Type | Required | Description |
|---|---|---|---|
| task_type | enum | Yes | Type key used for profile selection. |
| display_label | string | Yes | Explicit text label shown in report list/detail. |
| visual_variant | string | Yes | Variant token controlling style family. |
| icon_token | string | No | Optional icon semantic key. |
| emphasis_rules | array[string] | No | Defines which fields receive visual priority. |
| fallback | boolean | Yes | Marks profile as default fallback for unknown types. |

### Validation Rules

- Exactly one profile per known `task_type`.
- Exactly one fallback profile with `fallback=true`.
- `display_label` must be non-empty and localized in implementation.

---

## 3. Entity: ReportQuery

Represents user-selected filtering and ordering options for list retrieval.

### Fields

| Field | Type | Required | Description |
|---|---|---|---|
| page | integer | Yes | 1-based page index. |
| page_size | integer | Yes | Number of items per page. |
| task_types | array[enum] | No | Type filter list. |
| statuses | array[enum] | No | Status filter list. |
| time_from | datetime | No | Lower time bound. |
| time_to | datetime | No | Upper time bound. |
| search | string | No | Free text search over summary/details. |
| sort_by | enum | Yes | `updated_at`, `status`, `task_type`. |
| sort_order | enum | Yes | `asc`, `desc`. |

### Validation Rules

- `page >= 1`.
- `1 <= page_size <= 100`.
- `time_from <= time_to` when both are provided.
- Unsupported filter values are rejected with validation error.

---

## 4. Entity: ReportCollection

A paginated response containing normalized reports for unified listing.

### Fields

| Field | Type | Required | Description |
|---|---|---|---|
| items | array[TaskReport] | Yes | Current page of reports. |
| total | integer | Yes | Total count matching filters. |
| page | integer | Yes | Current page index. |
| page_size | integer | Yes | Page size used. |
| has_next | boolean | Yes | True when another page exists. |
| applied_filters | ReportQuery | Yes | Echo of effective filter/query. |

---

## 5. Entity: ReportDetailView

Detailed representation for a single selected report.

### Fields

| Field | Type | Required | Description |
|---|---|---|---|
| report | TaskReport | Yes | Base normalized report. |
| timeline | array[object] | No | Ordered key lifecycle events (start/fail/complete). |
| diagnostics | object | No | Extended detail payload for the type. |
| next_actions | array[string] | No | Human-readable recovery guidance. |

### Validation Rules

- Detail view must always include `report`.
- For `failed`/`partial` status, `next_actions` should be non-empty whenever actionable context exists.

---

## 6. Relationships

- `ReportCollection.items[*]` → `TaskReport`
- `TaskReport.task_type` → selects `ReportTypeProfile`
- `ReportQuery` → constrains `ReportCollection`
- `ReportDetailView.report` → exactly one `TaskReport`

---

## 7. Scale Assumptions

- Historical report volume may reach thousands of entries per environment.
- Query model is designed for server-side filtering and pagination.
- UI must remain usable even when only partial fields are available for some task types.