app.model.strategy_definition module¶
Persistent model for user-authored strategies.
The legacy engine (see app.engine) loads BaseStrategy subclasses
discovered at import time. A second path covers strategies
expressed as a JSON AST and stored per-tenant in Postgres, so that game
designers can create or extend strategies from the dashboard without
touching Python code.
This model only stores the definition. Execution lives in the DSL
interpreter. At this layer astJson is opaque to
the engine and rows are addressable via the custom:<id> prefix on
Games.strategyId / Tasks.strategyId (see the compat layer in
app.services.strategy_service).
- class app.model.strategy_definition.StrategyDefinitionType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
str,EnumDiscriminator describing how the row should be executed.
BUILT_IN– placeholder for promoting a registry class into the DB, currently unused but kept so the column is forward-compatible.DSL_EXTEND– runs a built-in parent and wraps it with pre/post rules expressed in the AST.DSL_FULL– fully replaces the parent; only the AST runs.
- class app.model.strategy_definition.StrategyDefinitionStatus(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
str,EnumLifecycle states. Only
PUBLISHEDrows are eligible to execute in production;DRAFTandARCHIVEDare visible from the editor but ignored by the engine.
- class app.model.strategy_definition.StrategyDefinition(*, id=<factory>, created_at=<factory>, updated_at=<factory>, apiKey_used=None, oauth_user_id=None, realmId=None, name, description=None, type, parentStrategyId=None, astJson=None, blocklyXml=None, version, status, createdBy=None, publishedAt=None, experimentTag=None)[source]¶
Bases:
BaseModelTenant-scoped strategy authored from the dashboard.
- Versioning rules (enforced by
StrategyDefinitionService): Editing a
PUBLISHEDrow never overwrites it. A new row withversion + 1andstatus=DRAFTis created instead.Publishing a draft transitions its status to
PUBLISHEDand archives any sibling row in the same(realmId, name)family that was previously published.The
(realmId, name, version)triple is unique so that the history can be walked deterministically.
- Parameters:
id (Annotated[str, FieldInfoMetadata(primary_key=PydanticUndefined, nullable=PydanticUndefined, foreign_key=PydanticUndefined, ondelete=PydanticUndefined, unique=PydanticUndefined, index=PydanticUndefined, sa_type=UUID(), sa_column=PydanticUndefined, sa_column_args=PydanticUndefined, sa_column_kwargs={'primary_key': True, 'index': True})])
created_at (Annotated[datetime, FieldInfoMetadata(primary_key=PydanticUndefined, nullable=PydanticUndefined, foreign_key=PydanticUndefined, ondelete=PydanticUndefined, unique=PydanticUndefined, index=PydanticUndefined, sa_type=DateTime(timezone=True), sa_column=PydanticUndefined, sa_column_args=PydanticUndefined, sa_column_kwargs={'server_default': <sqlalchemy.sql.functions.now at 0x7fa8900484a0; now>})])
updated_at (Annotated[datetime, FieldInfoMetadata(primary_key=PydanticUndefined, nullable=PydanticUndefined, foreign_key=PydanticUndefined, ondelete=PydanticUndefined, unique=PydanticUndefined, index=PydanticUndefined, sa_type=DateTime(timezone=True), sa_column=PydanticUndefined, sa_column_args=PydanticUndefined, sa_column_kwargs={'server_default': <sqlalchemy.sql.functions.now at 0x7fa88fa2a840; now>, 'onupdate': <sqlalchemy.sql.functions.now at 0x7fa88fa2ad20; now>})])
apiKey_used (Annotated[str | None, FieldInfoMetadata(primary_key=PydanticUndefined, nullable=True, foreign_key=apikey.apiKey, ondelete=PydanticUndefined, unique=PydanticUndefined, index=PydanticUndefined, sa_type=PydanticUndefined, sa_column=PydanticUndefined, sa_column_args=PydanticUndefined, sa_column_kwargs=PydanticUndefined)])
oauth_user_id (Annotated[str | None, FieldInfoMetadata(primary_key=PydanticUndefined, nullable=True, foreign_key=oauthusers.provider_user_id, ondelete=PydanticUndefined, unique=PydanticUndefined, index=PydanticUndefined, sa_type=PydanticUndefined, sa_column=PydanticUndefined, sa_column_args=PydanticUndefined, sa_column_kwargs=PydanticUndefined)])
- model_config: ClassVar[ConfigDict] = {'from_attributes': True, 'read_from_attributes': True, 'read_with_orm_mode': True, 'registry': PydanticUndefined, 'table': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- Versioning rules (enforced by