"use server"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { AppwriteException, ID, Permission, Role, Query } from "node-appwrite"; import { createAdminClient, createSessionClient } from "./server"; import { DATABASE_ID, TABLES } from "./schema"; import { ACTIVE_TENANT_COOKIE, type WorkspaceState } from "./tenant-types"; function appwriteError(e: unknown): string { if (e instanceof AppwriteException) { if (e.type === "team_already_exists") return "Bu isimde bir çalışma alanı zaten var."; if (e.type === "general_unauthorized_scope") return "Yetki hatası. Tekrar giriş yapın."; return e.message || "Beklenmeyen bir hata oluştu."; } return "Bağlantı hatası. Tekrar deneyin."; } async function setActiveTenantCookie(tenantId: string) { (await cookies()).set(ACTIVE_TENANT_COOKIE, tenantId, { path: "/", httpOnly: true, sameSite: "strict", secure: process.env.NODE_ENV === "production", maxAge: 60 * 60 * 24 * 365, }); } export async function createWorkspaceAction( _prev: WorkspaceState, formData: FormData, ): Promise { const companyName = String(formData.get("companyName") ?? "").trim(); const companyPhone = String(formData.get("companyPhone") ?? "").trim() || undefined; if (!companyName) { return { ok: false, error: "Ofis adı zorunlu." }; } let teamId: string | null = null; const admin = createAdminClient(); try { const session = await createSessionClient(); const user = await session.account.get(); const team = await session.teams.create(ID.unique(), companyName, ["owner"]); teamId = team.$id; await admin.tablesDB.createRow( DATABASE_ID, TABLES.tenantSettings, ID.unique(), { tenantId: teamId, officeName: companyName, phone: companyPhone, createdBy: user.$id, }, [ Permission.read(Role.team(teamId)), Permission.update(Role.team(teamId, "owner")), Permission.update(Role.team(teamId, "admin")), Permission.delete(Role.team(teamId, "owner")), ], ); await session.account.updatePrefs({ ...(user.prefs ?? {}), activeTenant: teamId, }); await setActiveTenantCookie(teamId); } catch (e) { if (teamId) { try { await admin.teams.delete(teamId); } catch { // best-effort cleanup; original error is what we surface } } return { ok: false, error: appwriteError(e) }; } redirect("/dashboard"); } export async function importWorkspaceAction( _prev: WorkspaceState, formData: FormData, ): Promise { const teamId = String(formData.get("teamId") ?? "").trim(); if (!teamId) return { ok: false, error: "Geçersiz istek." }; try { const { account, teams, tablesDB } = await createSessionClient(); const user = await account.get(); const allTeams = await teams.list(); const team = allTeams.teams.find((t) => t.$id === teamId); if (!team) return { ok: false, error: "Çalışma alanı bulunamadı." }; const existing = await tablesDB.listRows({ databaseId: DATABASE_ID, tableId: TABLES.tenantSettings, queries: [Query.equal("tenantId", teamId), Query.limit(1)], }); if (existing.total > 0) return { ok: false, error: "Bu çalışma alanı zaten mevcut." }; const admin = createAdminClient(); await admin.tablesDB.createRow( DATABASE_ID, TABLES.tenantSettings, ID.unique(), { tenantId: teamId, officeName: team.name, createdBy: user.$id, defaultCurrency: "TRY", }, [ Permission.read(Role.team(teamId)), Permission.update(Role.team(teamId, "owner")), Permission.update(Role.team(teamId, "admin")), Permission.delete(Role.team(teamId, "owner")), ], ); await account.updatePrefs({ ...(user.prefs ?? {}), activeTenant: teamId }); await setActiveTenantCookie(teamId); } catch (e) { return { ok: false, error: appwriteError(e) }; } redirect("/dashboard"); } export async function setActiveTenantAction(tenantId: string) { try { const { account, teams, tablesDB } = await createSessionClient(); const user = await account.get(); const allTeams = await teams.list(); const isMember = allTeams.teams.some((t) => t.$id === tenantId); if (!isMember) { return { ok: false, error: "Bu çalışma alanına erişiminiz yok." }; } // Verify this team belongs to this app (not a team from another KovakSoft product) const settingsCheck = await tablesDB.listRows({ databaseId: DATABASE_ID, tableId: TABLES.tenantSettings, queries: [Query.equal("tenantId", tenantId), Query.limit(1)], }); if (settingsCheck.total === 0) { return { ok: false, error: "Bu çalışma alanına erişiminiz yok." }; } await account.updatePrefs({ ...(user.prefs ?? {}), activeTenant: tenantId }); await setActiveTenantCookie(tenantId); return { ok: true }; } catch (e) { return { ok: false, error: appwriteError(e) }; } }