Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions development_guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I acknowledge and will strictly adhere to the caching strategy constraints outlined. My approach will exclusively use the `use cache` directive, prioritize multi-tenancy security by passing `tenantId` as an argument, implement granular `cacheTag` invalidation, recommend appropriate cache lifetimes, and clearly distinguish between static and dynamic components using Suspense.
35 changes: 10 additions & 25 deletions src/db/actions/dashboard/products/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,15 @@ import { dashboardActionClient } from "@/lib/safe-action-clients/dashboard-clien
import { revalidatePath } from "next/cache";
import { checkPermission } from "@/lib/auth/check-permission";

import {
getCachedDashboardProduct,
getCachedDashboardProducts,
} from "./cached-actions";

export const getDashboardProducts = dashboardActionClient.action(
async ({ ctx }) => {
checkPermission(ctx, "products:read");

const storeId = ctx.storeId;

const products = await db.query.ProductTable.findMany({
where: eq(ProductTable.store_id, storeId),
columns: {
store_id: false,
},
orderBy: [desc(ProductTable.updated_at)],
});

return products;
return await getCachedDashboardProducts(ctx.storeId);
},
);

Expand All @@ -35,17 +29,7 @@ export const getDashboardProduct = dashboardActionClient
checkPermission(ctx, "products:read");
const slug = parsedInput.slug;

const product = await db.query.ProductTable.findFirst({
where: and(
eq(ProductTable.slug, slug),
eq(ProductTable.store_id, ctx.storeId),
),
columns: {
store_id: false,
},
});

return product;
return await getCachedDashboardProduct(ctx.storeId, slug);
});

export const updateDashboardProduct = dashboardActionClient
Expand Down Expand Up @@ -73,6 +57,7 @@ export const updateDashboardProduct = dashboardActionClient
),
)
.returning({ id: ProductTable.id });
revalidatePath("/products");
return results[0];
});

Expand Down Expand Up @@ -119,7 +104,7 @@ export const createDashboardProduct = dashboardActionClient
if (!product[0].id) {
return { success: false, error: "Product not created." };
}

revalidatePath("/products");
return { success: true, message: "Product created" };
});

Expand All @@ -146,6 +131,6 @@ export const updateDashboardProductDetails = dashboardActionClient
eq(ProductTable.store_id, ctx.storeId),
),
);

revalidatePath("/products");
return { success: true, message: "Product updated" };
});
34 changes: 34 additions & 0 deletions src/db/actions/dashboard/products/cached-actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use cache";

import { db } from "@/db/db";
import { ProductTable } from "@/db/schema";
import { and, desc, eq } from "drizzle-orm";
import { cacheTag } from "next/cache";

export async function getCachedDashboardProducts(storeId: string) {
cacheTag(`tenant-${storeId}:products`);

const products = await db.query.ProductTable.findMany({
where: eq(ProductTable.store_id, storeId),
columns: {
store_id: false,
},
orderBy: [desc(ProductTable.updated_at)],
});

return products;
}

export async function getCachedDashboardProduct(storeId: string, slug: string) {
cacheTag(`tenant-${storeId}:products`);
cacheTag(`tenant-${storeId}:product-${slug}`);

const product = await db.query.ProductTable.findFirst({
where: and(eq(ProductTable.slug, slug), eq(ProductTable.store_id, storeId)),
columns: {
store_id: false,
},
});

return product;
}
Loading