feat(ops): health-fail alerts, optional DB backup, admin UX polish
Wire jobs-worker health probes to Discord/email alerts with cooldown, optional mysqldump, rate-limit /api/health, mark-all-read alerts, ConfirmDialog on destructive admin actions, and raise coverage floors. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
3bd712e744
commit
725e1cb338
16 files changed
+327
-32
No files matched your search
@@ -232,6 +232,33 @@ export function emulatorOffline(detail?: string): Promise<SendAlertResult> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Raise an ERROR alert when ops health is degraded (DB / Redis / emulator).
|
||||
*/
|
||||
export function healthDegraded(parts: {
|
||||
database: boolean;
|
||||
redis: boolean | null;
|
||||
emulator: boolean;
|
||||
}): Promise<SendAlertResult> {
|
||||
const failed: string[] = [];
|
||||
if (!parts.database) failed.push("database");
|
||||
if (parts.redis === false) failed.push("redis");
|
||||
if (!parts.emulator) failed.push("emulator");
|
||||
return sendAlert({
|
||||
type: "health",
|
||||
severity: parts.database ? "error" : "critical",
|
||||
message:
|
||||
failed.length > 0
|
||||
? `Ops health degraded: ${failed.join(", ")} unavailable.`
|
||||
: "Ops health degraded.",
|
||||
context: {
|
||||
database: parts.database,
|
||||
redis: parts.redis,
|
||||
emulator: parts.emulator,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Raise a WARNING alert that a possible DDoS / abusive request pattern was
|
||||
* detected from a single IP (count = requests seen in the sampling window).
|
||||
|
||||
@@ -179,6 +179,23 @@ describe("staff smoke contract", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("ships ops health alerts, optional DB backup, and health rate limit", () => {
|
||||
const worker = readFileSync("scripts/jobs-worker.ts", "utf8");
|
||||
expect(worker).toContain("checkOpsHealth");
|
||||
expect(worker).toContain("healthDegraded");
|
||||
expect(worker).toContain("backupDatabase");
|
||||
expect(readFileSync("src/lib/services/alert.ts", "utf8")).toContain(
|
||||
"healthDegraded",
|
||||
);
|
||||
expect(readFileSync("src/app/api/health/route.ts", "utf8")).toContain(
|
||||
"rateLimit",
|
||||
);
|
||||
expect(readFileSync("src/actions/admin-alerts.ts", "utf8")).toContain(
|
||||
"markAllAlertsRead",
|
||||
);
|
||||
expect(readFileSync("src/env.ts", "utf8")).toContain("DB_BACKUP_DIR");
|
||||
});
|
||||
|
||||
it("documents local-only photo file purge", () => {
|
||||
expect(readFileSync("src/app/admin/photos/page.tsx", "utf8")).toContain(
|
||||
"purgeHint",
|
||||
|
||||
Reference in new issue
Block a user