feat(accounts): hesaplar (KMH, kredi kartı, yemek kartı, yalnızca ben)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 02:57:58 +03:00
parent 380ddaf303
commit 8dd5fd42e3
9 changed files with 1805 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
"use server";
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { tr } from "@/i18n/tr";
import { fail, type ActionResult } from "@/lib/action-result";
import { getHouseholdActionContext } from "@/lib/dal";
import { accountFormSchema } from "@/shared/schemas/account";
import { createAccount, reorderAccount, setAccountArchived, updateAccount } from "./service";
const PATH = "/hesaplar";
const idSchema = z.string().regex(/^[a-f0-9]{24}$/i);
/** zod hatalarını alan bazlı mesajlara çevirir (formda gösterilir). */
function fieldErrors(error: z.ZodError) {
const out: Record<string, string> = {};
for (const issue of error.issues) {
const key = String(issue.path[0] ?? "");
if (key && !out[key]) out[key] = issue.message;
}
return out;
}
export async function createAccountAction(input: unknown): Promise<ActionResult<{ id: string }>> {
const ctx = await getHouseholdActionContext("owner");
if (!ctx) return fail(tr.common.unauthorized);
const parsed = accountFormSchema.safeParse(input);
if (!parsed.success) return fail(tr.adminUsers.errors.checkFields, fieldErrors(parsed.error));
const result = await createAccount(ctx.user.id, ctx.household.id, parsed.data);
if (result.ok) revalidatePath("/", "layout");
return result;
}
export async function updateAccountAction(
accountId: unknown,
input: unknown,
): Promise<ActionResult> {
const ctx = await getHouseholdActionContext("owner");
if (!ctx) return fail(tr.common.unauthorized);
const id = idSchema.safeParse(accountId);
const parsed = accountFormSchema.safeParse(input);
if (!id.success) return fail(tr.common.notFound);
if (!parsed.success) return fail(tr.adminUsers.errors.checkFields, fieldErrors(parsed.error));
const result = await updateAccount(ctx.user.id, ctx.household.id, id.data, parsed.data);
if (result.ok) revalidatePath("/", "layout");
return result;
}
export async function setAccountArchivedAction(
accountId: unknown,
archived: unknown,
): Promise<ActionResult> {
const ctx = await getHouseholdActionContext("owner");
if (!ctx) return fail(tr.common.unauthorized);
const id = idSchema.safeParse(accountId);
const a = z.boolean().safeParse(archived);
if (!id.success || !a.success) return fail(tr.common.genericError);
const result = await setAccountArchived(ctx.user.id, ctx.household.id, id.data, a.data);
if (result.ok) revalidatePath(PATH);
return result;
}
export async function reorderAccountAction(
accountId: unknown,
direction: unknown,
): Promise<ActionResult> {
const ctx = await getHouseholdActionContext("owner");
if (!ctx) return fail(tr.common.unauthorized);
const id = idSchema.safeParse(accountId);
const dir = z.enum(["up", "down"]).safeParse(direction);
if (!id.success || !dir.success) return fail(tr.common.genericError);
const result = await reorderAccount(ctx.user.id, ctx.household.id, id.data, dir.data);
if (result.ok) revalidatePath(PATH);
return result;
}