Files
shopdb-flask/plugins/notifications/models/acknowledgement.py
Proudlock 381cc6c845 Add fleet alert notifications for shop floor PCs
Fleet alerts push server notifications to endpoint PCs via the command pipe.
Operators acknowledge alerts via toast UI in the tray. Backend tracks
acknowledgements per asset to prevent re-showing dismissed alerts.

Backend: alertfleet/alertscope/alerttimeout columns, GET/POST /api/endpoints/alerts,
NotificationAcknowledgement model with unique constraint, hostname validation.

Frontend: Alert Fleet checkbox in notification form.

Agent: FleetAlertClient polls alerts, FleetAlertStore tracks acknowledged IDs,
FleetAlertForm displays toast (no auto-dismiss), FleetAlertWorker 60s polling.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-08 16:19:14 -04:00

53 lines
1.7 KiB
Python

"""Notification acknowledgement tracking for fleet alerts."""
from datetime import datetime, timezone
from shopdb.api import db
class NotificationAcknowledgement(db.Model):
"""
Tracks which assets have acknowledged fleet alerts.
Matches existing notificationacknowledgements table.
"""
__tablename__ = 'notificationacknowledgements'
__table_args__ = (
db.UniqueConstraint('notificationid', 'assetid', name='uq_notification_asset'),
)
notificationacknowledgementid = db.Column(db.Integer, primary_key=True)
notificationid = db.Column(
db.Integer,
db.ForeignKey('notifications.notificationid', ondelete='CASCADE'),
nullable=False,
index=True
)
assetid = db.Column(
db.Integer,
db.ForeignKey('assets.assetid', ondelete='CASCADE'),
nullable=False,
index=True
)
acknowledgedat = db.Column(
db.DateTime,
nullable=False,
default=lambda: datetime.now(timezone.utc).replace(tzinfo=None)
)
# Relationships
notification = db.relationship('Notification', backref='acknowledgements')
asset = db.relationship('Asset', backref='notification_acknowledgements')
def __repr__(self):
return f"<NotificationAcknowledgement {self.notificationacknowledgementid}>"
def to_dict(self):
"""Convert to dictionary following ShopDB patterns."""
return {
'notificationacknowledgementid': self.notificationacknowledgementid,
'notificationid': self.notificationid,
'assetid': self.assetid,
'acknowledgedat': self.acknowledgedat.replace(
tzinfo=timezone.utc
).isoformat() if self.acknowledgedat else None
}