62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
export type Viewer = {
|
|
id: number;
|
|
name: string;
|
|
email: string | null;
|
|
role: string;
|
|
/** Server-Admin (User.role === "admin"). Allein kein Gutschein-Zugriff. */
|
|
isServerAdmin: boolean;
|
|
/** Genau ein Haushalt oder null (nur privater Bestand). */
|
|
householdId: number | null;
|
|
householdName: string | null;
|
|
householdRole: string | null;
|
|
};
|
|
|
|
export type ScopedItem = { householdId: number | null; ownerId: number };
|
|
|
|
/**
|
|
* Prisma-Where für sichtbare Gutscheine/Kontakte:
|
|
* gemeinsamer Bestand des eigenen Haushalts plus eigene private Einträge.
|
|
* Server-Admins ohne Mitgliedschaft sehen nichts.
|
|
*/
|
|
export function scopeWhere(v: Viewer): { OR: Array<Record<string, unknown>> } | { householdId: null; ownerId: number } {
|
|
if (v.householdId !== null) {
|
|
return { OR: [{ householdId: v.householdId }, { householdId: null, ownerId: v.id }] };
|
|
}
|
|
return { householdId: null, ownerId: v.id };
|
|
}
|
|
|
|
/** Darf dieser Betrachter den Eintrag sehen/bearbeiten? */
|
|
export function canAccess(viewer: Viewer, item: ScopedItem): boolean {
|
|
if (item.householdId !== null) return viewer.householdId === item.householdId;
|
|
return item.ownerId === viewer.id;
|
|
}
|
|
|
|
/**
|
|
* Darf dieser Kontakt für einen Gutschein in der Ziel-Ablage verwendet werden?
|
|
* Gleiche Ablage (derselbe Haushalt) oder beide privat im Besitz des Nutzers.
|
|
*/
|
|
export function contactUsableIn(
|
|
viewer: Viewer,
|
|
targetHouseholdId: number | null,
|
|
contact: ScopedItem
|
|
): boolean {
|
|
if (!canAccess(viewer, contact)) return false;
|
|
if (targetHouseholdId !== null) return contact.householdId === targetHouseholdId;
|
|
return contact.householdId === null && contact.ownerId === viewer.id;
|
|
}
|
|
|
|
/** Ziel-Ablage für neue Einträge auflösen: "private" oder "household". */
|
|
export function resolveTarget(
|
|
viewer: Viewer,
|
|
scope: unknown
|
|
): { ok: true; householdId: number | null } | { ok: false; error: string } {
|
|
if (scope === "household") {
|
|
if (viewer.householdId === null) return { ok: false, error: "Kein Haushalt zugeordnet" };
|
|
return { ok: true, householdId: viewer.householdId };
|
|
}
|
|
if (scope === "private" || scope === undefined || scope === null || scope === "") {
|
|
return { ok: true, householdId: null };
|
|
}
|
|
return { ok: false, error: "Unbekannte Ablage" };
|
|
}
|