# PROMPT SPRINT 1.4 — Panel de Administración

> **Para Ricci:** Pegá este prompt en una sesión NUEVA de Claude Code.
> Este es el sprint más grande del proyecto. Estimación: 3-5 sesiones de Claude Code, 4-8 horas de tu validación al final.

---

Hola Claude. Soy Ricci de Crono Systems. Sprint 1.3 cerrado (schema catálogo), ahora vamos con **Sprint 1.4: Panel de Administración**.

## Estado actual

```bash
git log --oneline | head -30
```

Tenés:
- 17 tablas en cada tenant (8 sistema + 8 catálogo + migrations)
- 5 tablas en innovium_master
- 8 models del catálogo (`Categoria`, `Nivel`, `Producto`, `ProductoVariante`, `ProductoImagen`, `PlanLinea`, `PrecioUf`, `TenantConfig`)
- 85 tests verdes
- TenantResolver funcionando con subdominios `*.innovium.test`
- Login + dashboard placeholder styled
- Las tablas del catálogo están VACÍAS (intencional, las llena el admin)

## Lectura obligatoria antes de codear

En orden:

1. `CLAUDE.md`
2. `docs/ARQUITECTURA.md`
3. `docs/sprint-1-3/SCHEMA_CATALOGO.md` — entender los modelos
4. `docs/sprint-1-4/DESIGN_ADMIN_LAYOUT.md` — cómo se ve cada pantalla
5. `docs/sprint-1-4/STORAGE_R2.md` — cómo integrar R2
6. `docs/sprint-1-4/VALIDADOR_CHILE.md` — reglas de validación chilenas
7. `docs/sprint-1-4/CRITERIOS_ACEPTACION_1_4.md` — qué tiene que pasar para cerrar
8. `design-kit/DESIGN_SYSTEM.md` — sección de tablas, modales, formularios
9. `design-kit/mockups/v2_dashboard.svg` — patrón visual del sidebar y cards
10. `app/Models/User.php` — patrón de data-mapper
11. `app/Views/dashboard/index.php` — el layout y estilos a replicar
12. `app/Middleware/RbacMiddleware.php` — cómo se chequean permisos

**No empieces hasta haber leído todo.**

## Alcance del sprint

### Lo que entra ✅

#### Infraestructura

1. **`app/Core/Storage.php`** — gateway R2 con prefijo automático por tenant
   - `Storage::put($path, $contents)` → sube a R2 con prefijo `tenants/<slug>/`
   - `Storage::url($path, $ttlSeconds = 3600)` → URL firmada con expiración
   - `Storage::delete($path)` → elimina objeto
   - `Storage::exists($path)` → check existencia
   - Internamente usa `aws-sdk-php` (ya instalado)

2. **`app/Core/Validator.php`** — clase de validación con reglas custom
   - `Validator::make($data, $rules)` → devuelve instancia
   - `errors(): array` → errores por campo
   - `passes(): bool`, `fails(): bool`
   - Reglas built-in: `required`, `email`, `min:X`, `max:X`, `numeric`, `decimal`, `integer`, `boolean`, `in:a,b,c`, `unique:tabla,columna`, `exists:tabla,columna`, `image`, `mimes:jpg,png`, `dimensions:min_w=400`
   - Reglas custom chilenas: `rut`, `telefono_chileno`, `slug`, `precio_clp`, `precio_uf`

3. **`app/Core/Upload.php`** — handler de archivos subidos
   - `Upload::fromRequest($field): ?UploadedFile`
   - Validación: tamaño max, mime type, dimensiones (para imágenes)
   - Usa `Storage::put()` para subir

4. **Permissions nuevos** seedeados en `permissions`:
   - `admin.acceso` (root del panel admin)
   - `categorias.gestionar`, `niveles.gestionar`, `productos.gestionar`, `planes.gestionar`
   - `tenant.configurar` (ya existía, mantener)

5. **Mapping de roles a estos permisos**:
   - `tenant_admin` → todos los `admin.*` y `*.gestionar` y `tenant.configurar`
   - `gerente` → solo lectura (que aún no existe como permiso, lo agregamos: `categorias.ver`, etc.)
   - Vendedor / operativo / contador → ninguno

#### Layout y navegación

6. **`app/Views/layouts/admin.php`** — layout para todas las pantallas admin
   - Sidebar nuevo con secciones: MÓDULOS (placeholder Próx.), ADMINISTRACIÓN (los 5 nuevos), USUARIO al fondo
   - Misma estética que dashboard (mesh-app, glass cards, paleta)
   - Topbar con greeting + breadcrumbs
   - Mobile: sidebar drawer

7. **Componente sidebar dinámico**: el item activo se resalta según la ruta actual

#### Pantallas (5)

8. **`/admin/categorias`** — CRUD de categorías
   - Listado con búsqueda
   - Botón "Nueva categoría" → modal
   - Click en fila → modal de edición
   - Botón eliminar (soft delete) con confirmación

9. **`/admin/niveles`** — CRUD de niveles (mismo patrón)

10. **`/admin/productos`** — CRUD de productos
    - Listado con filtros (categoría, nivel, tipo, activo)
    - Vista detalle con galería de imágenes
    - Form de crear/editar con todos los campos del modelo
    - Upload de imágenes con preview
    - Drag & drop opcional para reordenar imágenes (si es complejo, dejarlo para 1.4 fase 2)

11. **`/admin/planes`** — CRUD de planes (el más complejo)
    - Lista de planes
    - Form de crear/editar con builder de líneas:
      - Botón "Agregar línea fija" → selector de producto + cantidad + obligatorio
      - Botón "Agregar línea elección" → selector de categoría (+ nivel opcional) + cantidad + obligatorio
      - Drag & drop opcional para reordenar líneas
    - Preview del plan (qué incluye)

12. **`/admin/configuracion`** — settings del tenant
    - Tabs: Monetario (UF, IVA, moneda), Funeraria (nombre, RUT, dirección, teléfono), Branding (logo, color primario)
    - Cada campo con `TenantConfig::set()`
    - Upload de logo a R2

#### Componentes UI reutilizables

13. **`app/Views/components/`** — componentes incluibles
    - `tabla.php` — tabla con header, filas, paginación, estado vacío
    - `modal.php` — modal con backdrop blur, animación
    - `form-input.php` — input con label, error message
    - `form-select.php` — select customizado
    - `form-textarea.php`
    - `form-toggle.php` — switch tipo iOS
    - `form-image-upload.php` — upload con preview drag&drop
    - `boton-primary.php`, `boton-secondary.php`, `boton-destructive.php`
    - `pill.php` — pills de estado/categoría
    - `confirm-dialog.php` — confirmación destructiva
    - `toast.php` — notificación esquina superior derecha (Alpine.js)

14. **`resources/js/`** — JavaScript modular
    - `alpine-init.js` — inicializa Alpine
    - `image-upload.js` — drag & drop + preview client-side
    - `confirm.js` — wrapper de modales de confirmación
    - `toast.js` — sistema de notificaciones

#### Tests

15. **Tests unitarios**:
    - `ValidatorTest` — todas las reglas (incluyendo RUT chileno)
    - `UploadTest` — validación de tamaño, mime, dimensiones
    - `StorageR2Test` — mocked, no toca R2 real

16. **Tests integración** (HTTP):
    - `AdminCategoriaControllerTest` — CRUD completo
    - `AdminNivelControllerTest`
    - `AdminProductoControllerTest`
    - `AdminPlanControllerTest`
    - `AdminConfiguracionControllerTest`
    - `AdminAccessTest` — vendedor no puede acceder, gerente solo puede ver, tenant_admin puede todo

### Lo que NO entra ❌

- 🚫 Visor 360° de productos (Sprint 2.x)
- 🚫 Integración API de UF (Sprint 2.x)
- 🚫 Dashboard de admin con KPIs (Sprint 2.x)
- 🚫 Bulk operations (importar/exportar Excel) — Sprint 3.x+
- 🚫 Historial de cambios visible en UI (existe en audit_log pero sin pantalla todavía)
- 🚫 Notificaciones email al admin de funeraria — Sprint 2.x

## Decisiones ya tomadas

### Storage R2

- Bucket: `innovium-storage`
- Prefijo automático por tenant: `tenants/<slug>/`
- Estructura de paths:
  ```
  /tenants/<slug>/productos/<producto_id>/<uuid>.<ext>
  /tenants/<slug>/branding/logo.<ext>
  /tenants/<slug>/branding/favicon.<ext>
  ```
- URLs firmadas con TTL 1 hora por default
- Variables `.env`: `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET=innovium-storage`, `R2_ENDPOINT`

### Subida de imágenes

- Validación client-side primero (tamaño, mime, dimensiones)
- Preview con `URL.createObjectURL()` antes de upload
- Upload a R2 vía endpoint `POST /admin/upload-image`
- Server response: `{ id, r2_path, url_temporal }`
- Solo después de confirmar el form se asocia el `r2_path` al producto

### Validaciones

- Server-side **siempre** (cliente puede mentir)
- RUT chileno con algoritmo correcto (módulo 11)
- Slugs únicos por tenant (no globales)
- Precios siempre positivos, max razonable
- Imágenes: max 5MB, mimes JPEG/PNG/WebP, dimensiones min 400x400

### UI/UX

- **NO usar Bootstrap, AdminLTE, Tabler ni cualquier admin template.** Construir desde cero con Tailwind + theme.css.
- **Modal de crear/editar** en lugar de pantallas separadas (más rápido para el admin).
- **Toast notifications** después de cada acción (success/error).
- **Confirmación destructiva** antes de eliminar.
- **Estados de carga** (buttons disabled + spinner inline) durante AJAX.
- **Mobile-first** — todas las pantallas funcionan en tablet 1024×768.

### Audit log

- TODAS las mutaciones del admin escriben a `audit_log`
- Acciones: `categoria.creada`, `categoria.actualizada`, `categoria.eliminada`, etc.
- Datos antes/después en JSON (sin valores sensibles como passwords)

## Plan de commits sugerido

Atómicos, en este orden:

### Fase A · Infraestructura
1. `feat(core): Validator con reglas chilenas (RUT, telefono, slug)`
2. `feat(core): Storage gateway R2 con prefijo por tenant`
3. `feat(core): Upload handler con validación de archivos`
4. `feat(db): permissions del panel admin`
5. `feat(views): layout admin y sidebar dinámico`

### Fase B · Componentes UI
6. `feat(views): componentes base (tabla, modal, forms, botones)`
7. `feat(js): Alpine helpers (toast, confirm, image upload)`

### Fase C · Pantallas (de simple a complejo)
8. `feat(admin): pantalla de categorías (CRUD)`
9. `feat(admin): pantalla de niveles (CRUD)`
10. `feat(admin): pantalla de configuración del tenant`
11. `feat(admin): pantalla de productos con upload de imágenes`
12. `feat(admin): pantalla de planes con builder de líneas`

### Fase D · Tests y cierre
13. `test: Validator + Upload + Storage`
14. `test: controllers admin + access control`
15. `chore: sprint 1.4 cerrado`

## Cómo trabajar conmigo

1. Empezás leyendo los 12 archivos de "lectura obligatoria"

2. **Confirmá 6 puntos antes de tocar archivos:**
   - ¿Leíste DESIGN_ADMIN_LAYOUT.md y entendés la estructura del sidebar?
   - ¿Leíste STORAGE_R2.md y vas a usar `aws-sdk-php` (ya instalado)?
   - ¿Confirmas validación tanto client como server-side?
   - ¿Confirmas que NO usás Bootstrap, AdminLTE ni component libraries?
   - ¿Confirmas que las pantallas usan modales (no rutas separadas) para crear/editar?
   - ¿Tenés claro que las 5 pantallas se construyen al final, después de la infra?

3. **Importante: ESTE SPRINT NO MUESTRA pantallas individualmente al usuario.** Ricci pidió ver todo al final, no después de cada pantalla. Vos avanzás con todos los commits del plan, mostrando solo:
   - Avance de fase A (infra) cuando termine
   - Avance de fase B (componentes) cuando termine
   - Avance de fase C (5 pantallas, una por una en commits separados pero sin pedir validación entre cada una)
   - Resumen final cuando todo esté listo

4. Si tenés dudas técnicas, **preguntá** antes de inventar.

5. Cuando termines TODO el sprint, mostrame:
   - `git log --oneline | head -20`
   - Lista de pantallas implementadas con sus URLs
   - Output de PHPUnit (todos verdes)
   - Cualquier decisión que tomaste que se desvió del plan

6. **Después de tu reporte final, Ricci abre el navegador y valida visualmente las 5 pantallas con la checklist de aceptación. Ahí pueden venir ajustes visuales.**

## Tiempo estimado

- Trabajo de Claude Code: 3-5 sesiones (split natural si se llena la context window)
- Validación de Ricci: 1-2 horas (5 pantallas + uploads + permisos)

¡Vamos! 🚀
