# ANALISIS MODULO RT-009: E-COMMERCE **Fecha:** 2025-12-18 **Fase:** 2 - Analisis por Modulo **Modulo:** RT-009 E-commerce **Herencia:** 20% **Story Points:** 55 **Prioridad:** P2 --- ## 1. DESCRIPCION GENERAL ### 1.1 Proposito Tienda online integrada con inventario, carrito de compras, checkout, pasarelas de pago y opciones de entrega. ### 1.2 Funcionalidades Principales | Funcionalidad | Descripcion | Criticidad | |---------------|-------------|------------| | Catalogo online | Navegacion y busqueda | Alta | | Carrito | Persistente | Alta | | Checkout | Flujo completo | Critica | | Pagos | Multiples pasarelas | Critica | | Envio | Multiples opciones | Alta | | Pedidos | Gestion backoffice | Alta | --- ## 2. HERENCIA DEL CORE ### 2.1 Componentes Heredados (20%) | Componente Core | % Uso | Accion | |-----------------|-------|--------| | inventory.products | 100% | HEREDAR | | sales.pricelists | 100% | HEREDAR | | core.partners | 100% | HEREDAR | ### 2.2 Servicios a Heredar ```typescript import { ProductsService } from '@erp-core/inventory'; import { PricelistsService } from '@erp-core/sales'; import { PartnersService } from '@erp-core/core'; ``` --- ## 3. COMPONENTES NUEVOS ### 3.1 Entidades (TypeORM) ```typescript // 1. EcommerceOrder - Pedido online @Entity('ecommerce_orders', { schema: 'retail' }) export class EcommerceOrder { @PrimaryGeneratedColumn('uuid') id: string; @Column('uuid') tenantId: string; @Column() orderNumber: string; @ManyToOne(() => Partner) customer: Partner; @Column({ type: 'enum', enum: EcommerceOrderStatus }) status: EcommerceOrderStatus; // pending, paid, preparing, shipped, ready_pickup, delivered, cancelled @Column({ type: 'timestamptz' }) orderDate: Date; // Totales @Column({ type: 'decimal', precision: 12, scale: 2 }) subtotal: number; @Column({ type: 'decimal', precision: 12, scale: 2, default: 0 }) discountAmount: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) shippingCost: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) taxAmount: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) total: number; // Pago @Column({ type: 'enum', enum: PaymentStatus }) paymentStatus: PaymentStatus; @Column({ nullable: true }) paymentMethod: string; @Column({ nullable: true }) paymentReference: string; // Entrega @Column({ type: 'enum', enum: DeliveryMethod }) deliveryMethod: DeliveryMethod; // shipping, pickup @ManyToOne(() => Branch, { nullable: true }) pickupBranch: Branch; // Si es pickup @Column({ type: 'jsonb', nullable: true }) shippingAddress: Address; @Column({ nullable: true }) trackingNumber: string; @OneToMany(() => EcommerceOrderLine, line => line.order) lines: EcommerceOrderLine[]; @Column({ nullable: true }) notes: string; } // 2. EcommerceOrderLine @Entity('ecommerce_order_lines', { schema: 'retail' }) export class EcommerceOrderLine { @PrimaryGeneratedColumn('uuid') id: string; @ManyToOne(() => EcommerceOrder) order: EcommerceOrder; @ManyToOne(() => Product) product: Product; @Column() productName: string; @Column({ type: 'decimal', precision: 12, scale: 4 }) quantity: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) unitPrice: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) total: number; } // 3. Cart - Carrito (session-based) @Entity('carts', { schema: 'retail' }) export class Cart { @PrimaryGeneratedColumn('uuid') id: string; @Column('uuid') tenantId: string; @ManyToOne(() => Partner, { nullable: true }) customer: Partner; // null si guest @Column({ nullable: true }) sessionId: string; // Para guests @OneToMany(() => CartItem, item => item.cart) items: CartItem[]; @Column({ type: 'decimal', precision: 12, scale: 2, default: 0 }) subtotal: number; @Column({ type: 'timestamptz' }) createdAt: Date; @Column({ type: 'timestamptz' }) updatedAt: Date; @Column({ type: 'timestamptz', nullable: true }) expiresAt: Date; } // 4. CartItem @Entity('cart_items', { schema: 'retail' }) export class CartItem { @PrimaryGeneratedColumn('uuid') id: string; @ManyToOne(() => Cart) cart: Cart; @ManyToOne(() => Product) product: Product; @Column({ type: 'decimal', precision: 12, scale: 4 }) quantity: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) unitPrice: number; @Column({ type: 'decimal', precision: 12, scale: 2 }) total: number; } // 5. ShippingRate @Entity('shipping_rates', { schema: 'retail' }) export class ShippingRate { @PrimaryGeneratedColumn('uuid') id: string; @Column('uuid') tenantId: string; @Column() name: string; // "Envio estandar", "Express" @Column() carrier: string; // "Fedex", "DHL", "Estafeta" @Column({ type: 'decimal', precision: 12, scale: 2 }) baseRate: number; @Column({ type: 'decimal', precision: 12, scale: 2, nullable: true }) freeShippingMinimum: number; @Column({ type: 'int', nullable: true }) estimatedDays: number; @Column({ type: 'boolean', default: true }) isActive: boolean; } ``` ### 3.2 Servicios Backend | Servicio | Metodos Principales | |----------|-------------------| | CatalogService | search(), getByCategory(), getProduct() | | CartService | create(), addItem(), updateItem(), removeItem(), clear() | | CheckoutService | validate(), calculateTotals(), processPayment() | | PaymentGatewayService | createPayment(), capture(), refund() | | ShippingService | calculateRates(), createShipment(), track() | | EcommerceOrderService | create(), updateStatus(), getByCustomer() | ### 3.3 Controladores ```typescript // API Publica (Storefront) @Controller('store') export class StorefrontController { // Catalogo @Get('products') getProducts(@Query() filters: CatalogFilters): Promise; @Get('products/:id') getProduct(@Param('id') id: string): Promise; @Get('products/search') searchProducts(@Query('q') query: string): Promise; @Get('categories') getCategories(): Promise; // Carrito @Get('cart') getCart(): Promise; @Post('cart/items') addToCart(@Body() dto: AddToCartDto): Promise; @Put('cart/items/:id') updateCartItem(@Param('id') id: string, @Body() dto: UpdateCartDto): Promise; @Delete('cart/items/:id') removeFromCart(@Param('id') id: string): Promise; // Checkout @Post('checkout/validate') validateCheckout(@Body() dto: CheckoutDto): Promise; @Get('checkout/shipping-rates') getShippingRates(@Query() dto: ShippingQuery): Promise; @Post('checkout/complete') completeCheckout(@Body() dto: CompleteCheckoutDto): Promise; // Pagos @Post('payments/create') createPayment(@Body() dto: PaymentDto): Promise; @Post('payments/webhook') handleWebhook(@Body() payload: any): Promise; // Pedidos (autenticado) @Get('orders') @UseGuards(AuthGuard) getMyOrders(): Promise; @Get('orders/:id') @UseGuards(AuthGuard) getOrder(@Param('id') id: string): Promise; } // API Backoffice @Controller('ecommerce') export class EcommerceController { // Gestion de pedidos @Get('orders') getOrders(@Query() filters: OrderFilters): Promise; @Put('orders/:id/status') updateStatus(@Param('id') id: string, @Body() dto: StatusDto): Promise; @Post('orders/:id/ship') markAsShipped(@Param('id') id: string, @Body() dto: ShipDto): Promise; // Configuracion @Get('shipping-rates') getShippingRates(): Promise; @Post('shipping-rates') createShippingRate(@Body() dto: CreateRateDto): Promise; } ``` --- ## 4. INTEGRACIONES EXTERNAS ### 4.1 Pasarelas de Pago ```typescript interface PaymentGateway { name: string; createPayment(order: EcommerceOrder): Promise; capturePayment(paymentId: string): Promise; refund(paymentId: string, amount: number): Promise; } // Implementaciones class StripeGateway implements PaymentGateway { ... } class ConektaGateway implements PaymentGateway { ... } class MercadoPagoGateway implements PaymentGateway { ... } ``` ### 4.2 Proveedores de Envio ```typescript interface ShippingProvider { name: string; calculateRate(origin: Address, destination: Address, weight: number): Promise; createShipment(order: EcommerceOrder): Promise; getTracking(trackingNumber: string): Promise; } // Implementaciones class FedexProvider implements ShippingProvider { ... } class DHLProvider implements ShippingProvider { ... } class EstafetaProvider implements ShippingProvider { ... } ``` --- ## 5. FLUJOS DE NEGOCIO ### 5.1 Flujo de Compra ``` 1. Cliente navega catalogo ↓ 2. Agrega productos al carrito ↓ 3. Revisa carrito ↓ 4. Inicia checkout ↓ 5. Login/registro (o guest) ↓ 6. Selecciona direccion de envio ↓ 7. Selecciona metodo de envio ↓ 8. Ve resumen con totales ↓ 9. Selecciona metodo de pago ↓ 10. Procesa pago ↓ 11. Confirmacion de pedido ↓ 12. Email de confirmacion ``` ### 5.2 Flujo de Gestion de Pedido ``` 1. Pedido creado (PENDING) ↓ 2. Pago confirmado (PAID) ↓ 3. Preparando (PREPARING) - Reservar stock - Imprimir etiqueta ↓ 4. Enviado (SHIPPED) o Listo para recoger (READY_PICKUP) - Tracking disponible ↓ 5. Entregado (DELIVERED) ↓ 6. Fin (o cancelado en cualquier punto) ``` --- ## 6. TABLAS DDL ### 6.1 Tablas Nuevas ```sql -- Pedidos CREATE TABLE retail.ecommerce_orders ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), order_number VARCHAR(20) NOT NULL, customer_id UUID NOT NULL REFERENCES core.partners(id), status VARCHAR(20) NOT NULL DEFAULT 'pending', order_date TIMESTAMPTZ NOT NULL DEFAULT NOW(), subtotal DECIMAL(12,2) NOT NULL, discount_amount DECIMAL(12,2) DEFAULT 0, shipping_cost DECIMAL(12,2) NOT NULL DEFAULT 0, tax_amount DECIMAL(12,2) NOT NULL DEFAULT 0, total DECIMAL(12,2) NOT NULL, payment_status VARCHAR(20), payment_method VARCHAR(50), payment_reference VARCHAR(100), delivery_method VARCHAR(20) NOT NULL, pickup_branch_id UUID REFERENCES retail.branches(id), shipping_address JSONB, tracking_number VARCHAR(50), notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ, UNIQUE(tenant_id, order_number) ); -- Lineas CREATE TABLE retail.ecommerce_order_lines ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), order_id UUID NOT NULL REFERENCES retail.ecommerce_orders(id) ON DELETE CASCADE, product_id UUID NOT NULL REFERENCES inventory.products(id), product_name VARCHAR(255) NOT NULL, quantity DECIMAL(12,4) NOT NULL, unit_price DECIMAL(12,2) NOT NULL, total DECIMAL(12,2) NOT NULL ); -- Carritos CREATE TABLE retail.carts ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), customer_id UUID REFERENCES core.partners(id), session_id VARCHAR(100), subtotal DECIMAL(12,2) DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ, expires_at TIMESTAMPTZ ); CREATE TABLE retail.cart_items ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), cart_id UUID NOT NULL REFERENCES retail.carts(id) ON DELETE CASCADE, product_id UUID NOT NULL REFERENCES inventory.products(id), quantity DECIMAL(12,4) NOT NULL, unit_price DECIMAL(12,2) NOT NULL, total DECIMAL(12,2) NOT NULL ); -- Tarifas de envio CREATE TABLE retail.shipping_rates ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), name VARCHAR(100) NOT NULL, carrier VARCHAR(50) NOT NULL, base_rate DECIMAL(12,2) NOT NULL, free_shipping_minimum DECIMAL(12,2), estimated_days INT, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMPTZ DEFAULT NOW() ); ``` --- ## 7. DEPENDENCIAS ### 7.1 Dependencias de Retail | Modulo | Tipo | |--------|------| | RT-001 Fundamentos | Prerequisito | | RT-003 Inventario | Stock | | RT-005 Clientes | Clientes y puntos | | RT-006 Precios | Precios online | ### 7.2 Dependencias Externas | Servicio | Proposito | |----------|-----------| | Stripe/Conekta | Pagos | | Fedex/DHL | Envios | | SendGrid | Emails | ### 7.3 Bloquea a | Modulo | Razon | |--------|-------| | RT-010 Facturacion | Facturas de pedidos | --- ## 8. CRITERIOS DE ACEPTACION ### 8.1 Storefront - [ ] Navegar catalogo - [ ] Buscar productos - [ ] Ver detalle de producto - [ ] Stock en tiempo real - [ ] Agregar al carrito - [ ] Carrito persistente - [ ] Checkout como guest o registrado - [ ] Multiples metodos de pago - [ ] Envio o pickup - [ ] Confirmacion por email ### 8.2 Backoffice - [ ] Ver pedidos - [ ] Actualizar estado - [ ] Generar etiqueta envio - [ ] Registrar tracking - [ ] Cancelar pedido --- ## 9. ESTIMACION DETALLADA | Componente | SP Backend | SP Frontend | Total | |------------|-----------|-------------|-------| | Entities + Migrations | 5 | - | 5 | | CatalogService | 3 | - | 3 | | CartService | 5 | - | 5 | | CheckoutService | 5 | - | 5 | | PaymentGatewayService | 8 | - | 8 | | ShippingService | 5 | - | 5 | | OrderService | 5 | - | 5 | | Storefront UI | - | 13 | 13 | | Backoffice UI | - | 6 | 6 | | **TOTAL** | **36** | **19** | **55** | --- **Estado:** ANALISIS COMPLETO **Bloqueado por:** RT-001, RT-003, RT-005, RT-006