Skip to content

BeautyHub — Arquitectura del Sistema

Diagramas de referencia rápida. La especificación detallada de cada dominio vive en docs/domains/.


1. Vista general del sistema


2. Dependencias entre dominios

Las flechas sólidas son llamadas síncronas (in-process). Las flechas punteadas son eventos asíncronos via domain_events.


3. Modelo de datos — entidades clave


4. Modelo de autorización (ReBAC · OpenFGA)

Tipos y relaciones principales

Flujo de autorización por request


5. Ciclo de vida del booking


6. Ciclo de vida del pago


7. Flujo de eventos (outbox pattern)


8. Estructura del dominio de autorización — tuples por evento

EventoTuples escritos en authz_outbox
Account creadoaccount:X#self@account:X · account:X#active@account:X
Email verificadoaccount:X#email_verified@account:X
Account suspendidoDELETE account:X#active@account:X (síncrono, no outbox)
Business creadobusiness:X#owner@account:Y · business:X#active@business:X
Branch creadabranch:X#active@account:* · hereda owner via OpenFGA
Branch suspendidaDELETE branch:X#active@account:* (síncrono)
Membresía aceptadabranch:X#member@account:Y · branch:X#professional_member@account:Y
Membresía terminadaDELETE todos los tuples de esa membresía
Permiso delegadobranch:X#booking_manager@account:Z (o el rol delegado)
Review creadareview:X#author@account:sofia · review:X#professional@account:maria · review:X#located_at@branch:chap
BranchService propuestobranch_service:X#branch@branch:Y · branch_service:X#proposer@account:Z

9. Resumen de decisiones arquitectónicas

DecisiónElecciónAlternativa descartadaRazón
AutorizaciónReBAC + OpenFGARBAC custom / CasbinHerencia y delegación sin deuda técnica
Status gatesTuples positivos + intersección andMiddleware HTTPCubre todas las superficies (HTTP, workers, eventos)
SuspensiónSíncrono a OpenFGAVia outboxSin lag en eventos de seguridad críticos
Overlap de bookingsEXCLUDE USING GIST + tstzrangeUNIQUE(start_at, end_at)Previene solapamientos parciales a nivel DB
Eventos de dominiodomain_events + LISTEN/NOTIFYRedis Streams / NATSSin broker externo, transaccional, migrable
Captura parcialcapture(total) + refund(exceso)partial_captureWompi/MercadoPago Colombia no soportan partial capture
Disponibilidadbooking.GET /availabilityscheduling.GET /availabilityElimina acoplamiento circular booking↔scheduling
Índice de búsquedaPostgres + PostGIS + tsvectorElasticsearch / MeilisearchSuficiente para MVP; migrable cuando escale

Documentación interna — BeautyHub