"use server"; import { revalidatePath } from "next/cache"; import { z } from "zod"; import { getSessionUser } from "@/lib/auth"; import { addCollection, addTitle, createOrder, createUniverse, deleteOrder, removeTitle, renameOrder, renameUniverse, setOrderPositions, shareUniverse, trashUniverse, unshareUniverse, UniverseError, } from "@/lib/universes"; /** Server-Aktionen für Universen. Zugriffsrechte prüft die Domänenschicht. */ export type UniverseActionResult = { ok: boolean; message?: string; id?: string }; async function run( fn: (userId: string) => Promise<{ message?: string; id?: string } | void>, ): Promise { const user = await getSessionUser(); if (!user) return { ok: false, message: "Bitte melde dich an." }; try { const result = (await fn(user.id)) ?? {}; revalidatePath("/universen", "layout"); revalidatePath("/", "layout"); return { ok: true, message: result.message, id: result.id }; } catch (error) { if (error instanceof UniverseError) return { ok: false, message: error.message }; console.error("Universums-Aktion fehlgeschlagen:", error); return { ok: false, message: "Das hat nicht geklappt. Bitte noch einmal versuchen." }; } } const id = z.string().min(1).max(64); const name = z.string().trim().min(1).max(120); export async function createUniverseAction(rawName: string, description?: string) { return run(async (userId) => { const universe = await createUniverse(userId, name.parse(rawName), description); return { message: `„${universe.name}" angelegt`, id: universe.id }; }); } export async function renameUniverseAction( universeId: string, data: { name?: string; description?: string | null }, ) { return run(async (userId) => { await renameUniverse(userId, id.parse(universeId), { ...(data.name !== undefined ? { name: name.parse(data.name) } : {}), ...(data.description !== undefined ? { description: z.string().max(2000).nullable().parse(data.description) } : {}), }); return { message: "Gespeichert" }; }); } export async function trashUniverseAction(universeId: string) { return run(async (userId) => { await trashUniverse(userId, id.parse(universeId)); return { message: "Universum gelöscht" }; }); } export async function addTitleToUniverseAction(universeId: string, titleId: string) { return run(async (userId) => { await addTitle(userId, id.parse(universeId), id.parse(titleId)); return { message: "Aufgenommen" }; }); } export async function removeFromUniverseAction(universeId: string, itemId: string) { return run(async (userId) => { await removeTitle(userId, id.parse(universeId), id.parse(itemId)); return { message: "Aus dem Universum entfernt" }; }); } export async function addCollectionAction(universeId: string, tmdbCollectionId: number) { return run(async (userId) => { const added = await addCollection( userId, id.parse(universeId), z.number().int().parse(tmdbCollectionId), ); return { message: added === 0 ? "Alles daraus war schon drin" : `${added} ${added === 1 ? "Titel" : "Titel"} übernommen`, }; }); } export async function createOrderAction(universeId: string, rawName: string) { return run(async (userId) => { const order = await createOrder(userId, id.parse(universeId), name.parse(rawName)); return { message: "Reihenfolge angelegt", id: order.id }; }); } export async function renameOrderAction(orderId: string, rawName: string) { return run(async (userId) => { await renameOrder(userId, id.parse(orderId), name.parse(rawName)); return { message: "Umbenannt" }; }); } export async function deleteOrderAction(orderId: string) { return run(async (userId) => { await deleteOrder(userId, id.parse(orderId)); return { message: "Reihenfolge gelöscht" }; }); } export async function reorderAction(orderId: string, itemIds: string[]) { return run(async (userId) => { await setOrderPositions(userId, id.parse(orderId), z.array(id).max(1000).parse(itemIds)); return { message: "Reihenfolge gespeichert" }; }); } export async function shareUniverseAction( universeId: string, email: string, permission: "READ" | "WRITE", ) { return run(async (userId) => { const target = await shareUniverse( userId, id.parse(universeId), z.string().trim().email().parse(email), z.enum(["READ", "WRITE"]).parse(permission), ); return { message: `Mit ${target.name} geteilt` }; }); } export async function unshareUniverseAction(universeId: string, memberId: string) { return run(async (userId) => { await unshareUniverse(userId, id.parse(universeId), id.parse(memberId)); return { message: "Freigabe aufgehoben" }; }); }