template-saas/docs/01-modulos/SAAS-019-portfolio.md
Adrian Flores Cortes 7d05081b4d
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
[SAAS-018-022] docs: Add specifications for advanced modules
Add complete specifications for 5 advanced modules:
- SAAS-018 Sales Foundation (21 SP) - Leads, opportunities, pipeline
- SAAS-019 Portfolio (13 SP) - Product/service catalog
- SAAS-020 Commissions (13 SP) - Commission system for salespeople
- SAAS-021 MLM (21 SP) - Multi-level marketing networks
- SAAS-022 Goals (13 SP) - Goals and objectives tracking

Each specification includes:
- Complete DDL with RLS policies
- Full API endpoint documentation
- Frontend pages and components
- Dependencies and integration points
- Story point estimates

Total new SP: 81 (bringing total to 260 SP)
Core modules: 14 (100% complete)
Advanced modules: 5 (specified, ready for implementation)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 20:12:07 -06:00

7.9 KiB

id title type status priority module version created_date updated_date estimated_sp
SAAS-019 Portfolio Module Specified P2 portfolio 1.0.0 2026-01-24 2026-01-24 13

SAAS-019: Portfolio

Metadata

  • Codigo: SAAS-019
  • Modulo: Portfolio
  • Prioridad: P2
  • Estado: Especificado
  • Fase: 6 - Advanced Features
  • Story Points: 13

Descripcion

Catalogo de productos y servicios para plataformas SaaS. Permite definir ofertas, precios, categorias y variantes. Se integra con Sales para cotizaciones y con Billing para suscripciones basadas en productos.

Objetivos

  1. Catalogo de productos/servicios configurable
  2. Categorias y subcategorias jerarquicas
  3. Precios con multiples monedas
  4. Variantes de productos (tallas, colores, etc.)
  5. Integracion con Sales y Billing

Alcance

Incluido

  • CRUD de productos/servicios
  • Categorias jerarquicas
  • Precios por moneda
  • Variantes basicas
  • Imagenes de productos
  • Productos activos/inactivos
  • Busqueda y filtros
  • Exportacion catalogo

Excluido

  • Inventario (erp-core)
  • Ordenes de compra (erp-core)
  • Proveedores (erp-core)
  • Configurador de productos complejo

Modelo de Datos

Schema: portfolio

-- Categorias
CREATE TABLE portfolio.categories (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),

    name VARCHAR(100) NOT NULL,
    slug VARCHAR(100) NOT NULL,
    description TEXT,
    parent_id UUID REFERENCES portfolio.categories(id),

    image_url VARCHAR(500),
    position INTEGER DEFAULT 0,
    is_active BOOLEAN DEFAULT true,

    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT unique_category_slug UNIQUE (tenant_id, slug)
);

-- Productos
CREATE TABLE portfolio.products (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),

    -- Info basica
    name VARCHAR(200) NOT NULL,
    slug VARCHAR(200) NOT NULL,
    description TEXT,
    short_description VARCHAR(500),

    -- Clasificacion
    type portfolio.product_type NOT NULL DEFAULT 'product',
    category_id UUID REFERENCES portfolio.categories(id),

    -- Codigo
    sku VARCHAR(100),
    barcode VARCHAR(100),

    -- Precios
    base_price DECIMAL(15,2) NOT NULL DEFAULT 0,
    currency VARCHAR(3) DEFAULT 'USD',
    tax_rate DECIMAL(5,2) DEFAULT 0,

    -- Estado
    status portfolio.product_status NOT NULL DEFAULT 'draft',
    is_featured BOOLEAN DEFAULT false,

    -- Media
    images JSONB DEFAULT '[]',
    thumbnail_url VARCHAR(500),

    -- Metadata
    tags JSONB DEFAULT '[]',
    attributes JSONB DEFAULT '{}',
    meta_title VARCHAR(200),
    meta_description VARCHAR(500),

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT unique_product_slug UNIQUE (tenant_id, slug),
    CONSTRAINT unique_product_sku UNIQUE (tenant_id, sku)
);

-- Variantes
CREATE TABLE portfolio.variants (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    product_id UUID NOT NULL REFERENCES portfolio.products(id) ON DELETE CASCADE,
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),

    name VARCHAR(200) NOT NULL,
    sku VARCHAR(100),

    -- Precio diferencial
    price_adjustment DECIMAL(15,2) DEFAULT 0,
    price_type portfolio.price_type DEFAULT 'adjustment', -- 'adjustment' | 'fixed'

    -- Atributos (color, talla, etc.)
    attributes JSONB NOT NULL DEFAULT '{}',

    -- Estado
    is_active BOOLEAN DEFAULT true,

    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Precios por moneda
CREATE TABLE portfolio.prices (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    product_id UUID NOT NULL REFERENCES portfolio.products(id) ON DELETE CASCADE,
    variant_id UUID REFERENCES portfolio.variants(id) ON DELETE CASCADE,

    currency VARCHAR(3) NOT NULL,
    amount DECIMAL(15,2) NOT NULL,

    -- Precios especiales
    compare_at_price DECIMAL(15,2), -- Precio tachado
    cost_price DECIMAL(15,2), -- Costo

    -- Vigencia
    starts_at TIMESTAMPTZ,
    ends_at TIMESTAMPTZ,

    created_at TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT unique_price UNIQUE (product_id, variant_id, currency)
);

-- Enums
CREATE TYPE portfolio.product_type AS ENUM (
    'product', 'service', 'digital', 'subscription'
);

CREATE TYPE portfolio.product_status AS ENUM (
    'draft', 'active', 'inactive', 'archived'
);

CREATE TYPE portfolio.price_type AS ENUM (
    'adjustment', 'fixed'
);

RLS Policies

ALTER TABLE portfolio.categories ENABLE ROW LEVEL SECURITY;
ALTER TABLE portfolio.products ENABLE ROW LEVEL SECURITY;
ALTER TABLE portfolio.variants ENABLE ROW LEVEL SECURITY;
ALTER TABLE portfolio.prices ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON portfolio.products
    USING (tenant_id = current_setting('app.current_tenant_id')::UUID);

Endpoints API

Categories

Metodo Endpoint Descripcion
GET /portfolio/categories Listar categorias
POST /portfolio/categories Crear categoria
GET /portfolio/categories/:id Obtener categoria
PATCH /portfolio/categories/:id Actualizar categoria
DELETE /portfolio/categories/:id Eliminar categoria
GET /portfolio/categories/tree Arbol jerarquico

Products

Metodo Endpoint Descripcion
GET /portfolio/products Listar productos
POST /portfolio/products Crear producto
GET /portfolio/products/:id Obtener producto
PATCH /portfolio/products/:id Actualizar producto
DELETE /portfolio/products/:id Eliminar producto
POST /portfolio/products/:id/duplicate Duplicar producto
PATCH /portfolio/products/:id/status Cambiar estado

Variants

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

Prices

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

Frontend

Paginas

  • /portfolio - Dashboard catalogo
  • /portfolio/products - Lista de productos
  • /portfolio/products/new - Crear producto
  • /portfolio/products/:id - Editar producto
  • /portfolio/categories - Gestion categorias

Componentes

  • ProductsList - Tabla/grid de productos
  • ProductForm - Formulario producto completo
  • ProductCard - Tarjeta preview
  • VariantsManager - Gestion variantes
  • PricesManager - Gestion precios multi-moneda
  • CategoryTree - Arbol de categorias
  • CategoryForm - Formulario categoria
  • ImageUploader - Subida de imagenes
  • ProductSearch - Busqueda avanzada

Hooks

  • useProducts - CRUD productos
  • useCategories - CRUD categorias
  • useVariants - CRUD variantes
  • usePrices - CRUD precios

Dependencias

Modulos Requeridos

  • SAAS-001 Auth
  • SAAS-002 Tenants
  • SAAS-011 Storage (imagenes)

Modulos Opcionales

  • SAAS-018 Sales (productos en oportunidades)
  • SAAS-004 Billing (suscripciones)

Criterios de Aceptacion

  1. CRUD productos con validaciones
  2. Categorias jerarquicas funcionales
  3. Variantes con atributos dinamicos
  4. Precios multi-moneda
  5. Subida de imagenes integrada
  6. Busqueda y filtros avanzados
  7. Tests unitarios (>70% coverage)

Estimacion

Componente SP
DDL + Entities 2
Backend Services 3
Controllers + DTOs 2
Frontend Pages 3
Frontend Components 2
Tests 1
Total 13

Ultima actualizacion: 2026-01-24 Autor: Claude Opus 4.5