"""Workspace state envelopes.

The server stores `payload_json` as an OPAQUE BLOB — it does NOT parse the
TypeScript-owned shape. This is intentional per the SYNTHESIS contract-authority
split (LOCKED #8): UI-owned data stays in TypeScript+zod SSOT.

The Pydantic models here are the HTTP envelope only.
"""
from __future__ import annotations

from pydantic import BaseModel, Field

# Schema version on the envelope (separate from any schemaVersion the UI puts
# inside payload_json, which is the UI's concern).
ENVELOPE_SCHEMA_VERSION = 2


class WorkspaceStateRead(BaseModel):
    workspace_id: str
    schema_version: int = Field(
        default=ENVELOPE_SCHEMA_VERSION,
        description="Envelope schema version. Bump on breaking envelope changes.",
    )
    payload_json: str = Field(
        ...,
        description="OPAQUE JSON owned by the UI. Server does NOT parse.",
    )
    updated_at: str


class WorkspaceStateWrite(BaseModel):
    # Typed as int (not Literal[1]) so the route handler's 409 check actually
    # fires on mismatch — Pydantic's Literal validation would 422 first and
    # mask the contract-level error per Law 4 (errors visible at the right
    # boundary). The route handler enforces == ENVELOPE_SCHEMA_VERSION.
    schema_version: int = ENVELOPE_SCHEMA_VERSION
    payload_json: str
