feat(nextcloud-status): erneute Prüfung nach Ausfall und Hinweis auf der Kachel
- Wiederholungsauftrag jede Minute für Clouds mit einem Fehlschlag älter als fünf Minuten - Neue Adresse setzt den Prüfstand zurück, der gemeldete Zustand bleibt - Kachel: Hinweis Prüfung fehlgeschlagen, Fehlercodes als lesbarer Text mit Tooltip Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ export const PUBLIC_SELECT = {
|
||||
edition: true,
|
||||
errorKind: true,
|
||||
errorDetail: true,
|
||||
consecutiveFailures: true,
|
||||
} as const;
|
||||
|
||||
type PublicRow = {
|
||||
@@ -56,6 +57,7 @@ type PublicRow = {
|
||||
edition: string | null;
|
||||
errorKind: string | null;
|
||||
errorDetail: string | null;
|
||||
consecutiveFailures: number;
|
||||
};
|
||||
|
||||
export interface NextcloudInstanceView {
|
||||
@@ -74,6 +76,11 @@ export interface NextcloudInstanceView {
|
||||
edition: string | null;
|
||||
errorKind: string | null;
|
||||
errorDetail: string | null;
|
||||
/**
|
||||
* Genau ein Fehlschlag in Folge: die Kachel zeigt den letzten guten Stand
|
||||
* mit Hinweis, die Wiederholung folgt in wenigen Minuten (L-03).
|
||||
*/
|
||||
pendingRetry: boolean;
|
||||
};
|
||||
rating: NextcloudRating;
|
||||
/**
|
||||
@@ -125,6 +132,7 @@ export class NextcloudStatusService {
|
||||
|
||||
private toView(row: PublicRow, reference: NextcloudReference | null): NextcloudInstanceView {
|
||||
const status = {
|
||||
pendingRetry: row.consecutiveFailures === 1,
|
||||
checkedAt: row.lastCheckedAt ? row.lastCheckedAt.toISOString() : null,
|
||||
reachable: row.reachable,
|
||||
maintenance: row.maintenance,
|
||||
@@ -271,6 +279,22 @@ export class NextcloudStatusService {
|
||||
if (baseUrl !== existing.baseUrl) {
|
||||
data.baseUrl = baseUrl;
|
||||
urlChanged = true;
|
||||
// Neue Adresse: der alte Pruefstand gilt nicht mehr (D-K8). `alertState`
|
||||
// bleibt bewusst unberuehrt — wird eine kaputte Adresse korrigiert und
|
||||
// antwortet die neue, geht "wieder in Ordnung" an die Abonnenten.
|
||||
Object.assign(data, {
|
||||
reachable: null,
|
||||
maintenance: null,
|
||||
needsDbUpgrade: null,
|
||||
versionString: null,
|
||||
edition: null,
|
||||
productName: null,
|
||||
errorKind: null,
|
||||
errorDetail: null,
|
||||
lastCheckedAt: null,
|
||||
consecutiveFailures: 0,
|
||||
firstFailureAt: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,11 +427,25 @@ export class NextcloudStatusService {
|
||||
* Leserecht ueber `system_read_policy ... FOR SELECT` der Migration
|
||||
* 20261002150000): nur Kennung und Mandant ALLER Clouds, nie Logo-Bytes oder
|
||||
* Adressen. Geprueft und geschrieben wird danach je Cloud an ihren eigenen
|
||||
* Mandanten gebunden (`checkInstance`).
|
||||
* Mandanten gebunden (`checkInstance`). Mit `retryDueBefore` (Wiederholung
|
||||
* nach dem ersten Fehlschlag, quick-261002-kxc) filtert dieselbe Abfrage auf
|
||||
* Clouds mit genau einem Fehlschlag, der vor diesem Zeitpunkt lag.
|
||||
*/
|
||||
async loadAllInstancesForScheduler(): Promise<{ id: string; tenantId: string }[]> {
|
||||
async loadAllInstancesForScheduler(filter?: {
|
||||
retryDueBefore: Date;
|
||||
}): Promise<{ id: string; tenantId: string }[]> {
|
||||
const systemPrisma = forSystem(this.prisma);
|
||||
return systemPrisma.nextcloudInstance.findMany({
|
||||
// Wiederholungsauftrag (D-K3): nur Clouds mit genau einem Fehlschlag, dessen
|
||||
// Zeitpunkt lange genug zurueckliegt — derselbe Systemlesezugriff, kein neuer.
|
||||
...(filter
|
||||
? {
|
||||
where: {
|
||||
consecutiveFailures: 1,
|
||||
firstFailureAt: { lte: filter.retryDueBefore },
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
select: { id: true, tenantId: true },
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user