Sistema core de marketplace B2C/B2B para productos de ferretería y servicios técnicos, diseñado para escalar de 0 a 100k productos sin reescrituras.
- ✅ Catálogo Multi-Tipo: Productos físicos, servicios puros y bundles híbridos
- ✅ Multi-Vendedor: Empresas, PYMEs y maestros independientes
- ✅ Sistema de Órdenes Robusto: Manejo de inventario con reservas, pagos idempotentes
- ✅ Reviews Verificados: Solo post-compra, con rating ponderado
- ✅ Eventos de Dominio: Event bus para integración y evolución
- ✅ Observabilidad: Logging estructurado, métricas de negocio
- Monolito Modular: Next.js 14 + App Router
- Base de Datos: PostgreSQL + Prisma ORM
- Cache: Redis para performance y rate limiting
- Transacciones ACID: Para operaciones críticas (órdenes, pagos)
- Idempotencia: En pagos y webhooks
- Soft Deletes: Para auditoría y compliance
marketplace-core/
├── src/
│ ├── app/ # Next.js App Router
│ │ └── api/ # API Routes
│ │ ├── orders/
│ │ ├── payments/
│ │ └── reviews/
│ ├── core/ # Business Logic
│ │ ├── orders/
│ │ │ └── order.service.ts
│ │ ├── inventory/
│ │ │ └── inventory.service.ts
│ │ ├── payments/
│ │ │ └── payment.service.ts
│ │ └── reviews/
│ │ └── review.service.ts
│ └── lib/ # Infrastructure
│ ├── db.ts # Prisma client
│ ├── redis.ts # Redis client
│ ├── logger.ts # Structured logging
│ └── events.ts # Event bus
└── prisma/
└── schema.prisma # Database schema
- Node.js 18+
- PostgreSQL 14+
- Redis 6+
# Instalar dependencias
npm install
# O con pnpm (recomendado)
pnpm installcp .env.example .envEdita .env con tus credenciales:
DATABASE_URL="postgresql://user:password@localhost:5432/marketplace"
REDIS_URL="redis://localhost:6379"
JWT_SECRET="tu-secret-super-seguro"# Generar Prisma Client
npm run db:generate
# Ejecutar migraciones
npm run db:migrate
# (Opcional) Seed data de prueba
npm run db:seednpm run devLa app estará disponible en http://localhost:3000
User: Usuario base con roles (ADMIN, USER, SELLER)Seller: Extensión de User con info de negocio, reputación y comisiones
Category: Jerarquía de categorías con multi-nivelProduct: Productos con tipos (PHYSICAL, SERVICE, HYBRID)Inventory: Control de stock con reservas atómicas
Order: Órdenes con estados transicionablesOrderItem: Items individuales con snapshot de preciosPayment: Pagos idempotentes con webhooksOrderStatusHistory: Auditoría completa de cambios
Review: Solo post-compra verificada- Rating denormalizado en Product y Seller para performance
import { OrderService } from '@/core/orders/order.service'
const orderService = new OrderService()
// Crear orden
const order = await orderService.createOrder({
userId: 'user_123',
items: [
{ productId: 'prod_456', quantity: 2 },
{ productId: 'prod_789', quantity: 1, scheduledAt: new Date() }
],
addressId: 'addr_012',
shippingMethod: 'EXPRESS'
})
// Confirmar pago
await orderService.confirmPayment(order.id, payment.id)
// Cancelar orden
await orderService.cancelOrder(order.id, 'Cliente solicitó cancelación')import { InventoryService } from '@/core/inventory/inventory.service'
const inventoryService = new InventoryService()
// Verificar disponibilidad
const available = await inventoryService.getAvailable('prod_123')
// Restock
await inventoryService.restock('prod_123', 50, 'seller_456', 'Compra proveedor')
// Ajuste manual
await inventoryService.adjust('prod_123', 100, 'admin_789', 'Corrección inventario')import { PaymentService } from '@/core/payments/payment.service'
const paymentService = new PaymentService()
// Crear pago (idempotente)
const payment = await paymentService.createPayment({
orderId: 'ord_123',
amount: 50000,
method: 'WEBPAY',
idempotencyKey: 'unique_key_123'
})
// Procesar webhook
await paymentService.handleWebhook('transbank', 'payment.success', payload)import { ReviewService } from '@/core/reviews/review.service'
const reviewService = new ReviewService()
// Crear review (solo si compró)
const review = await reviewService.createReview({
orderItemId: 'item_123',
userId: 'user_456',
rating: 5,
title: 'Excelente producto',
comment: 'Llegó rápido y funciona perfecto'
})
// Seller responde
await reviewService.respondToReview(review.id, 'seller_789', '¡Gracias por tu compra!')- JWT-based authentication (implementar con NextAuth o similar)
- Headers:
x-user-idpara identificar usuario en requests
- Validación server-side en todos los endpoints
- Políticas por rol (ADMIN, SELLER, USER)
- Ownership validation en operaciones sensibles
import { CacheService } from '@/lib/redis'
const { allowed } = await CacheService.checkRateLimit(
`api:${userId}`,
100, // requests
60 // window en segundos
)
if (!allowed) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 })
}import { CacheService } from '@/lib/redis'
// Get con fallback
const product = await CacheService.getOrSet(
`product:${id}`,
() => prisma.product.findUnique({ where: { id } }),
300 // TTL 5 minutos
)
// Invalidar cache
await CacheService.invalidate('product:*')- Índices compuestos en queries frecuentes
selectespecífico para reducir payload- Paginación en listados
- Denormalización estratégica (ratings, stats)
- Implementar autenticación (NextAuth)
- UI básica con React
- Integración con payment provider (Webpay/Stripe)
- Sistema de notificaciones
- Admin dashboard básico
- Meilisearch para búsqueda avanzada
- CDN para imágenes
- Monitoring (Sentry/Datadog)
- Analytics dashboard
- Optimización de queries
- Sistema de recomendaciones (Python/ML)
- Matching proveedor-servicio
- Chat en tiempo real
- Seller dashboard avanzado
- Reportes y analytics
- Read replicas
- Background jobs (BullMQ)
- Event sourcing para auditoría
- A/B testing
- Fraud detection
# Unit tests
npm test
# Watch mode
npm run test:watch
# Coverage
npm test -- --coverage# Development
Los logs se muestran en consola con colores
# Production
Los logs están en formato JSON para parseonpm run db:studioimport { EventBus } from '@/lib/events'
// Ver últimos 50 eventos
const history = EventBus.getHistory(50)
console.log(history)feat:Nueva funcionalidadfix:Bug fixrefactor:Refactorización sin cambio funcionalperf:Mejora de performancedocs:Documentacióntest:Tests
- TypeScript strict mode
- Prettier para formateo
- ESLint para linting
- Comentarios en funciones críticas
- Fork el proyecto
- Crea tu feature branch (
git checkout -b feat/amazing-feature) - Commit cambios (
git commit -m 'feat: add amazing feature') - Push al branch (
git push origin feat/amazing-feature) - Abre un Pull Request
Este proyecto es privado y propietario.
- Email: soporte@marketplace.com
- Documentación:
/docs - Issues: GitHub Issues
Nota: Este es un sistema core de producción. Cada decisión arquitectónica fue tomada basada en experiencia real escalando marketplaces. No es un tutorial ni un ejemplo académico.