Appearance
Roadmap de Desarrollo — Portal de Clientes
Módulo: Portal de Clientes Tipo: Hoja de ruta de implementación Estado: En desarrollo — Fase 1 completada
Visión del Roadmap
El Portal de Clientes se desarrolla en 4 fases secuenciales, cada una testeada y verificada antes de iniciar la siguiente. La feature vive en una rama paraguas (feature/portal-backend) aislada del ciclo de releases de develop, para que las fases intermedias no bloqueen otras entregas.
Estado Actual por Fase
| Fase | Nombre | Contenido | Estado | Rama de trabajo |
|---|---|---|---|---|
| 1 | Backend Foundation | Auth JWT + scaffold DDD + migrations | ✅ Completada | feature/portal-backend (squash) |
| 2 | Account & Cupon | Consulta ctacte + cupones | ⏳ Pendiente | feature/portal-backend/phase-2-account |
| 3 | Payment | MercadoPago + PagoTic + webhooks | ⏳ Pendiente | feature/portal-backend/phase-3-payments |
| 4 | Frontend PWA | React SPA en portal-usuarios | ⏳ Pendiente | feature/portal-backend/phase-4-pwa |
Diagrama de Fases
mermaid
gantt
title Portal de Clientes — Roadmap
dateFormat YYYY-MM-DD
axisFormat %b %d
section Fase 1 — Foundation
Auth JWT + Scaffold DDD :done, f1a, 2026-04-01, 2026-04-10
Migrations portal_users/payments :done, f1b, 2026-04-01, 2026-04-10
Tests PHPUnit (45 passing) :done, f1c, 2026-04-08, 2026-04-10
section Fase 2 — Account & Cupon
Sub-módulo Account/ (ctacte) :active, f2a, 2026-04-22, 10d
Sub-módulo Cupon/ : f2b, after f2a, 5d
Tests + verify : f2c, after f2b, 3d
section Fase 3 — Payment
Adapters MercadoPago + PagoTic : f3a, after f2c, 10d
Webhooks + recibo automático : f3b, after f3a, 5d
Tests + verify : f3c, after f3b, 3d
section Fase 4 — Frontend PWA
Setup React + auth flow : f4a, after f3c, 7d
Vistas ctacte + deudas : f4b, after f4a, 7d
Flujo de pago + polling : f4c, after f4b, 7d
Tests Vitest + Playwright : f4d, after f4c, 5d
section Integración Final
Squash merge → develop :milestone, m1, after f4d, 1dEstrategia de Branching
El portal usa un modelo de rama paraguas con squash merge por fase, que garantiza historial limpio en develop y aísla el ciclo de desarrollo del resto del ERP.
mermaid
gitGraph commit id: "develop baseline" branch feature/portal-backend checkout feature/portal-backend commit id: "fase 1: auth JWT, DDD scaffold, migrations" tag: "✅ Completada" commit id: "sync: merge develop" branch feature/portal-backend/phase-2-account checkout feature/portal-backend/phase-2-account commit id: "feat: Account sub-module" commit id: "feat: Cupon sub-module" commit id: "test: coverage + verify" checkout feature/portal-backend merge feature/portal-backend/phase-2-account id: "fase 2: account & cupon (squash)" commit id: "sync: merge develop" branch feature/portal-backend/phase-3-payments checkout feature/portal-backend/phase-3-payments commit id: "feat: MercadoPago adapter" commit id: "feat: PagoTic adapter + webhooks" commit id: "test: coverage + verify" checkout feature/portal-backend merge feature/portal-backend/phase-3-payments id: "fase 3: payments (squash)" commit id: "sync: merge develop" checkout develop merge feature/portal-backend id: "feature/portal completa → develop (squash)"
Reglas del modelo
| Regla | Detalle |
|---|---|
| Una rama paraguas | feature/portal-backend — integration branch, nunca toca develop hasta el final |
| Sub-ramas por fase | feature/portal-backend/phase-N-nombre — nacen de la paraguas, mueren al squash |
| Squash por fase | Cada fase aporta un solo commit a la paraguas — historial intencional, sin ruido WIP |
| Sync periódico con develop | git merge develop --no-ff a la paraguas cada vez que develop avanza |
| Sync = merge, no rebase | Rebase rompería las sub-ramas activas; merge agrega un commit de sync barato y seguro |
| Integración final | Squash merge de la paraguas completa a develop — un único commit de feature |
Detalle por Fase
Fase 1 — Backend Foundation ✅
Objetivo: Establecer la base del módulo DDD Modules/Portal/ con autenticación completa.
Entregables:
- Migrations:
portal_usersyportal_payments(multi-tenant, Phinx) - Scaffold
Modules/Portal/siguiendo patrón DDD deModules/Membresia - Sub-módulo
Auth/: register, login, forgot-password, reset-password, refresh-token PortalJwtMiddleware(RSA-signed, claims{portal_user_id, tenant_id, sucursal_id})- Hash bcrypt + lockout por intentos fallidos + reset por código de email
- Auto-registro validado contra
ordcon(DNI/CUIT debe existir)
Métricas de calidad:
- 45 tests PHPUnit — 0 fallos
- Cobertura ≥ 90% en Service + Middleware
- PHPStan sin errores nuevos, PHPCS PSR-12 limpio
- Code review GGA: ✅ PASSED
Rama: feature/portal-backend (squash de feature/portal-backend-foundation)
Fase 2 — Account & Cupon ⏳
Objetivo: Exponer la cuenta corriente del cliente y sus cupones de pago.
Sub-módulo Account/:
- Endpoint: listado de deudas con indicadores de vencimiento
- Endpoint: saldo actual del cliente
- Integración con
CuponPagoServiceyCuponValidacionServiceexistentes - Filtrado por
sucursal_iddel JWT
Sub-módulo Cupon/:
- Endpoint: listado de cupones por cliente
- Endpoint: descarga de PDF (proxy hacia servicio de
informesen puerto 9999) - Reutilización de
ReciboRelationsService
Criterios de completitud:
- [ ] Endpoints documentados en OpenAPI via
PortalOpenApiService - [ ] Cobertura PHPUnit ≥ 80% en handlers y services nuevos
- [ ] SDD verify: PASS (sin CRITICAL)
- [ ] Squash merge a
feature/portal-backend
Rama: feature/portal-backend/phase-2-account
Fase 3 — Payment ⏳
Objetivo: Habilitar pagos online con creación automática de recibo en ctacte.
Sub-módulo Payment/:
- Adapter
MercadoPagoAdapter(interfacePaymentGatewayAdapterInterface) - Adapter
PagoTicAdapter PaymentGatewayFactory— selección por tenant config- Endpoint: iniciar pago (crea preferencia en gateway, retorna URL de redirección)
- Webhook: recibe notificación de gateway → auto-crea recibo via
ReciboRelationsService - Idempotencia de webhooks (tabla
portal_payments+ status tracking) - Polling endpoint: estado de pago para frontend
Consideraciones críticas:
- Webhooks deben ser idempotentes — el mismo evento no puede crear dos recibos
- Timeout de gateway: manejar estados
pending/approved/rejected/expired - Configuración de gateway por tenant en
ini.sistema(no hardcodeada)
Criterios de completitud:
- [ ] Tests de idempotencia de webhooks
- [ ] Tests de cada adapter con mocks de gateway
- [ ] Cobertura PHPUnit ≥ 80% en services de pago
- [ ] SDD verify: PASS (sin CRITICAL)
- [ ] Squash merge a
feature/portal-backend
Rama: feature/portal-backend/phase-3-payments
Fase 4 — Frontend PWA ⏳
Objetivo: Aplicación React en portal-usuarios lista para deploy Docker por tenant.
Vistas:
/login— formulario con validación Zod (DNI/CUIT + password)/register— registro con confirmación de email + password match/forgot-password+/reset-password— flujo completo por código de email/dashboard— resumen: deudas vencidas + próximas, acceso rápido a pagar/deudas— listado con filtros, indicadores de vencimiento, selección para pagar/pagar— flujo de checkout: selección → confirmación → redirect a gateway/pagar/resultado— polling de estado + mensaje final/cupones— listado + descarga PDF
Stack:
- React 19 + TypeScript + Vite
- TanStack Query (data fetching + polling)
- React Hook Form + Zod (validaciones)
- shadcn/ui (componentes)
- BrandingContext (colores/logo desde
import.meta.env)
Configuración Docker por tenant:
VITE_BACKEND_URL, VITE_TENANT_ID, VITE_SUCURSAL_ID
VITE_APP_NAME, VITE_LOGO_URL, VITE_PRIMARY_COLOR, VITE_THEME_COLORCriterios de completitud:
- [ ] Tests Vitest + Testing Library ≥ 70% cobertura en componentes y hooks
- [ ] Tests Playwright: login, register, forgot-password, flujo de pago, descarga PDF
- [ ] Build Docker sin errores
- [ ] Smoke test en staging con tenant real
Rama: feature/portal-backend/phase-4-pwa (repo portal-usuarios/)
Procedimiento de Sync con develop
Ejecutar cada vez que develop avanza (hotfixes, otras features, releases):
bash
# Detectar qué cambió en develop que puede afectar el portal
git log feature/portal-backend..develop --oneline -- bautista-backend/bootstrap/
git log feature/portal-backend..develop --oneline -- bautista-backend/migrations/
# Sincronizar la paraguas
git checkout feature/portal-backend
git merge develop --no-ff -m "chore/portal: sync con develop"Archivos de mayor riesgo de conflicto:
| Archivo | Riesgo | Motivo |
|---|---|---|
index.php | Alto | DI container + rutas — cada feature agrega entries |
container/shared-definitions.php | Alto | Definiciones compartidas |
migrations (submodule) | Medio | Puntero de commit cambia con cada release |
Integración Final a develop
Cuando las 4 fases estén completas y verificadas:
bash
# Sync final con develop
git checkout feature/portal-backend
git merge develop --no-ff -m "chore/portal: sincronización final con develop"
# Resolver conflictos si los hay
# Squash merge a develop
git checkout develop
git merge --squash feature/portal-backend
git commit -m "feature/portal: portal de clientes completo — auth JWT, account, ctacte, cupones, payments y PWA frontend"
git push origin developEl resultado en develop: un único commit atómico que representa todo el portal.