semantics
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# #region ReportModels [C:3] [TYPE Module] [SEMANTICS pydantic, report, model, schema, task, task-type]
|
||||
# @BRIEF Canonical report schemas for unified task reporting across heterogeneous task types.
|
||||
# @LAYER: Domain
|
||||
# @PRE: Pydantic library and task manager models are available.
|
||||
# @POST: Provides validated schemas for cross-plugin reporting and UI consumption.
|
||||
# @SIDE_EFFECT: None (schema definition).
|
||||
# @DATA_CONTRACT: Model[TaskReport, ReportCollection, ReportDetailView]
|
||||
# @LAYER Domain
|
||||
# @PRE Pydantic library and task manager models are available.
|
||||
# @POST Provides validated schemas for cross-plugin reporting and UI consumption.
|
||||
# @SIDE_EFFECT None (schema definition).
|
||||
# @DATA_CONTRACT Model[TaskReport, ReportCollection, ReportDetailView]
|
||||
# @RELATION DEPENDS_ON -> [TaskModels]
|
||||
# @INVARIANT: Canonical report fields are always present for every report item.
|
||||
# @INVARIANT Canonical report fields are always present for every report item.
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
@@ -16,7 +16,7 @@ from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
|
||||
# #region TaskType [C:3] [TYPE Class] [SEMANTICS enum, type, task]
|
||||
# @INVARIANT: Must contain valid generic task type mappings.
|
||||
# @INVARIANT Must contain valid generic task type mappings.
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
# @BRIEF Supported normalized task report types.
|
||||
class TaskType(str, Enum):
|
||||
@@ -32,7 +32,7 @@ class TaskType(str, Enum):
|
||||
|
||||
|
||||
# #region ReportStatus [C:3] [TYPE Class] [SEMANTICS enum, status, task]
|
||||
# @INVARIANT: TaskStatus enum mapping logic holds.
|
||||
# @INVARIANT TaskStatus enum mapping logic holds.
|
||||
# @BRIEF Supported normalized report status values.
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportStatus(str, Enum):
|
||||
@@ -46,10 +46,10 @@ class ReportStatus(str, Enum):
|
||||
|
||||
|
||||
# #region ErrorContext [C:3] [TYPE Class] [SEMANTICS error, context, payload]
|
||||
# @INVARIANT: The properties accurately describe error state.
|
||||
# @INVARIANT The properties accurately describe error state.
|
||||
# @BRIEF Error and recovery context for failed/partial reports.
|
||||
#
|
||||
# @TEST_CONTRACT: ErrorContextModel ->
|
||||
# @TEST_CONTRACT ErrorContextModel ->
|
||||
# {
|
||||
# required_fields: {
|
||||
# message: str
|
||||
@@ -59,8 +59,8 @@ class ReportStatus(str, Enum):
|
||||
# next_actions: list[str]
|
||||
# }
|
||||
# }
|
||||
# @TEST_FIXTURE: basic_error -> {"message": "Connection timeout", "code": "ERR_504", "next_actions": ["retry"]}
|
||||
# @TEST_EDGE: missing_message -> {"code": "ERR_504"}
|
||||
# @TEST_FIXTURE basic_error -> {"message": "Connection timeout", "code": "ERR_504", "next_actions": ["retry"]}
|
||||
# @TEST_EDGE missing_message -> {"code": "ERR_504"}
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ErrorContext(BaseModel):
|
||||
code: str | None = None
|
||||
@@ -72,10 +72,10 @@ class ErrorContext(BaseModel):
|
||||
|
||||
|
||||
# #region TaskReport [C:3] [TYPE Class] [SEMANTICS report, model, summary]
|
||||
# @INVARIANT: Must represent canonical task record attributes.
|
||||
# @INVARIANT Must represent canonical task record attributes.
|
||||
# @BRIEF Canonical normalized report envelope for one task execution.
|
||||
#
|
||||
# @TEST_CONTRACT: TaskReportModel ->
|
||||
# @TEST_CONTRACT TaskReportModel ->
|
||||
# {
|
||||
# required_fields: {
|
||||
# report_id: str,
|
||||
@@ -91,7 +91,7 @@ class ErrorContext(BaseModel):
|
||||
# "summary is a non-empty string"
|
||||
# ]
|
||||
# }
|
||||
# @TEST_FIXTURE: valid_task_report ->
|
||||
# @TEST_FIXTURE valid_task_report ->
|
||||
# {
|
||||
# report_id: "rep-123",
|
||||
# task_id: "task-456",
|
||||
@@ -100,10 +100,10 @@ class ErrorContext(BaseModel):
|
||||
# updated_at: "2026-02-26T12:00:00Z",
|
||||
# summary: "Migration completed successfully"
|
||||
# }
|
||||
# @TEST_EDGE: empty_report_id -> {"report_id": " ", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
||||
# @TEST_EDGE: empty_summary -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": ""}
|
||||
# @TEST_EDGE: invalid_task_type -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "invalid_type", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
||||
# @TEST_INVARIANT: non_empty_validators -> verifies: [empty_report_id, empty_summary]
|
||||
# @TEST_EDGE empty_report_id -> {"report_id": " ", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
||||
# @TEST_EDGE empty_summary -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": ""}
|
||||
# @TEST_EDGE invalid_task_type -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "invalid_type", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
||||
# @TEST_INVARIANT non_empty_validators -> verifies: [empty_report_id, empty_summary]
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class TaskReport(BaseModel):
|
||||
report_id: str
|
||||
@@ -130,10 +130,10 @@ class TaskReport(BaseModel):
|
||||
|
||||
|
||||
# #region ReportQuery [C:3] [TYPE Class] [SEMANTICS query, filter, search]
|
||||
# @INVARIANT: Time and pagination queries are mutually consistent.
|
||||
# @INVARIANT Time and pagination queries are mutually consistent.
|
||||
# @BRIEF Query object for server-side report filtering, sorting, and pagination.
|
||||
#
|
||||
# @TEST_CONTRACT: ReportQueryModel ->
|
||||
# @TEST_CONTRACT ReportQueryModel ->
|
||||
# {
|
||||
# optional_fields: {
|
||||
# page: int, page_size: int, task_types: list[TaskType], statuses: list[ReportStatus],
|
||||
@@ -146,11 +146,11 @@ class TaskReport(BaseModel):
|
||||
# "time_from <= time_to if both exist"
|
||||
# ]
|
||||
# }
|
||||
# @TEST_FIXTURE: valid_query -> {"page": 1, "page_size":20, "sort_by": "updated_at", "sort_order": "desc"}
|
||||
# @TEST_EDGE: invalid_page_size_large -> {"page_size": 150}
|
||||
# @TEST_EDGE: invalid_sort_by -> {"sort_by": "unknown_field"}
|
||||
# @TEST_EDGE: invalid_time_range -> {"time_from": "2026-02-26T12:00:00Z", "time_to": "2026-02-25T12:00:00Z"}
|
||||
# @TEST_INVARIANT: attribute_constraints_enforced -> verifies: [invalid_page_size_large, invalid_sort_by, invalid_time_range]
|
||||
# @TEST_FIXTURE valid_query -> {"page": 1, "page_size":20, "sort_by": "updated_at", "sort_order": "desc"}
|
||||
# @TEST_EDGE invalid_page_size_large -> {"page_size": 150}
|
||||
# @TEST_EDGE invalid_sort_by -> {"sort_by": "unknown_field"}
|
||||
# @TEST_EDGE invalid_time_range -> {"time_from": "2026-02-26T12:00:00Z", "time_to": "2026-02-25T12:00:00Z"}
|
||||
# @TEST_INVARIANT attribute_constraints_enforced -> verifies: [invalid_page_size_large, invalid_sort_by, invalid_time_range]
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportQuery(BaseModel):
|
||||
page: int = Field(default=1, ge=1)
|
||||
@@ -189,18 +189,18 @@ class ReportQuery(BaseModel):
|
||||
|
||||
|
||||
# #region ReportCollection [C:3] [TYPE Class] [SEMANTICS collection, pagination]
|
||||
# @INVARIANT: Represents paginated data correctly.
|
||||
# @INVARIANT Represents paginated data correctly.
|
||||
# @BRIEF Paginated collection of normalized task reports.
|
||||
#
|
||||
# @TEST_CONTRACT: ReportCollectionModel ->
|
||||
# @TEST_CONTRACT ReportCollectionModel ->
|
||||
# {
|
||||
# required_fields: {
|
||||
# items: list[TaskReport], total: int, page: int, page_size: int, has_next: bool, applied_filters: ReportQuery
|
||||
# },
|
||||
# invariants: ["total >= 0", "page >= 1", "page_size >= 1"]
|
||||
# }
|
||||
# @TEST_FIXTURE: empty_collection -> {"items": [], "total": 0, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
||||
# @TEST_EDGE: negative_total -> {"items": [], "total": -5, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
||||
# @TEST_FIXTURE empty_collection -> {"items": [], "total": 0, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
||||
# @TEST_EDGE negative_total -> {"items": [], "total": -5, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportCollection(BaseModel):
|
||||
items: list[TaskReport]
|
||||
@@ -215,16 +215,16 @@ class ReportCollection(BaseModel):
|
||||
|
||||
|
||||
# #region ReportDetailView [C:3] [TYPE Class] [SEMANTICS view, detail, logs]
|
||||
# @INVARIANT: Incorporates a report and logs correctly.
|
||||
# @INVARIANT Incorporates a report and logs correctly.
|
||||
# @BRIEF Detailed report representation including diagnostics and recovery actions.
|
||||
#
|
||||
# @TEST_CONTRACT: ReportDetailViewModel ->
|
||||
# @TEST_CONTRACT ReportDetailViewModel ->
|
||||
# {
|
||||
# required_fields: {report: TaskReport},
|
||||
# optional_fields: {timeline: list[dict], diagnostics: dict, next_actions: list[str]}
|
||||
# }
|
||||
# @TEST_FIXTURE: valid_detail -> {"report": {"report_id": "rep-1", "task_id": "task-1", "task_type": "backup", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}}
|
||||
# @TEST_EDGE: missing_report -> {}
|
||||
# @TEST_FIXTURE valid_detail -> {"report": {"report_id": "rep-1", "task_id": "task-1", "task_type": "backup", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}}
|
||||
# @TEST_EDGE missing_report -> {}
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportDetailView(BaseModel):
|
||||
report: TaskReport
|
||||
|
||||
Reference in New Issue
Block a user