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

@@ -6,7 +6,7 @@
import type { FastifyRequest } from 'fastify';
import { AppError } from './errors.js';
export type Role = 'customer' | 'admin';
export type Role = 'customer' | 'admin' | 'editor';
export interface CurrentUser {
id: string;

View File

@@ -0,0 +1,127 @@
/**
* OpenAPI 3.0 configuration and shared schemas for the API.
* Route-level schemas are defined in each module's routes file.
*/
import type { FastifySchema } from 'fastify';
export const swaggerConfig = {
openapi: {
openapi: '3.0.3',
info: {
title: 'mercadodevida API',
description:
'API REST completa del e-commerce mercadodevida. ' +
'Incluye gestión de productos, catálogo, carrito, pedidos, pagos, ' +
'CMS, reseñas, promociones, inventario, precios y configuración de tienda.',
version: '1.0.0',
contact: {
name: 'Soporte mercadodevida',
email: 'soporte@mercadodevida.com',
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT',
},
},
servers: [
{
url: 'http://localhost:3000',
description: 'Desarrollo local',
},
],
tags: [
{ name: 'Health', description: 'Health checks' },
{ name: 'Auth', description: 'Autenticación y sesiones' },
{ name: 'Catalog', description: 'Catálogo de productos (público)' },
{ name: 'Admin Products', description: 'Gestión de productos (admin)' },
{ name: 'Cart', description: 'Carrito de compras' },
{ name: 'Checkout', description: 'Proceso de compra' },
{ name: 'Orders', description: 'Pedidos' },
{ name: 'Payments', description: 'Pagos y transacciones' },
{ name: 'Users', description: 'Gestión de usuarios y perfiles' },
{ name: 'Categories', description: 'Categorías' },
{ name: 'Brands', description: 'Marcas' },
{ name: 'Inventory', description: 'Inventario y stock' },
{ name: 'Pricing', description: 'Precios y IVA' },
{ name: 'Shipping', description: 'Envíos y zonas' },
{ name: 'Promotions', description: 'Promociones y cupones' },
{ name: 'Reviews', description: 'Reseñas de productos' },
{ name: 'CMS', description: 'Páginas de contenido' },
{ name: 'Admin', description: 'Panel de administración' },
],
},
};
// ── Shared schemas ─────────────────────────────────────────────────────────────
export const errorSchema = {
type: 'object',
required: ['error', 'requestId'],
properties: {
error: {
type: 'object',
required: ['statusCode', 'code', 'message'],
properties: {
statusCode: { type: 'integer' },
code: { type: 'string' },
message: { type: 'string' },
details: { type: 'array', items: { type: 'object', additionalProperties: true } },
},
},
requestId: { type: 'string' },
},
};
export const paginationQuerySchema = {
type: 'object',
properties: {
limit: {
type: 'integer',
minimum: 1,
maximum: 100,
default: 20,
description: 'Resultados por página',
},
offset: {
type: 'integer',
minimum: 0,
default: 0,
description: 'Desplazamiento desde el inicio',
},
},
};
export const paginationResponseSchema = (itemSchema: Record<string, unknown>) => ({
type: 'object',
properties: {
items: { type: 'array', items: itemSchema },
total: { type: 'integer', description: 'Total de registros' },
},
});
// ── Common route config helpers ───────────────────────────────────────────────
/** Mark a route as requiring authentication. */
export function withAuth(schema: FastifySchema): FastifySchema {
return {
...schema,
headers: {
type: 'object',
properties: {
cookie: { type: 'string', description: 'mdv_session cookie de sesión' },
},
},
};
}
/** Mark a route as admin-only. */
export function withAdmin(schema: FastifySchema): FastifySchema {
return withAuth({
...schema,
response: {
...(schema.response ?? {}),
401: errorSchema,
403: errorSchema,
},
});
}