sched: add typed occurrence expression kind for schedule inputs (T04)

This commit is contained in:
lda
2026-09-08 10:09:31 +07:00 Verified
parent 352686128b
commit 0ded9b0d40
3 changed files with 323 additions and 2 deletions
+71 -1
View File
@@ -103,6 +103,46 @@ type InputExpression = Annotated[
]
class OccurrenceExpression(BaseModel):
"""Reference one typed schedule-occurrence field.
Schedule-only leaf: graph expressions must not accept this kind, and
``GraphSourcePath`` roots stay closed to input/state/context.
"""
model_config = ConfigDict(extra="forbid", strict=True)
kind: Literal["occurrence"]
field: Literal["schedule_id", "occurrence_id", "scheduled_at"]
class ScheduleArrayExpression(BaseModel):
"""Resolve ordered child schedule expressions into one JSON array."""
model_config = ConfigDict(extra="forbid")
kind: Literal["array"]
items: list[ScheduleExpression]
class ScheduleObjectExpression(BaseModel):
"""Resolve named child schedule expressions into one JSON object."""
model_config = ConfigDict(extra="forbid")
kind: Literal["object"]
fields: dict[str, ScheduleExpression]
type ScheduleExpression = Annotated[
LiteralExpression
| OccurrenceExpression
| ScheduleArrayExpression
| ScheduleObjectExpression,
Field(discriminator="kind"),
]
def _raise_limit(limit: str, location: str) -> None:
raise ValueError(f"input expression {limit} limit exceeded at {location}")
@@ -206,5 +246,35 @@ StepInputBinding = TypeAliasType(
)
for _model in (ArrayExpression, ObjectExpression, InputExpressionBinding):
class ScheduleInputBinding(BaseModel):
"""Assign one schedule-side expression to a workflow-input target.
Schedule expressions reuse literal/object/array composition and the same
budget validator, but leaves are typed occurrence references only. Graph
paths are invalid here.
"""
model_config = ConfigDict(extra="forbid")
target: LocalPath
expression: ScheduleExpression
@field_validator("expression", mode="before")
@classmethod
def check_limits(cls, value: object) -> object:
raw_value = (
value.model_dump(mode="python") if isinstance(value, BaseModel) else value
)
validate_input_expression_limits(raw_value)
return value
for _model in (
ArrayExpression,
ObjectExpression,
InputExpressionBinding,
ScheduleArrayExpression,
ScheduleObjectExpression,
ScheduleInputBinding,
):
_model.model_rebuild()