fix: purge deleted-stack notifications from panel and ticker (#1674)

* fix: purge deleted-stack notifications from panel and ticker

Stack delete already cascaded scans and drift but left notification_history rows, so the bell and Activity ticker kept showing the deleted stack. Purge those rows in the shared deletion lifecycle, invalidate connected clients, and drop node-scoped in-memory rows immediately.

* fix: target remote notification purge by hub node id

Remote stack-deleted invalidations always reconcile with hub rn.id, and
notification refetch preserves failed node slices instead of wiping them.
This commit is contained in:
Anso
2026-07-22 20:00:45 -04:00
committed by GitHub
parent 394e68671d
commit 698b7d0713
9 changed files with 644 additions and 14 deletions
@@ -18,6 +18,7 @@ import DockerController from './DockerController';
import { FileSystemService } from './FileSystemService';
import { NodeRegistry } from './NodeRegistry';
import { MeshService } from './MeshService';
import { NotificationService } from './NotificationService';
import { StackOpLockService, stackOpSkipMessage } from './StackOpLockService';
import { getErrorMessage } from '../utils/errors';
import { sanitizeForLog } from '../utils/safeLog';
@@ -248,6 +249,7 @@ export class DeployedStackDeletionService {
db.deleteStackExposure(nodeId, stackName);
db.deleteStackProjectEnvFiles(nodeId, stackName);
db.deleteStackScans(nodeId, stackName);
db.deleteNotificationsForStack(nodeId, stackName);
} catch (dbErr) {
console.error(
'[DeployedStackDeletion] Secondary DB cleanup failed for %s; recovery rows already retired:',
@@ -272,6 +274,14 @@ export class DeployedStackDeletionService {
}
await this.sweepReadyIntent(intentId);
NotificationService.getInstance().broadcastEvent({
type: 'state-invalidate',
scope: 'notifications',
action: 'stack-deleted',
nodeId,
stackName,
ts: Date.now(),
});
return { ok: true };
}