template-saas/docs/02-especificaciones/ET-SAAS-019-portfolio.md
Adrian Flores Cortes 2825b3d5fd
Some checks are pending
CI / Backend CI (push) Waiting to run
CI / Frontend CI (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / CI Summary (push) Blocked by required conditions
docs: Add ET-SAAS-018 to ET-SAAS-022 technical specifications
- ET-SAAS-018-sales.md: Sales pipeline/CRM module
- ET-SAAS-019-portfolio.md: Product catalog module
- ET-SAAS-020-commissions.md: Commissions system
- ET-SAAS-021-mlm.md: Multi-Level Marketing module
- ET-SAAS-022-goals.md: Goals and objectives system
- Update _MAP.md with all 9 specifications

All specs document:
- Data model (DDL, enums, tables)
- Backend architecture (endpoints, services)
- Security (RLS, RBAC permissions)
- Frontend status and hooks
- Module integrations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 13:14:48 -06:00

9.6 KiB

id title type status priority module version created_date updated_date story_points
ET-SAAS-019 Especificacion Tecnica Portfolio (Product Catalog) TechnicalSpec Implemented P1 portfolio 1.0.0 2026-02-03 2026-02-03 8

ET-SAAS-019: Especificacion Tecnica - Portfolio (Catalogo de Productos)

Metadata

  • Codigo: ET-SAAS-019
  • Modulo: Portfolio
  • Version: 1.0.0
  • Estado: Implementado
  • Fecha: 2026-02-03
  • Basado en: SAAS-019

1. Resumen Ejecutivo

1.1 Estado Actual

Sistema de catalogo de productos completamente implementado.

Capacidad Estado Notas
Categories SI Jerarquicas con arbol
Products SI Multi-tipo, inventario
Variants SI Atributos configurables
Prices SI Multi-moneda, tiered
RLS SI Row Level Security

1.2 Funcionalidades v1.0

Catalogo completo con:

  • 4 Entidades: Categories, Products, Variants, Prices
  • Categorias jerarquicas: Arbol ilimitado con parent_id
  • 5 Tipos de producto: physical, digital, service, subscription, bundle
  • Variantes: Atributos dinamicos (color, size, etc.)
  • Precios flexibles: one_time, recurring, usage_based, tiered

2. Modelo de Datos

2.1 Schema: portfolio

Tabla: categories

Campo Tipo Descripcion
id UUID PK
tenant_id UUID FK tenants
parent_id UUID FK categories (jerarquia)
name VARCHAR(100) Nombre categoria
slug VARCHAR(120) URL-friendly (unique per tenant)
description TEXT Descripcion
position INT Orden dentro del padre
image_url VARCHAR(500) Imagen
color VARCHAR(7) Color hex
icon VARCHAR(50) Icono
is_active BOOLEAN Estado
meta_title, meta_description VARCHAR/TEXT SEO
custom_fields JSONB Campos personalizados

Tabla: products

Campo Tipo Descripcion
id UUID PK
tenant_id UUID FK tenants
category_id UUID FK categories
name VARCHAR(255) Nombre producto
slug VARCHAR(280) URL-friendly
sku VARCHAR(100) Stock Keeping Unit
barcode VARCHAR(100) Codigo de barras
description TEXT Descripcion larga
short_description VARCHAR(500) Descripcion corta
product_type ENUM physical, digital, service, subscription, bundle
status ENUM draft, active, inactive, discontinued, out_of_stock
base_price DECIMAL(15,2) Precio base
cost_price DECIMAL(15,2) Costo
compare_at_price DECIMAL(15,2) Precio tachado
currency VARCHAR(3) Moneda (default USD)
track_inventory BOOLEAN Trackear inventario
stock_quantity INT Cantidad en stock
low_stock_threshold INT Umbral de stock bajo
allow_backorder BOOLEAN Permitir backorder
weight, length, width, height DECIMAL Dimensiones
images JSONB Array de URLs
featured_image_url VARCHAR(500) Imagen principal
tags JSONB Array de tags
is_visible BOOLEAN Visible en frontend
is_featured BOOLEAN Producto destacado
has_variants BOOLEAN Tiene variantes
variant_attributes JSONB Atributos para variantes

Tabla: variants

Campo Tipo Descripcion
id UUID PK
tenant_id UUID FK tenants
product_id UUID FK products
sku VARCHAR(100) SKU de variante
barcode VARCHAR(100) Codigo de barras
name VARCHAR(255) Nombre (e.g., "Rojo - XL")
attributes JSONB {"color": "red", "size": "XL"}
price DECIMAL(15,2) Override de precio
cost_price DECIMAL(15,2) Costo variante
stock_quantity INT Stock de variante
weight DECIMAL(10,3) Peso (override)
image_url VARCHAR(500) Imagen de variante
is_active BOOLEAN Estado
position INT Orden

Tabla: prices

Campo Tipo Descripcion
id UUID PK
tenant_id UUID FK tenants
product_id UUID FK products (o variant_id)
variant_id UUID FK variants (o product_id)
price_type ENUM one_time, recurring, usage_based, tiered
currency VARCHAR(3) Moneda
amount DECIMAL(15,2) Precio
compare_at_amount DECIMAL(15,2) Precio comparativo
billing_period VARCHAR(20) day, week, month, year
billing_interval INT Intervalo (e.g., 1 = mensual)
min_quantity, max_quantity INT Rango para tiered
valid_from, valid_until TIMESTAMPTZ Validez
priority INT Prioridad (0 = default)
is_active BOOLEAN Estado

2.2 Enums

portfolio.product_type: physical, digital, service, subscription, bundle
portfolio.product_status: draft, active, inactive, discontinued, out_of_stock
portfolio.price_type: one_time, recurring, usage_based, tiered
portfolio.attribute_type: color, size, material, style, capacity, custom

3. Arquitectura Backend

3.1 Estructura de Archivos

backend/src/modules/portfolio/
├── portfolio.module.ts
├── controllers/
│   ├── categories.controller.ts
│   └── products.controller.ts
├── services/
│   ├── categories.service.ts
│   └── products.service.ts
├── entities/
│   ├── category.entity.ts
│   ├── product.entity.ts
│   ├── variant.entity.ts
│   └── price.entity.ts
├── dto/
│   ├── create-category.dto.ts
│   ├── create-product.dto.ts
│   └── ...
└── __tests__/

3.2 Endpoints API

Categories

Metodo Endpoint Descripcion
GET /portfolio/categories Listar (paginado)
GET /portfolio/categories/tree Arbol jerarquico
GET /portfolio/categories/:id Obtener
POST /portfolio/categories Crear
PUT /portfolio/categories/:id Actualizar
DELETE /portfolio/categories/:id Eliminar

Products

Metodo Endpoint Descripcion
GET /portfolio/products Listar (paginado, filtros)
GET /portfolio/products/:id Obtener con variantes
POST /portfolio/products Crear
PUT /portfolio/products/:id Actualizar
PATCH /portfolio/products/:id/status Cambiar status
POST /portfolio/products/:id/duplicate Duplicar
DELETE /portfolio/products/:id Eliminar

Variants

Metodo Endpoint Descripcion
GET /portfolio/products/:id/variants Listar variantes
POST /portfolio/products/:id/variants Crear variante
PATCH /portfolio/products/:id/variants/:vid Actualizar
DELETE /portfolio/products/:id/variants/:vid Eliminar

Prices

Metodo Endpoint Descripcion
GET /portfolio/products/:id/prices Listar precios
POST /portfolio/products/:id/prices Crear precio
PATCH /portfolio/products/:id/prices/:pid Actualizar
DELETE /portfolio/products/:id/prices/:pid Eliminar

4. Seguridad

4.1 Row Level Security (RLS)

-- Aislamiento por tenant
CREATE POLICY categories_tenant_isolation ON portfolio.categories
    USING (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY products_tenant_isolation ON portfolio.products
    USING (tenant_id = current_setting('app.tenant_id')::uuid);

4.2 Permisos RBAC

Permiso Descripcion
portfolio:read Ver catalogo
portfolio:write Crear/editar productos
portfolio:delete Eliminar productos
portfolio:publish Publicar/despublicar
portfolio:manage Configuracion avanzada

5. Frontend

5.1 Paginas Implementadas

Ruta Componente Estado
/dashboard/portfolio PortfolioPage Implementado
/dashboard/portfolio/products ProductsPage Implementado
/dashboard/portfolio/categories CategoriesPage Implementado
/dashboard/portfolio/products/:id ProductDetailPage Pendiente
/dashboard/portfolio/products/new ProductFormPage Pendiente

5.2 Hooks

// frontend/src/hooks/usePortfolio.ts
useCategories, useCategory, useCategoryTree
useCreateCategory, useUpdateCategory, useDeleteCategory
useProducts, useProduct
useCreateProduct, useUpdateProduct, useDeleteProduct, useDuplicateProduct
useProductVariants, useCreateVariant, useUpdateVariant, useDeleteVariant
useProductPrices, useCreatePrice, useUpdatePrice, useDeletePrice

6. Integraciones

6.1 Modulos Relacionados

Modulo Integracion
sales Productos en oportunidades
commissions Comisiones por producto/categoria
storage Imagenes de productos
audit Log de cambios

6.2 Eventos Emitidos

ProductCreated, ProductUpdated, ProductStatusChanged
CategoryCreated, CategoryUpdated
VariantCreated, PriceUpdated
LowStockAlert // Cuando stock < threshold

7. Filtros y Busqueda

7.1 Filtros Disponibles

interface ProductFilters {
  category_id?: string;
  product_type?: ProductType;
  status?: ProductStatus;
  is_visible?: boolean;
  is_featured?: boolean;
  min_price?: number;
  max_price?: number;
  search?: string;      // Busca en name, sku, description
  tags?: string[];
  sort_by?: 'name' | 'price' | 'created_at' | 'stock';
  sort_order?: 'ASC' | 'DESC';
}

8. Referencias

  • DDL: database/ddl/schemas/portfolio/
  • Backend: backend/src/modules/portfolio/
  • Frontend Services: frontend/src/services/portfolio/
  • Frontend Hooks: frontend/src/hooks/usePortfolio.ts
  • Frontend Pages: frontend/src/pages/dashboard/portfolio/