diff --git a/src/app/(dashboard)/connections/page.tsx b/src/app/(dashboard)/connections/page.tsx index 6c1cf2c..7c696f8 100644 --- a/src/app/(dashboard)/connections/page.tsx +++ b/src/app/(dashboard)/connections/page.tsx @@ -1,7 +1,10 @@ import { redirect } from "next/navigation"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { listClinicPricing } from "@/lib/appwrite/clinic-pricing-queries"; +import { + listAllPricingForClinic, + listAllPricingForLab, +} from "@/lib/appwrite/clinic-pricing-queries"; import { listApprovedConnections, listPendingInbound, @@ -37,29 +40,18 @@ export default async function ConnectionsPage() { listPendingOutbound(ctx.tenantId, ctx.user.id), ]); - // Lab side: load pricing rules per approved clinic so the dialog can - // surface existing rules. Clinic side leaves this empty — it's display-only - // for them (see ConnectionsTable). + // Single bulk query for pricing then group client-side. Avoids N+1 across + // approved counterparts (was the main reason the save dialog felt slow — + // every revalidatePath of /connections fanned out one query per peer). + const allPricing = isLab + ? await listAllPricingForLab(ctx.tenantId) + : await listAllPricingForClinic(ctx.tenantId); const pricingByCounterpart = new Map(); - if (isLab) { - const pricingLists = await Promise.all( - approved.map((c) => - listClinicPricing(ctx.tenantId, c.clinicTenantId).then( - (rows) => [c.clinicTenantId, rows] as const, - ), - ), - ); - for (const [id, rows] of pricingLists) pricingByCounterpart.set(id, rows); - } else { - // Clinic side: only its own pricing rules from each lab, read-only - const pricingLists = await Promise.all( - approved.map((c) => - listClinicPricing(c.labTenantId, ctx.tenantId).then( - (rows) => [c.labTenantId, rows] as const, - ), - ), - ); - for (const [id, rows] of pricingLists) pricingByCounterpart.set(id, rows); + for (const row of allPricing) { + const key = isLab ? row.clinicTenantId : row.labTenantId; + const bucket = pricingByCounterpart.get(key); + if (bucket) bucket.push(row); + else pricingByCounterpart.set(key, [row]); } const pricingObject: Record = Object.fromEntries( pricingByCounterpart, diff --git a/src/lib/appwrite/clinic-pricing-actions.ts b/src/lib/appwrite/clinic-pricing-actions.ts index d8f9c9e..a13705a 100644 --- a/src/lib/appwrite/clinic-pricing-actions.ts +++ b/src/lib/appwrite/clinic-pricing-actions.ts @@ -124,7 +124,7 @@ export async function setClinicPricingAction( if (row) { await tablesDB.updateRow(DATABASE_ID, TABLES.clinicPricing, row.$id, payload); - await logAudit({ + void logAudit({ tenantId: ctx.tenantId, userId: ctx.user.id, action: "update", @@ -140,7 +140,7 @@ export async function setClinicPricingAction( payload, pricingPermissions(ctx.tenantId, parsed.data.clinicTenantId), ); - await logAudit({ + void logAudit({ tenantId: ctx.tenantId, userId: ctx.user.id, action: "create", @@ -184,7 +184,7 @@ export async function clearClinicPricingAction( return { ok: false, error: "Yetkiniz yok." }; } await tablesDB.deleteRow(DATABASE_ID, TABLES.clinicPricing, id); - await logAudit({ + void logAudit({ tenantId: ctx.tenantId, userId: ctx.user.id, action: "delete", diff --git a/src/lib/appwrite/clinic-pricing-queries.ts b/src/lib/appwrite/clinic-pricing-queries.ts index 63e93cc..5121f2f 100644 --- a/src/lib/appwrite/clinic-pricing-queries.ts +++ b/src/lib/appwrite/clinic-pricing-queries.ts @@ -29,3 +29,28 @@ export async function listClinicPricingForClinic( ): Promise { return listClinicPricing(labTenantId, clinicTenantId); } + +/** Single bulk query so /connections doesn't N+1 across approved counterparts. */ +export async function listAllPricingForLab( + labTenantId: string, +): Promise { + const { tablesDB } = createAdminClient(); + const result = await tablesDB.listRows({ + databaseId: DATABASE_ID, + tableId: TABLES.clinicPricing, + queries: [Query.equal("labTenantId", labTenantId), Query.limit(500)], + }); + return toPlain(result.rows as unknown as ClinicPricing[]); +} + +export async function listAllPricingForClinic( + clinicTenantId: string, +): Promise { + const { tablesDB } = createAdminClient(); + const result = await tablesDB.listRows({ + databaseId: DATABASE_ID, + tableId: TABLES.clinicPricing, + queries: [Query.equal("clinicTenantId", clinicTenantId), Query.limit(500)], + }); + return toPlain(result.rows as unknown as ClinicPricing[]); +}