feat(F-132): completed feature

This commit is contained in:
chattie
2026-08-21 17:45:12 +02:00
parent 3058c81b31
commit f37333bb56
16 changed files with 368 additions and 14 deletions

View File

@@ -4,6 +4,9 @@ import type { Metadata } from 'next';
import { fetchBrandBySlug, fetchProducts, formatPrice } from '@/lib/api';
import { formatRichText } from '@/lib/format-rich-text';
// ISR para fichas de marca (F-132).
export const revalidate = 3600;
interface Props {
params: Promise<{ slug: string }>;
}

View File

@@ -3,6 +3,9 @@ import type { Metadata } from 'next';
import { fetchBrands } from '@/lib/api';
import { CmsBlock } from '@/components/content/CmsBlock';
// ISR para /brands (F-132).
export const revalidate = 3600;
export const metadata: Metadata = {
title: 'Marcas — mercadodevida',
description: 'Todas las marcas de productos naturales y ecológicos.',

View File

@@ -4,6 +4,9 @@ import type { Metadata } from 'next';
import { fetchCategoryBySlug, fetchProducts, fetchBrands } from '@/lib/api';
import { formatRichText } from '@/lib/format-rich-text';
// ISR para fichas de categoría (F-132).
export const revalidate = 3600;
interface Props {
params: Promise<{ slug: string }>;
}

View File

@@ -3,6 +3,9 @@ import type { Metadata } from 'next';
import { fetchCategories } from '@/lib/api';
import { CmsBlock } from '@/components/content/CmsBlock';
// ISR para /categories (F-132).
export const revalidate = 3600;
export const metadata: Metadata = {
title: 'Categorías — mercadodevida',
description: 'Explora todas las categorías de productos naturales y orgánicos.',

View File

@@ -15,6 +15,9 @@ import ProductAddToCart from '@/components/cart/ProductAddToCart';
import ProductAttributes from '@/components/product/ProductAttributes';
import { formatRichText } from '@/lib/format-rich-text';
// ISR para fichas de producto (F-132).
export const revalidate = 3600;
interface Props {
params: Promise<{ slug: string }>;
}

View File

@@ -5,6 +5,10 @@ import { fetchProducts, fetchBrands, fetchCategories, formatPrice } from '@/lib/
import { formatRichText } from '@/lib/format-rich-text';
import { CmsBlock } from '@/components/content/CmsBlock';
// ISR: revalidar listado cada hora para que la home / productos reflejen
// cambios del catálogo sin necesidad de redeploy (F-132).
export const revalidate = 3600;
export const metadata: Metadata = {
title: 'Productos — mercadodevida',
description: 'Todos los productos naturales y orgánicos.',

View File

@@ -4,6 +4,10 @@ import type { Metadata } from 'next';
import { fetchProducts, fetchBrands, fetchCategories, formatPrice } from '@/lib/api';
import { formatRichText } from '@/lib/format-rich-text';
// Search es por-query (searchParams dinámicos), forzamos dinámico: cada
// búsqueda debe ver datos frescos (no se cachea) (F-132).
export const dynamic = 'force-dynamic';
interface Props {
searchParams: Promise<{ q?: string; brand?: string; category?: string }>;
}

View File

@@ -54,7 +54,7 @@ async function readIfFile(filePath: string): Promise<Buffer | null> {
async function findOriginal(filename: string): Promise<{ root: string; buffer: Buffer } | null> {
for (const root of UPLOAD_ROOTS) {
const buffer = await readIfFile(path.join(root, filename));
const buffer = await readIfFile(path.join(/*turbopackIgnore: true*/ root, filename));
if (buffer) return { root, buffer };
}
return null;
@@ -114,7 +114,7 @@ export async function GET(
// Cached thumbnail already on disk?
for (const root of UPLOAD_ROOTS) {
const cached = await readIfFile(path.join(root, sizeSegment, filename));
const cached = await readIfFile(path.join(/*turbopackIgnore: true*/ root, sizeSegment, filename));
if (cached) return imageResponse(cached, filename);
}
@@ -126,9 +126,9 @@ export async function GET(
if (!thumbnail) return imageResponse(original.buffer, filename);
try {
const cacheDir = path.join(original.root, sizeSegment);
const cacheDir = path.join(/*turbopackIgnore: true*/ original.root, sizeSegment);
await mkdir(cacheDir, { recursive: true });
await writeFile(path.join(cacheDir, filename), thumbnail);
await writeFile(path.join(/*turbopackIgnore: true*/ cacheDir, filename), thumbnail);
} catch {
// Serving the thumbnail matters more than caching it.
}