feat: audit log, device tags, maintenance windows (v0.11.3 Beta)

- Audit log: middleware captures all write operations, paginated admin UI in Settings
- Device tags: full CRUD, device assignment, filter bar and chips on Devices page
- Maintenance windows: alert suppression during planned downtime, Settings management UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2GT-Rich
2026-05-16 15:33:15 -07:00
co-authored by Claude Sonnet 4.6
parent 6a4ab1fc5f
commit 49ab1b002e
16 changed files with 801 additions and 10 deletions
+13
View File
@@ -73,6 +73,19 @@ export class AlertService {
const rule = await this.getRule(eventType);
if (!rule?.enabled) return;
// Maintenance window suppression — skip if device is in a currently active window
if (ctx.deviceId != null) {
const inMaintenance = await query<{ count: string }>(
`SELECT COUNT(*)::text AS count FROM maintenance_windows
WHERE active = true AND $1 = ANY(device_ids) AND NOW() BETWEEN start_at AND end_at`,
[ctx.deviceId]
).catch(() => [{ count: '0' }]);
if (parseInt(inMaintenance[0]?.count || '0', 10) > 0) {
console.log(`[AlertService] Suppressed ${eventType} for device ${ctx.deviceId} (maintenance window)`);
return;
}
}
// Cooldown check
const cooldownKey = ctx.cooldownKey ?? `${eventType}:${ctx.deviceId ?? 'global'}`;
const cooldownMs = (rule.cooldown_min ?? 15) * 60 * 1000;