The conformance board (tests/afi/test_capability_parity.py) is now fully green: 90 capability cells + 4 meta-locks + 3 codegen byte-parity = 97 passed. The gaps the prose table used to launder as "Django-only" / "out of scope" are wired, against the pinned-spec model (single-authored spec, byte-identical conformance across languages) — never per-language reimplementation. FastAPI — edge_manifest + PSR (logic single-sourced in mizan_core.manifest), WebSocket RPC (/ws/ through the shared dispatch), SSR (the framework-agnostic SSRBridge relocated to mizan_core.ssr; Django rides it from there), Shapes (SQLAlchemy projection, same declaration surface as django-readers), Forms (Pydantic schema/validate/submit). Rust (Axum + Tauri + cores/mizan-rust) — X-Mizan-Invalidate header, auth= enforcement, origin HMAC cache, edge manifest + PSR, WebSocket handler / IPC subscription channel, multipart upload, SSR bridge, Shapes, Forms; JWT/MWT mint+verify and cache-key derivation byte-pinned to the Python reference (cache_keys_pin, token_pin, invalidate_header_pin). TypeScript — a KDL IR emitter byte-identical to the Python build_ir (so a TS backend can feed the codegen — the largest gap), multipart upload, session-init, WebSocket transport, SSR bridge, JWT/MWT mint (pinned to Python), Shapes, Forms. Verified in the merged tree: core 25, fastapi 74, django 353/21-skip, mizan-rust (incl. cross-language pins) green, axum 10, tauri 8, mizan-ts 103/2-skip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
1.7 KiB
Python
78 lines
1.7 KiB
Python
"""
|
|
Form role output schemas — the wire shapes the schema/validate/submit roles emit.
|
|
|
|
These mirror the Django adapter's `mizan.forms.schemas` field-for-field (FormMeta,
|
|
FieldSchema, FormSchema, FormValidation, FormSubmitPass/Fail) so the generated
|
|
client is identical regardless of which backend authored the form. The only
|
|
difference is the source: Django builds these from `forms.Field` introspection;
|
|
this builds them from Pydantic `FieldInfo`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Optional
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class FormMeta(BaseModel):
|
|
"""Frontend behavior flags (parity with the Django adapter)."""
|
|
|
|
refetch_schema_on_validate: bool = False
|
|
live_validation: bool = True
|
|
live_form_errors: bool = False
|
|
|
|
|
|
class FieldChoice(BaseModel):
|
|
value: str
|
|
label: str
|
|
|
|
|
|
class FieldError(BaseModel):
|
|
message: str
|
|
code: Optional[str] = None
|
|
|
|
|
|
class FieldErrorList(BaseModel):
|
|
field: str
|
|
errors: list[FieldError]
|
|
|
|
|
|
class FieldSchema(BaseModel):
|
|
name: str
|
|
label: str
|
|
type: str
|
|
widget: str
|
|
required: bool
|
|
disabled: bool
|
|
help_text: str
|
|
initial: Any = None
|
|
max_length: Optional[int] = None
|
|
min_length: Optional[int] = None
|
|
choices: Optional[list[FieldChoice]] = None
|
|
|
|
|
|
class FormSchema(BaseModel):
|
|
"""Schema returned by the `.schema` role: form metadata + field definitions."""
|
|
|
|
name: str
|
|
title: str
|
|
subtitle: Optional[str] = None
|
|
submit_label: str
|
|
fields: list[FieldSchema]
|
|
meta: FormMeta = FormMeta()
|
|
|
|
|
|
class FormValidation(BaseModel):
|
|
errors: list[FieldErrorList]
|
|
|
|
|
|
class FormSubmitPass(BaseModel):
|
|
success: bool
|
|
data: Optional[dict] = None
|
|
|
|
|
|
class FormSubmitFail(BaseModel):
|
|
success: bool
|
|
errors: FormValidation
|