feat(F-079): completed feature

This commit is contained in:
chattie
2026-08-20 05:57:24 +02:00
parent fffb52721a
commit 60206d88eb
10 changed files with 227 additions and 41 deletions

View File

@@ -30,6 +30,12 @@ export const PRODUCT_ATTRIBUTES = [
export type ProductAttribute = (typeof PRODUCT_ATTRIBUTES)[number];
export interface ProductBrandSummary {
id: string;
name: string;
slug: string;
}
export interface Product {
id: string;
name: string;
@@ -43,6 +49,7 @@ export interface Product {
seoDescription: string | null;
categoryIds: string[];
brandId: string | null;
brand?: ProductBrandSummary;
createdAt: Date;
updatedAt: Date;
}

View File

@@ -23,6 +23,8 @@ export interface ProductRow {
seo_description: string | null;
brand_id: string | null;
category_ids: string[] | null;
brand_name: string | null;
brand_slug: string | null;
created_at: Date;
updated_at: Date;
}
@@ -35,7 +37,9 @@ export const PRODUCT_COLUMNS = `
COALESCE(
array_agg(pc.category_id ORDER BY pc.category_id) FILTER (WHERE pc.category_id IS NOT NULL),
ARRAY[]::uuid[]
) AS category_ids
) AS category_ids,
b.name AS brand_name,
b.slug AS brand_slug
`;
const UPDATABLE: ReadonlyArray<[keyof ProductPatch, string]> = [
@@ -59,8 +63,9 @@ export class PgProductRepository implements ProductRepository {
`SELECT ${PRODUCT_COLUMNS}
FROM catalog_products p
LEFT JOIN catalog_product_categories pc ON pc.product_id = p.id
LEFT JOIN brands_brands b ON b.id = p.brand_id
WHERE p.id = $1
GROUP BY p.id`,
GROUP BY p.id, b.name, b.slug`,
[id],
);
const row = result.rows[0];
@@ -72,8 +77,9 @@ export class PgProductRepository implements ProductRepository {
`SELECT ${PRODUCT_COLUMNS}
FROM catalog_products p
LEFT JOIN catalog_product_categories pc ON pc.product_id = p.id
LEFT JOIN brands_brands b ON b.id = p.brand_id
WHERE p.slug = $1 AND p.state = 'active'
GROUP BY p.id`,
GROUP BY p.id, b.name, b.slug`,
[slug],
);
const row = result.rows[0];
@@ -191,14 +197,16 @@ export class PgProductRepository implements ProductRepository {
? `SELECT ${PRODUCT_COLUMNS}
FROM catalog_products p
LEFT JOIN catalog_product_categories pc ON pc.product_id = p.id
LEFT JOIN brands_brands b ON b.id = p.brand_id
WHERE p.name ILIKE $1
GROUP BY p.id
GROUP BY p.id, b.name, b.slug
ORDER BY p.created_at DESC
LIMIT $2 OFFSET $3`
: `SELECT ${PRODUCT_COLUMNS}
FROM catalog_products p
LEFT JOIN catalog_product_categories pc ON pc.product_id = p.id
GROUP BY p.id
LEFT JOIN brands_brands b ON b.id = p.brand_id
GROUP BY p.id, b.name, b.slug
ORDER BY p.created_at DESC
LIMIT $1 OFFSET $2`,
q ? [`%${q}%`, limit, offset] : [limit, offset],
@@ -279,6 +287,10 @@ export function toProduct(row: ProductRow): Product {
seoTitle: row.seo_title,
seoDescription: row.seo_description,
brandId: row.brand_id,
brand:
row.brand_id && row.brand_name && row.brand_slug
? { id: row.brand_id, name: row.brand_name, slug: row.brand_slug }
: undefined,
categoryIds: row.category_ids ?? [],
createdAt: row.created_at,
updatedAt: row.updated_at,