59 lines
1.4 KiB
Python
59 lines
1.4 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
DATA_FORMAT_VERSION = 1
|
|
|
|
|
|
class StoredTask(BaseModel):
|
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
|
|
id: UUID
|
|
title: str = Field(..., min_length=1, max_length=100)
|
|
created_at: datetime
|
|
started_at: datetime | None = None
|
|
done_at: datetime | None = None
|
|
|
|
|
|
class StoragePayloadV1(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
version: int = Field(default=DATA_FORMAT_VERSION)
|
|
tasks: list[StoredTask] = Field(default_factory=list)
|
|
|
|
|
|
class StoragePayload(BaseModel):
|
|
"""
|
|
Canonical in-memory storage payload.
|
|
This model allows safe parsing of the top-level version field
|
|
before delegating to a concrete versioned schema.
|
|
"""
|
|
|
|
model_config = ConfigDict(extra="allow")
|
|
|
|
version: int
|
|
|
|
|
|
def upgrade_payload(raw_data: dict) -> StoragePayloadV1:
|
|
"""
|
|
Upgrade any supported payload version to the latest schema.
|
|
"""
|
|
payload = StoragePayload.model_validate(raw_data)
|
|
|
|
if payload.version == 1:
|
|
parsed_v1 = StoragePayloadV1.model_validate(raw_data)
|
|
return StoragePayloadV1(
|
|
version=DATA_FORMAT_VERSION,
|
|
tasks=parsed_v1.tasks,
|
|
)
|
|
|
|
raise ValueError(
|
|
f"Unsupported storage payload version: {payload.version}. "
|
|
f"Supported versions: 1..{DATA_FORMAT_VERSION}",
|
|
)
|
|
|