vika-server / cbh /api /rules /models.py
brestok's picture
Refactor project structure and enhance batch processing capabilities
c2ea771
Raw History Blame Contribute Delete
2.05 kB
from datetime import datetime
from pydantic import Field
from cbh.api.common.dto import TradeDirection
from cbh.api.rules.dto import RuleAction, RuleScope
from cbh.core.database import MongoBaseModel
class RuleModel(MongoBaseModel):
"""A broker's own logic, written down once and replayed on every line.
Matching is deterministic and narrow: every condition that is set must
hold. A rule with no conditions at all is refused on the way in, because it
would silently touch the whole pack.
"""
name: str
description: str | None = None
scope: RuleScope = RuleScope.CLIENT
clientProfileId: str | None = None
active: bool = True
codePrefix: str | None = None
originCountry: str | None = None
destinationCountry: str | None = None
direction: TradeDirection | None = None
descriptionContains: str | None = None
action: RuleAction = RuleAction.NOTE
pinnedCode: str | None = None
documentCodes: list[str] = Field(default_factory=list)
note: str | None = None
createdFromBatchId: str | None = None
createdFromRowIndex: int | None = None
createdBy: str | None = None
hitCount: int = 0
datetimeLastHit: datetime | None = None
datetimeInserted: datetime = Field(default_factory=datetime.now)
datetimeUpdated: datetime = Field(default_factory=datetime.now)
@property
def conditions(self) -> dict[str, str]:
"""The conditions actually set, for display and for specificity."""
present = {
"codePrefix": self.codePrefix,
"originCountry": self.originCountry,
"destinationCountry": self.destinationCountry,
"direction": self.direction.name if self.direction else None,
"descriptionContains": self.descriptionContains,
}
return {key: value for key, value in present.items() if value}
@property
def specificity(self) -> int:
"""How many conditions a rule sets. The narrowest rule wins a conflict."""
return len(self.conditions)