feat(260929-if2): Erinnerungen anlegen und zur Faelligkeit benachrichtigen (Tracer)
- Reminder-Tabelle mit Zeilenschutz (Mandant+Benutzer, Systemlesen fuer den E-Mail-Planer), API reminders (Liste, Anlegen) - Kachel "Erinnerungen", globaler Melder im Portalrahmen (Browser und Desktop, je Faelligkeit einmal) - Desktop: Laufzeit-Berechtigung fuer Benachrichtigungen nur fuer die gespeicherte Server-Adresse - Zugriffsklassifikation nachgemessen Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Erinnerungen — API-Klient (quick-260929-if2). Spiegelt den
|
||||
* `RemindersController` der API. Alle Aufrufe mit `credentials: 'include'`
|
||||
* (Cookie-Anmeldung), Muster `favorites-api.ts`.
|
||||
*/
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
||||
|
||||
/** Ereignis nach jeder erfolgreichen Aenderung — der globale Melder laedt daraufhin neu. */
|
||||
export const REMINDERS_CHANGED_EVENT = 'tessera:reminders-changed';
|
||||
|
||||
/** Eine Erinnerung; Zeitangaben als ISO-Zeichenketten (so liefert sie die API). */
|
||||
export interface Reminder {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
dueAt: string;
|
||||
emailEnabled: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/** Ein abgewiesener Aufruf; `status` ist der HTTP-Status (401, 404, 409 ...). */
|
||||
export class ReminderRequestError extends Error {
|
||||
public readonly status: number;
|
||||
|
||||
constructor(status: number) {
|
||||
super(`Reminder request failed (${status})`);
|
||||
this.name = 'ReminderRequestError';
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${API_URL}${path}`, { credentials: 'include', ...init });
|
||||
if (!res.ok) throw new ReminderRequestError(res.status);
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
function jsonInit(method: string, body: unknown): RequestInit {
|
||||
return {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
};
|
||||
}
|
||||
|
||||
/** Die eigenen Erinnerungen, die naechste Faelligkeit zuerst. */
|
||||
export function listReminders(): Promise<Reminder[]> {
|
||||
return request<Reminder[]>('/reminders');
|
||||
}
|
||||
|
||||
export interface ReminderInput {
|
||||
title: string;
|
||||
description?: string;
|
||||
/** ISO-8601-Zeitpunkt. */
|
||||
dueAt: string;
|
||||
}
|
||||
|
||||
export function createReminder(input: ReminderInput): Promise<Reminder> {
|
||||
return request<Reminder>('/reminders', jsonInit('POST', input));
|
||||
}
|
||||
Reference in New Issue
Block a user