Skip to content

Backend - Portal de Clientes

Modulo DDD moderno bajo Modules/Portal/ que extiende Sistema Bautista con funcionalidad de autoservicio para clientes finales. Endpoints bajo el namespace /portal/*.

Estado: Planificado

Arquitectura

Modulo DDD: El portal se implementa como un modulo moderno dentro de Modules/Portal/, siguiendo la arquitectura DDD que ya usan los modulos CRM y Membresia.

  • Estructura DDD con sub-modulos independientes
  • Reutiliza infraestructura existente (PostgreSQL, Slim Framework)
  • Comparte servicios del ERP donde corresponda (CuponPagoService, ReciboRelationsService)
  • Autenticacion propia via JWT con password
  • Namespace aislado: Modules\Portal\

Sub-modulos

El modulo Portal se divide en 4 sub-modulos DDD:

Sub-moduloResponsabilidad
Auth/Registro, login, recuperacion de password, JWT
Account/Consulta de cuenta corriente, deudas, resumen
Payment/Pagos online (gateway), webhooks, acreditacion automatica
Cupon/Generacion y consulta de cupones (delega a servicios existentes)
Modules/Portal/
  Auth/
    Controller/PortalAuthController.php
    Service/PortalAuthService.php
    Middleware/PortalJwtMiddleware.php
  Account/
    Controller/PortalCtaCteController.php
    Service/PortalCtaCteService.php
  Payment/
    Controller/PortalPagosController.php
    Service/PaymentGatewayService.php
    Adapter/MercadoPagoAdapter.php
    Adapter/PagoTicAdapter.php
    Factory/PaymentGatewayFactory.php
  Cupon/
    Controller/PortalCuponesController.php
  Routes/portal-routes.php
  portal-module.php

Autenticacion

JWT con password (no passwordless):

  • El cliente se registra con DNI/CUIT que debe coincidir con un ordcon existente
  • Se almacena password_hash en portal_users
  • Login genera JWT con payload: { portal_user_id, tenant_id, sucursal_id }
  • El frontend envia tenant_id y sucursal_id en el login (valores de .env)
  • Recuperacion de password via codigo enviado por email

Resolucion de Tenant

NO se usa resolucion por dominio. Cada tenant tiene su propio deploy Docker con variables de entorno.

Flujo de resolucion:

  1. Frontend envia tenant_id + sucursal_id en el login
  2. Backend valida que la sucursal pertenece al tenant
  3. JWT incluye tenant_id y sucursal_id
  4. En cada request autenticado:
    • tenant_id del JWT resuelve la base de datos via ini.sistema
    • sucursal_id del JWT resuelve el schema (sucXXXX, o public si ordcon es a nivel empresa)
  5. Backend valida que la sucursal pertenece al tenant

Tablas

TablaUbicacionDescripcion
portal_usersMismo schema que ordcon (dinamico via ini.sistema)Usuarios del portal con password_hash
portal_paymentsMismo schema que ordconPagos online pendientes, aprobados, rechazados

NO existe tabla portal_cupones. El sub-modulo Cupon delega a los servicios existentes CuponPagoService y CuponValidacionService del modulo CtaCte.

Documentacion

API Endpoints

Documentacion completa de los endpoints REST del portal.

Services

Servicios de logica de negocio del portal.

Seguridad

  • Autenticacion JWT con HS256, expiracion configurable
  • Refresh token para renovar sesion sin re-login
  • Rate limiting: 5 intentos login/min por IP, 100 requests/min por usuario
  • Bloqueo automatico tras 5 intentos fallidos de login (15 min)
  • Validacion de pertenencia: portal_user vinculado a ordcon del tenant
  • Webhook: validacion de firma especifica por gateway, idempotencia