Files

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" };
}