# Sprint 1 — checklist E2E por rol

> Última actualización: 2026-05-07
> Cubre: Sprint 1 "Roles operativos" (12h estimadas, ejecutado en una sesión).
> Pre-requisitos para validar: `php artisan migrate` + `php artisan optimize:clear` + login simultáneo en 4 ventanas.

## Pre-flight (una sola vez)

```bash
# 1. Correr migraciones nuevas (parent_reseller_id + admin_notes)
php artisan migrate

# 2. Asegurar roles + permisos (idempotente)
php artisan db:seed --class=BewProRolesPermissionsSeeder

# 3. Asegurar test users (idempotente, resetea passwords a las conocidas)
php artisan bewpro:seed-test-users

# 4. Limpiar caches de view + permission
php artisan optimize:clear
php artisan tinker --execute="app(Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();"
```

## Credenciales

| Rol | Email | Password |
|---|---|---|
| Customer | `coke_colombres@hotmail.com` | `Customer1!` |
| Reseller | `lacompaniad@gmail.com` | `Reseller1!` |
| Admin Comercial | `leandro@lacompaniadigital.com` | `Comercial1!` |
| Admin General | `juan@bewpro.com` | `Admin1!` |

URL común: `http://127.0.0.1:8000/login`

> **Tip**: 4 ventanas (1 normal + 3 incógnitos, o Firefox Multi-Account Containers).

## Customer (`coke_colombres`)

- [ ] Login OK → redirige a `/my-projects`.
- [ ] **Header arriba a la derecha**: muestra avatar con iniciales `CC` (no avatar gris genérico) + "Coke Colombres" + rol "Client" debajo.
- [ ] **Click en avatar** → dropdown muestra: Mi Perfil · Mis Pagos · Sign Out.
- [ ] Click "Mi Perfil" → `/my-projects/profile` carga form de datos + cambio password.
- [ ] **Sidebar izquierdo**: solo aparecen los items "Mis Proyectos" (Panel · Mis Pagos · Soporte) + "Mi Cuenta" (Programa de Resellers · Comprar otro proyecto). NINGÚN item `/admin/*`.
- [ ] Si tiene 1+ proyecto creado en últimos 1d con status `required`/`on_development` → ve **welcome card grande** persistente (no flash). Tiene botón "Ocultar".
- [ ] Va a `/admin/customers` → 403 o redirect a `/my-projects` (no admin).
- [ ] Va a `/admin/resellers` → 403.
- [ ] Va a `/reseller` → 403 (no es Reseller).

## Reseller (`lacompaniad`)

- [ ] Login OK → redirige a `/my-projects` (default landing).
- [ ] **Header**: avatar con iniciales `CD`, nombre "Compañía Digital", rol "Reseller".
- [ ] **Sidebar**: además de "Mis Proyectos" + "Mi Cuenta", aparece sección **"Mi Negocio"** con: Panel Reseller · Mis Clientes · Proyectos-Cliente.
- [ ] Click "Panel Reseller" → `/reseller` carga dashboard con 4 stats (Clientes/Proyectos/Activos/MRR) + acciones rápidas + "Últimos proyectos" (vacío por ahora — no hay TPs con `parent_reseller_id = $reseller->id`).
- [ ] Click "Mis Clientes" → `/reseller/customers` muestra tabla vacía con search.
- [ ] Click "Proyectos-Cliente" → `/reseller/projects` muestra tabla vacía con filtros.
- [ ] Va a `/admin/customers` → 403.
- [ ] Va a `/my-projects/profile` → carga (Reseller también puede editar perfil).

## Admin Comercial (`leandro`)

- [ ] Login OK → redirige al admin del CMS legacy.
- [ ] **Header**: avatar `LC`, nombre "Leandro CD", rol "Admin Comercial".
- [ ] **Sidebar**: aparece bloque **"Customers"** + **"Resellers"** (NO ve "Mis Proyectos" / "Mi Negocio"). Ve también el sidebar legacy del CMS pero los items de plataforma (settings, modules) están filtrados.
- [ ] Click "Customers" → `/admin/customers` carga tabla de 254+ users con filtros (fecha, sort, etc.).
- [ ] Click en un customer → `/admin/customers/{id}/edit` carga datos + roles + acciones de soporte + **"Notas internas"** (campo nuevo `admin_notes` editable).
- [ ] Edita "Notas internas" → guarda OK con flash success.
- [ ] **NO ve botón "Borrar selección"** en bulk (porque no tiene `customers.delete`). Si selecciona y trata, el server responde "Tu rol no tiene el permiso `customers.delete`".
- [ ] Cambia rol de un user → server responde "Tu rol no tiene el permiso `customers.assign-roles`".
- [ ] Click "Resellers" → `/admin/resellers` carga tabla de applications. Stats arriba (Pendientes / En revisión / Aprobados / Rechazados).
- [ ] Click en una application → `/admin/resellers/{id}` muestra detalle + form para aprobar/rechazar.
- [ ] **Aprueba** una application → status pasa a `approved`, user obtiene rol `Reseller` (verificable con tinker o en `/admin/customers/{user}/edit`).
- [ ] Va a `/admin/onboarding` → bloqueado (no permission `platform.*`).

## Admin General (`juan`)

- [ ] Login OK → admin completo.
- [ ] **Header**: avatar `JM`, nombre "Juan Mercado", rol "Administrator".
- [ ] **Sidebar**: ve TODO — "Customers" + "Resellers" + bloque legacy del CMS + plataforma (Mi Marca / settings).
- [ ] En `/admin/customers` puede **bulk delete** + **assign roles**.
- [ ] Aprueba una reseller application igual que Admin Comercial.
- [ ] Asigna rol "Admin Comercial" a un user → user logea y ve sidebar admin.

## Tests cross-rol críticos

### Aprobación reseller end-to-end
1. Customer (`coke`) va a `/resellers/apply`, completa form → genera `ResellerApplication` status=pending.
2. Admin Comercial (`leandro`) ve la nueva application en `/admin/resellers` con stats "Pendientes: 1".
3. Admin Comercial click "Marcar en revisión" → status=reviewing.
4. Admin Comercial completa "Notas del revisor" + click "Aprobar" → status=approved + user obtiene rol Reseller.
5. Customer logea de nuevo → ahora ve sidebar de Reseller con "Mi Negocio". Slack canal `support` recibe notif.

### Permission gate en bulk action
1. Admin Comercial entra a `/admin/customers`, selecciona 3 stress users con checkbox.
2. Elige "⚠️ Borrar" en bar → click Ejecutar.
3. JS confirm → server responde flash error `"Tu rol no tiene el permiso 'customers.delete' para esa acción"`.
4. Admin General hace exactamente lo mismo → 3 users borrados OK.

### Self-lockout protection
1. Admin General (`juan`) entra a su propia ficha en `/admin/customers/4/edit`.
2. Desmarca su propio rol "Administrator" → submit.
3. Server responde flash error `"No podés quitarte a vos mismo el rol Administrator."`.
4. Sigue siendo Admin.

## Checklist de QA visual

- [ ] Avatar con iniciales se ve consistente entre roles.
- [ ] Sidebar "Mi Negocio" tiene separator + label antes de los items Reseller.
- [ ] Stats cards (`/admin/resellers`, `/reseller`) son clickeables y filtran.
- [ ] Welcome card del Customer se ve solo si tiene proyectos en progreso (no a un user veterano).
- [ ] Tablas con `table-row-dashed` se ven prolijas en mobile (responsive).

## Comandos útiles

```bash
# Ver permisos efectivos de un user
php artisan tinker
> User::where('email','leandro@lacompaniadigital.com')->first()->getAllPermissions()->pluck('name')

# Forzar reseller a Customer (testing)
> User::where('email','...')->first()->syncRoles(['Client'])

# Crear ResellerApplication de test
> App\Models\ResellerApplication::create(['user_id' => 255, 'business_name' => 'Test Co', 'target_market' => 'argentina', 'monthly_clients_estimate' => '0-5', 'why_partner' => 'Probando el flujo completo de aprobación', 'status' => 'pending'])
```

## Polish post-Sprint 1 (todo cubierto en commit 2 del 2026-05-07)

- ✅ Customer: avatar iniciales, botón primary "Entrar al admin", ETA con progress bar, link a soporte para credenciales perdidas, perfil editable, welcome card persistente
- ✅ Reseller: panel con KPIs, welcome onboarding, empty states ricos, ETA en proyectos en provisión, post-login a /reseller
- ✅ Admin Comercial: dashboard /admin/dashboard con KPIs accionables, sidebar reorganizado "Marketplace", soporte vía permission compat
- ✅ Admin General: /admin/tenants cross-tenant overview, /admin/audit-log con activity log
- ✅ Data sync: `bewpro:link-reseller`, `bewpro:sync-resellers`, audit consistency, mapping airtable_reseller_record_id, doc data-flow.md
- ✅ Bug fixes: EnsureBrandKitConfigured bypass main site, /home redirect inteligente por rol, "Guía de uso" oculto en bewpro.com, Marketplace footer activado

## Pendientes para Sprint 2

- Bulk import CSV de clientes (Reseller)
- White-label config (Reseller)
- Compra rápida para cliente sin pasar por checkout (Reseller)
- Notificaciones in-app (campana con counter)
- Reseller histórico: comando `bewpro:link-historical-projects` para mapear los 89 proyectos pre-Stripe de CD vía Airtable Clients table
- Templates de respuesta para soporte (Admin Comercial)
- Métricas históricas / charts (signups por día, churn, MRR trend)
- Refactor del módulo Support para usar permisos granulares (`support.view-all/respond/close`) en lugar del monolítico `support.manage`

## Anclajes

- Roles+permisos: `database/seeders/BewProRolesPermissionsSeeder.php`
- Test users: `app/Console/Commands/SeedTestUsers.php`
- Doc roles: `docs/bewpro2.0/operaciones/roles-y-permisos.md`
- Reseller panel: `app/Modules/Clients/Controllers/Reseller/`
- Customers admin: `app/Modules/Clients/Controllers/Admin/CustomersController.php`
- Resellers admin: `app/Modules/Clients/Controllers/Admin/ResellersController.php`
- Profile customer/reseller: `app/Modules/Clients/Controllers/ProfileController.php`
