feat(nextcloud-status): Benachrichtigung abonnieren und Mail bei Störung

- Glocke je Kachel (persönlich, Benutzen-Ebene), Tabelle NextcloudAlertSubscription mit RLS
- Zwei-Fehlschläge-Regel und gemeldeter Zustand auf der Zeile, Anspruch vor dem Mailversand
- Mail (nur Deutsch) über MailService, bis zu drei Versuche, Zugriff beim Senden erneut geprüft
- Fehlercodes in der Mail als lesbarer Hinweis

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 15:23:34 +02:00
parent 6829c44464
commit faed0d760f
23 changed files with 1796 additions and 103 deletions
+21
View File
@@ -55,6 +55,12 @@ export interface NextcloudInstance {
logoVersion: number;
status: NextcloudInstanceStatus;
rating: NextcloudRating;
/**
* Glocke des angemeldeten Benutzers (quick-261002-kxc). Nur die Listen-
* antworten tragen das Feld; fehlt es (Einzelantwort), gilt der bisherige
* Stand der Kachel. Ohne Angabe = aus.
*/
subscribed?: boolean;
}
export interface NextcloudList {
@@ -174,3 +180,18 @@ export async function removeLogo(id: string): Promise<NextcloudInstance> {
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to remove logo'));
return res.json();
}
/** POST /instances/:id/subscription — Glocke "Benachrichtigen" einschalten (jeder mit Modulzugriff). */
export async function subscribe(id: string): Promise<void> {
const res = await fetch(`${BASE}/${id}/subscription`, { method: 'POST', credentials: 'include' });
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to subscribe'));
}
/** DELETE /instances/:id/subscription — Glocke ausschalten. */
export async function unsubscribe(id: string): Promise<void> {
const res = await fetch(`${BASE}/${id}/subscription`, {
method: 'DELETE',
credentials: 'include',
});
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to unsubscribe'));
}