fix(alerts): persist AlertOperator by value to match the DB enum
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 7s
CI / integration (push) Failing after 2m16s

The alertoperator Postgres enum (migration 0002) was created with the operator
VALUES as labels ('>', '<', …), but the model's Enum(AlertOperator) defaulted to
persisting enum-member NAMES ('gt', 'lt', …) — so inserting any AlertRule against
real Postgres raised 'invalid input value for enum alertoperator: "gt"'. Never
caught because unit tests mock the DB and no integration test inserted a rule
until task 250's. Add values_callable so the ORM round-trips the values.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 14:27:25 -04:00
parent 4771d17f6d
commit 43a5325e69
+7 -1
View File
@@ -32,7 +32,13 @@ class AlertRule(Base):
source_module: Mapped[str] = mapped_column(String(64), nullable=False)
resource_name: Mapped[str] = mapped_column(String(255), nullable=False)
metric_name: Mapped[str] = mapped_column(String(128), nullable=False)
operator: Mapped[AlertOperator] = mapped_column(Enum(AlertOperator), nullable=False)
# The DB enum (migration 0002) stores the operator VALUES (">", "<", …), so
# persist values rather than SQLAlchemy's default enum-member NAMES ("gt"…).
operator: Mapped[AlertOperator] = mapped_column(
Enum(AlertOperator, name="alertoperator",
values_callable=lambda e: [m.value for m in e]),
nullable=False,
)
threshold: Mapped[float] = mapped_column(Float, nullable=False)
consecutive_failures_required: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)