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
| Evento | Tuples escritos en authz_outbox |
|---|---|
Account creado | account:X#self@account:X · account:X#active@account:X |
| Email verificado | account:X#email_verified@account:X |
| Account suspendido | account:X#active@account:X (síncrono, no outbox) |
Business creado | business:X#owner@account:Y · business:X#active@business:X |
Branch creada | branch:X#active@account:* · hereda owner via OpenFGA |
Branch suspendida | branch:X#active@account:* (síncrono) |
| Membresía aceptada | branch:X#member@account:Y · branch:X#professional_member@account:Y |
| Membresía terminada | DELETE todos los tuples de esa membresía |
| Permiso delegado | branch:X#booking_manager@account:Z (o el rol delegado) |
Review creada | review:X#author@account:sofia · review:X#professional@account:maria · review:X#located_at@branch:chap |
BranchService propuesto | branch_service:X#branch@branch:Y · branch_service:X#proposer@account:Z |
9. Resumen de decisiones arquitectónicas
| Decisión | Elección | Alternativa descartada | Razón |
|---|---|---|---|
| Autorización | ReBAC + OpenFGA | RBAC custom / Casbin | Herencia y delegación sin deuda técnica |
| Status gates | Tuples positivos + intersección and | Middleware HTTP | Cubre todas las superficies (HTTP, workers, eventos) |
| Suspensión | Síncrono a OpenFGA | Via outbox | Sin lag en eventos de seguridad críticos |
| Overlap de bookings | EXCLUDE USING GIST + tstzrange | UNIQUE(start_at, end_at) | Previene solapamientos parciales a nivel DB |
| Eventos de dominio | domain_events + LISTEN/NOTIFY | Redis Streams / NATS | Sin broker externo, transaccional, migrable |
| Captura parcial | capture(total) + refund(exceso) | partial_capture | Wompi/MercadoPago Colombia no soportan partial capture |
| Disponibilidad | booking.GET /availability | scheduling.GET /availability | Elimina acoplamiento circular booking↔scheduling |
| Índice de búsqueda | Postgres + PostGIS + tsvector | Elasticsearch / Meilisearch | Suficiente para MVP; migrable cuando escale |