feat: add public product catalog boundary
This commit is contained in:
@@ -7,6 +7,7 @@ import { registerAdminInventoryRoutes } from '../modules/inventory/routes/admin-
|
||||
import { registerAdminImageRoutes } from '../modules/inventory/routes/admin-image-routes.js';
|
||||
import { registerAdminListingRoutes } from '../modules/listings/routes/admin-listing-routes.js';
|
||||
import { registerAdminProductRoutes } from '../modules/products/routes/admin-product-routes.js';
|
||||
import { registerPublicProductRoutes } from '../modules/products/routes/public-product-routes.js';
|
||||
import { registerPublicSearchRoutes } from '../modules/search/routes/public-search-routes.js';
|
||||
|
||||
export function buildApp(dependencies) {
|
||||
@@ -55,6 +56,10 @@ export function buildApp(dependencies) {
|
||||
...dependencies,
|
||||
prefix: '/api/v1',
|
||||
});
|
||||
app.register(registerPublicProductRoutes, {
|
||||
...dependencies,
|
||||
prefix: '/api/v1',
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import { createListingRepository } from '../modules/listings/repositories/listin
|
||||
import { createListingService } from '../modules/listings/services/listing-service.js';
|
||||
import { createProductRepository } from '../modules/products/repositories/product-repository.js';
|
||||
import { createProductService } from '../modules/products/services/product-service.js';
|
||||
import { createPublicProductService } from '../modules/products/services/public-product-service.js';
|
||||
import { createSearchService } from '../modules/search/services/search-service.js';
|
||||
|
||||
function parsePort(value) {
|
||||
@@ -86,6 +87,7 @@ async function startServer() {
|
||||
}),
|
||||
listingService: createListingService({ listingRepository, inventoryImageRepository }),
|
||||
productService: createProductService({ productRepository }),
|
||||
publicProductService: createPublicProductService({ productRepository }),
|
||||
searchService: createSearchService({ listingRepository }),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { and, asc, eq } from 'drizzle-orm';
|
||||
import { and, asc, eq, inArray } from 'drizzle-orm';
|
||||
|
||||
import { products } from '../../../infrastructure/database/schema.js';
|
||||
import {
|
||||
inventoryItems,
|
||||
listings,
|
||||
products,
|
||||
} from '../../../infrastructure/database/schema.js';
|
||||
|
||||
export function createProductRepository(db) {
|
||||
return {
|
||||
@@ -18,6 +22,22 @@ export function createProductRepository(db) {
|
||||
return product ?? null;
|
||||
},
|
||||
|
||||
async findPublicBySlug(slug) {
|
||||
const [result] = await db
|
||||
.select({ product: products })
|
||||
.from(products)
|
||||
.innerJoin(inventoryItems, eq(inventoryItems.productId, products.id))
|
||||
.innerJoin(listings, eq(listings.inventoryItemId, inventoryItems.id))
|
||||
.where(and(
|
||||
eq(products.slug, slug),
|
||||
eq(inventoryItems.status, 'ACTIVE'),
|
||||
inArray(listings.status, ['AVAILABLE', 'PENDING']),
|
||||
))
|
||||
.limit(1);
|
||||
|
||||
return result?.product ?? null;
|
||||
},
|
||||
|
||||
async findBySellerIdAndSlug(sellerId, slug) {
|
||||
const [product] = await db
|
||||
.select()
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { toPublicProductDto } from '@pokemon-inventory/contracts/public-product';
|
||||
|
||||
export async function registerPublicProductRoutes(app, options) {
|
||||
const { publicProductService } = options;
|
||||
|
||||
app.get('/public/products/:slug', async (request) => {
|
||||
const product = await publicProductService.getBySlug(request.params.slug);
|
||||
return { data: toPublicProductDto(product) };
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { createApplicationError } from '../../../shared/errors/application-error.js';
|
||||
|
||||
export function createPublicProductService({ productRepository }) {
|
||||
return {
|
||||
async getBySlug(slug) {
|
||||
const product = await productRepository.findPublicBySlug(slug);
|
||||
|
||||
if (!product) {
|
||||
throw createApplicationError('PRODUCT_NOT_FOUND', 'Product was not found.', 404);
|
||||
}
|
||||
|
||||
return product;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user