"use server"; import { revalidatePath } from "next/cache"; import { AppwriteException, ID, Permission, Query, Role } from "node-appwrite"; import { z } from "zod"; import { logAudit } from "./audit"; import { DATABASE_ID, TABLES, type TenantSettings } from "./schema"; import { createAdminClient } from "./server"; import { requireRole, requireTenant } from "./tenant-guard"; import type { WorkspaceSettingsState } from "./workspace-types"; import { workspaceSettingsSchema } from "@/lib/validation/workspace"; function appwriteError(e: unknown): string { if (e instanceof AppwriteException) return e.message || "Beklenmeyen hata."; return "Bağlantı hatası. Tekrar deneyin."; } function flattenErrors(err: z.ZodError): Record { const out: Record = {}; for (const issue of err.issues) { const key = issue.path.join("."); if (key && !out[key]) out[key] = issue.message; } return out; } function pickFormFields(formData: FormData) { return { officeName: String(formData.get("officeName") ?? "").trim(), phone: String(formData.get("phone") ?? "").trim() || undefined, email: String(formData.get("email") ?? "").trim() || undefined, address: String(formData.get("address") ?? "").trim() || undefined, defaultCurrency: String(formData.get("defaultCurrency") ?? "TRY").trim(), }; } export async function updateWorkspaceSettingsAction( _prev: WorkspaceSettingsState, formData: FormData, ): Promise { let ctx; try { ctx = await requireTenant(); requireRole(ctx, ["owner", "admin"]); } catch { return { ok: false, error: "Düzenleme yetkiniz yok." }; } const fields = pickFormFields(formData); if (!fields.officeName) { return { ok: false, error: "Ofis adı zorunlu.", fieldErrors: { officeName: "Ofis adı zorunlu." } }; } const parsed = { data: fields, success: true }; try { const { tablesDB } = createAdminClient(); const existing = await tablesDB.listRows({ databaseId: DATABASE_ID, tableId: TABLES.tenantSettings, queries: [Query.equal("tenantId", ctx.tenantId), Query.limit(1)], }); const row = existing.rows[0] as unknown as TenantSettings | undefined; if (row) { await tablesDB.updateRow(DATABASE_ID, TABLES.tenantSettings, row.$id, parsed.data); await logAudit({ tenantId: ctx.tenantId, userId: ctx.user.id, action: "update", entityType: "tenant_settings", entityId: row.$id, changes: parsed.data, }); } else { const created = await tablesDB.createRow( DATABASE_ID, TABLES.tenantSettings, ID.unique(), { tenantId: ctx.tenantId, ...parsed.data, createdBy: ctx.user.id }, [ Permission.read(Role.team(ctx.tenantId)), Permission.update(Role.team(ctx.tenantId, "owner")), Permission.update(Role.team(ctx.tenantId, "admin")), Permission.delete(Role.team(ctx.tenantId, "owner")), ], ); await logAudit({ tenantId: ctx.tenantId, userId: ctx.user.id, action: "create", entityType: "tenant_settings", entityId: created.$id, changes: parsed.data, }); } } catch (e) { return { ok: false, error: appwriteError(e) }; } // Tenant name shows up everywhere — revalidate broadly revalidatePath("/", "layout"); return { ok: true }; }