36 lines
1.3 KiB
Python
36 lines
1.3 KiB
Python
import uuid
|
|
|
|
from sqlalchemy import Column, DateTime, Integer, String, Text, func
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
|
|
from app.config.database import Base
|
|
|
|
|
|
class AlertState(Base):
|
|
"""One open condition, and when it was last shouted about.
|
|
|
|
Not tenant-scoped, deliberately: a stuck outbox or a detected token reuse
|
|
belongs to the platform, not to any one workspace, and the people who act on
|
|
them are the ones who can already see everything.
|
|
"""
|
|
|
|
__tablename__ = "alert_state"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
alert_key = Column(String(60), nullable=False, unique=True, index=True)
|
|
severity = Column(String(20), nullable=False)
|
|
detail = Column(Text, nullable=True)
|
|
observed = Column(Integer, nullable=True)
|
|
|
|
opened_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
|
last_notified_at = Column(DateTime(timezone=True), nullable=True)
|
|
notify_count = Column(Integer, nullable=False, server_default="0", default=0)
|
|
resolved_at = Column(DateTime(timezone=True), nullable=True)
|
|
|
|
@property
|
|
def is_open(self) -> bool:
|
|
return self.resolved_at is None
|
|
|
|
def __repr__(self) -> str:
|
|
return f"<AlertState {self.alert_key} {'open' if self.is_open else 'resolved'}>"
|