# Product Packager — cómo nace un producto en BewPro

> Source of truth para formular productos nuevos. **1 brief declarativo → todas las piezas del producto generadas**.

---

## Anatomía de un producto (qué piezas tiene)

Un producto en BewPro es la combinación de **6 piezas** distribuidas:

| Pieza | Donde vive | Función |
|-------|------------|---------|
| **Catalog entry** | `database/seeders/products/catalog.json` | Mapping `slug comercial → core técnico` + nombre |
| **Core preset** | `database/seeders/products/core/{core}.json` | demo, módulos, skin, fonts, brand_defaults, schema_type, header CTA, footer nav, welcome/about/contact defaults |
| **Module seeds** | `database/seeders/products/core/seeds/{module}-{core}.json` | Contenido inicial por módulo (blog, services, etc.) |
| **Demo schema** | `database/schemas/demos/{demo}.json` | Paridad vista↔JSON validada por CI |
| **Airtable Shop Products + Copy** | Airtable | Copy comercial (headline, CTA, value props) + pricing |
| **Stripe Price** | Stripe + DB `products.stripe_price_id` | Precio real de checkout |

Hoy crear un producto = **6 pasos manuales descoordinados**. El packager unifica todo en 1 brief.

---

## Formato del Brief

```json
{
    "slug": "vegan-restaurant",
    "name": "Sitio Web para Restaurante Vegano",
    "category": "Gastronomía",
    "core_base": "restaurant-bar",
    "create_new_core": false,
    "modules_override": null,
    "branding": {
        "colors": {
            "primary": "#2E7D32",
            "secondary": "#FFF8E1",
            "tertiary": null
        },
        "fonts": null,
        "logo_pack": null
    },
    "copy": {
        "tagline": "Comida vegana con identidad",
        "description": "...",
        "headline": "Tu mesa, sin culpa.",
        "subheadline": "Recetas autorales con productos de estación.",
        "value_props": ["Sin trazas animales", "Productos de estación"],
        "cta_primary": "Reservar mesa"
    },
    "pricing": {
        "monthly_usd": 25,
        "tier": "Profesional",
        "stripe_price_id": null
    },
    "schema_type_override": null,
    "demo_url_override": null
}
```

### Campos requeridos

| Campo | Obligatorio | Valor |
|-------|------------|-------|
| `slug` | ✅ | kebab-case único, ej. `vegan-restaurant` |
| `name` | ✅ | Nombre comercial, ej. "Sitio Web para Restaurante Vegano" |
| `core_base` | ✅ | Slug de un core existente como base |

### Decisión clave: `create_new_core`

| Valor | Cuándo usar | Resultado |
|-------|-------------|-----------|
| `false` (default) | El nuevo producto es solo **variante comercial** del core base — mismo demo, mismos módulos, mismas vistas | Solo se agrega entry en `catalog.json`. El producto comparte 100% el core técnico base. |
| `true` | El nuevo producto necesita **diferencias técnicas** (otros módulos, otro branding default, otro schema SEO) | Se crea `core/{slug}.json` nuevo, copiando el base + aplicando los overrides del brief |

**Regla**: si solo cambia el copy/pricing/categoría/branding visible al cliente → `false`. Si cambia demo/módulos/schema-type → `true`.

### Overrides al crear core nuevo

Cuando `create_new_core: true`, estos campos del brief se aplican al core nuevo:

| Brief field | Affects core | 
|-------------|--------------|
| `modules_override` | `modules[]` + `modules_navigation` reset |
| `branding.colors` | `brand_defaults.colors` (merge con base) |
| `branding.fonts` | `brand_defaults.fonts` + `fonts` |
| `branding.logo_pack` | `brand_defaults.logo_pack` |
| `copy.tagline` | `tagline` |
| `copy.description` | `description` + `footer.description` |
| `copy.cta_primary` | `header.cta_button.title` |
| `schema_type_override` | `schema_type` |
| `demo_url_override` | `demo_url` |

Lo que NO override (siempre hereda del base): `demo`, `welcome`, `about`, `contact` blocks, `footer.navegacion_principal`, `seo.keywords`, etc. Para modificar esos, editar el core JSON resultante.

---

## Comandos

### Scaffold (generar brief vacío)

```bash
php artisan bewpro:package-product --scaffold=storage/briefs/my-product.json --slug=my-product
```

### Preview (dry-run)

```bash
php artisan bewpro:package-product --brief=storage/briefs/my-product.json --dry-run
```

Muestra:
- Errores de validación
- Warnings (seeds faltantes, demo sin schema)
- Acciones que se aplicarían
- Tareas manuales post-packaging

### Aplicar (real)

```bash
php artisan bewpro:package-product --brief=storage/briefs/my-product.json
```

Pide confirmación. Aplica catalog.json + core nuevo (si toca) + reporta tareas manuales.

### Modo interactivo (preguntar campo por campo)

```bash
php artisan bewpro:package-product --interactive
```

---

## Qué hace el packager automáticamente

1. ✅ Valida estructura del brief
2. ✅ Verifica que `core_base` exista
3. ✅ Verifica que el demo del core base tenga schema (paridad blade↔JSON)
4. ✅ Lista seeds faltantes para módulos activos (warning, no bloquea)
5. ✅ Crea `core/{slug}.json` si `create_new_core=true`
6. ✅ Actualiza `catalog.json` con la entry nueva

## Qué queda como tarea manual (reporta al final)

| Sistema | Tarea |
|---------|-------|
| **Airtable** | Crear/actualizar records en Shop Products + Shop Products Copy con el copy del brief |
| **Stripe** | Crear Stripe Price recurring + agregar `stripe_price_id` al producto |
| **cd-system DB** | Correr `php artisan bewpro:catalog:seed` para hidratar producto en DB |

A futuro estas 3 tareas pueden automatizarse via API. Hoy son guidance — el comando te las imprime literales para que las hagas.

---

## Workflow típico

### Caso A — Producto sobre core existente (90% de los casos)

```bash
# 1. Scaffold
php artisan bewpro:package-product --scaffold=storage/briefs/vegan-restaurant.json --slug=vegan-restaurant

# 2. Editar el brief con:
#    core_base = "restaurant-bar"
#    create_new_core = false
#    name, category, copy, pricing

# 3. Preview
php artisan bewpro:package-product --brief=storage/briefs/vegan-restaurant.json --dry-run

# 4. Aplicar
php artisan bewpro:package-product --brief=storage/briefs/vegan-restaurant.json

# 5. Tareas manuales (Airtable + Stripe + bewpro:catalog:seed) — el comando te las imprime
```

### Caso B — Producto que necesita core nuevo

Misma idea pero `create_new_core: true` + override de módulos/branding/schema_type.

Si el core nuevo activa módulos que no tienen seed canónico:
- El packager warnea con "Seed faltante para módulo X"
- Antes de provisionar, crear `seeds/{module}-{slug}.json` (puede ser tarea Leandro/IA, copiando uno similar de otro core como template)

---

## Escalabilidad — por qué esto resuelve el problema

**Antes** (sistema actual):
- Sumar un producto = editar 6 archivos + records en Airtable + Stripe + DB seeder run
- Alta probabilidad de drift / olvido / inconsistencia
- 254 entries en catalog.json acumuladas sin proceso estandarizado

**Después** (con packager):
- Sumar un producto = 1 brief + 1 comando + checklist de tareas manuales (cada vez más pocas a medida que sumamos API integrations)
- Paridad blade↔schema validada por CI antes del packaging
- Brief versionable (git history del directorio briefs/) → trazabilidad completa
- AI agents (`product-packager`, `product-copywriter`, `pricing-strategist`) pueden generar briefs automáticamente

### Para sumar 100 productos más

```bash
# 1. AI agent genera 100 briefs en storage/briefs/
# 2. Loop:
for brief in storage/briefs/*.json; do
  php artisan bewpro:package-product --brief="$brief" --force
done
# 3. Sync masivo a Airtable + Stripe (commands separados, idempotentes)
```

---

## Próximas mejoras

- [ ] **Auto-sync Airtable**: `bewpro:catalog:sync-airtable` push de catálogo nuevo a Airtable
- [ ] **Auto-create Stripe Price**: comando dedicado con confirmación
- [ ] **Generador de seeds**: `bewpro:scaffold-seeds {module} {core}` que copia seeds de otro core como base
- [ ] **Validación cruzada**: `bewpro:validate-product {slug}` que verifica todas las piezas (catalog + core + seeds + schema + Airtable + Stripe)
- [ ] **UI admin**: form web para crear briefs sin tocar JSON
