feat(F-048): completed feature

This commit is contained in:
chattie
2026-08-19 07:17:14 +02:00
parent 8ee1938af9
commit 835ab66eda
187 changed files with 12361 additions and 1065 deletions

View File

@@ -1,15 +1,14 @@
import type { FastifyInstance } from 'fastify';
import type { FastifySchema } from 'fastify';
import type pg from 'pg';
import { z } from 'zod';
import type { Authenticate } from '../../../shared/auth.js';
import { AppError } from '../../../shared/errors.js';
import { errorSchema } from '../../../shared/swagger.js';
import { parseJson } from '../../../shared/http-input.js';
import { CartService } from '../../cart/index.js';
import { PgCartRepository } from '../../cart/infrastructure/pg-cart-repository.js';
import { createCartService } from '../../cart/index.js';
import { createInventoryService } from '../../inventory/index.js';
import { OrderService } from '../../orders/index.js';
import { PgOrderRepository } from '../../orders/infrastructure/pg-order-repository.js';
import { NoOpOrderEventPublisher } from '../../orders/infrastructure/no-op-event-publisher.js';
import { createOrderService } from '../../orders/index.js';
import { createPricingService } from '../../pricing/index.js';
import { createShippingService } from '../../shipping/index.js';
import { CheckoutService } from '../application/checkout-service.js';
@@ -42,8 +41,8 @@ export async function registerCheckoutRoutes(
const pricing = createPricingService(deps.pool);
const inventory = createInventoryService(deps.pool);
const shipping = createShippingService(deps.pool);
const orders = new OrderService(new PgOrderRepository(deps.pool), new NoOpOrderEventPublisher());
const cart = new CartService(new PgCartRepository(deps.pool), pricing, inventory);
const orders = createOrderService(deps.pool);
const cart = createCartService(deps.pool, pricing, inventory);
const metrics = new InMemoryCheckoutMetrics();
const tracer = deps.tracer ?? createNoOpTelemetry().tracer;
const orderLookup = new PgIdempotencyLookup(deps.pool);
@@ -60,7 +59,33 @@ export async function registerCheckoutRoutes(
tracer,
});
app.post('/checkout', async (request, reply) => {
const checkoutSchema: FastifySchema = {
tags: ['Checkout'],
summary: 'Checkout',
description: 'Procesa el carrito del usuario y crea el pedido.',
body: {
type: 'object',
required: ['address', 'idempotencyKey'],
properties: {
address: {
type: 'object',
required: ['country', 'postalCode'],
properties: {
country: { type: 'string' },
postalCode: { type: 'string' },
},
},
promoCode: { type: 'string', maxLength: 64, nullable: true },
idempotencyKey: {
type: 'string',
maxLength: 120,
description: 'Idempotency key para evitar duplicados',
},
},
},
response: { 401: errorSchema },
};
app.post('/checkout', { schema: checkoutSchema }, async (request, reply) => {
const user = await deps.authenticate(request);
const input = parseJson(checkoutBodySchema, request.body);
try {

View File

@@ -257,8 +257,12 @@ describe('CheckoutService', () => {
throw new Error('should not transition on retry');
},
listOrders: async () => [],
getOrderAdmin: async () => { throw new Error('not used'); },
transitionAdmin: async () => { throw new Error('not used'); },
getOrderAdmin: async () => {
throw new Error('not used');
},
transitionAdmin: async () => {
throw new Error('not used');
},
getOrder: async (id) => ({
id,
userId: 'u-1',