Pular para conteúdo

Arquitetura — Chronos

Visao Geral

graph TB
    subgraph Frontend
        FE[Next.js<br/>App Router]
    end

    subgraph Backend
        BE[Quarkus<br/>:5050]
    end

    subgraph Banco
        MG[(MongoDB<br/>chronosdb)]
    end

    subgraph Servicos Haus
        OATH[OATH<br/>:5001]
        GUILD[Guild<br/>:5002]
        HERALD[Herald<br/>:5004]
        VAULT[Vault<br/>:5006]
        CK[CoinKeeper<br/>:5005]
        SCROLLS[Scrolls<br/>:5003]
    end

    subgraph Externos
        EVO[Evolution API<br/>WhatsApp]
    end

    FE --> BE
    BE --> MG
    BE --> OATH
    BE --> GUILD
    BE --> HERALD
    BE --> VAULT
    BE --> CK
    BE --> SCROLLS
    HERALD --> EVO

Backend

Camadas

chronos/
├── api/
│   ├── controllers/       # BFF controllers (/bff/*)
│   └── controllers/       # Webhook controllers
├── application/
│   ├── services/          # Business logic
│   └── engines/           # AvailabilityEngine, PromotionEngine
├── domain/
│   └── entities/          # MongoDB entities
└── infrastructure/
    ├── clients/           # REST clients (OATH, Guild, Herald, WhatsApp)
    ├── persistence/       # MongoDB Panache repositories
    ├── scheduler/         # Jobs agendados
    └── security/          # AuthFilter, context service

Endpoints BFF

Controller Path Funcao
BffAuthController /bff/auth Login, signup, refresh, tenant selection
BffAppointmentController /bff/appointments CRUD agendamentos + status
BffServiceController /bff/services CRUD catalogo de servicos
BffProfessionalController /bff/professionals CRUD profissionais
BffCustomerController /bff/customers CRUD clientes + busca
BffScheduleController /bff/schedules Agenda + excecoes
BffLocationController /bff/locations CRUD locais
BffRoomController /bff/rooms CRUD salas + booking
BffPromotionController /bff/promotions CRUD promocoes
BffDashboardController /bff/dashboard Estatisticas + calendario
BffTenantController /bff/tenant Config do tenant
BffPublicController /bff/public Pagina publica de booking
WhatsAppWebhookController /webhooks/whatsapp Recebe msgs do Herald

Entidades Principais (MongoDB)

erDiagram
    Tenant ||--o{ Professional : "tem"
    Tenant ||--o{ ServiceItem : "oferece"
    Tenant ||--o{ Location : "opera em"
    Tenant ||--o{ Customer : "atende"
    Tenant ||--o{ Appointment : "agenda"
    Tenant ||--o{ Schedule : "define"
    Tenant ||--o{ Promotion : "oferece"
    Tenant ||--o{ Room : "tem"
    Professional ||--o{ Schedule : "segue"
    Professional ||--o{ Appointment : "atende"
    Customer ||--o{ Appointment : "agenda"
    Location ||--o{ Room : "contem"
    Room ||--o{ RoomBooking : "reservado"
    Appointment ||--o{ AppointmentItem : "contem"
    Tenant ||--o{ ScheduledMessage : "programa"

Engines

AvailabilityEngine

Calcula slots disponiveis para agendamento:

flowchart TD
    A[Data + Profissional] --> B[Carregar Schedule]
    B --> C{Modo?}
    C -->|INTERVALS| D[Gerar slots com<br/>slotDurationMinutes]
    C -->|FIXED_SLOTS| E[Usar slots fixos]
    D --> F[Remover excecoes]
    E --> F
    F --> G[Remover agendamentos<br/>existentes]
    G --> H[Retornar TimeSlots]

PromotionEngine

Valida e calcula descontos:

flowchart TD
    A[Codigo da promocao] --> B{Promocao existe?}
    B -->|Nao| X[Erro]
    B -->|Sim| C{Periodo valido?}
    C -->|Nao| X
    C -->|Sim| D{Limite de uso?}
    D -->|Excedido| X
    D -->|OK| E{Restricoes de servico?}
    E -->|Nao aplica| X
    E -->|Aplica| F[Calcular desconto]
    F --> G{Cap de desconto?}
    G -->|Sim| H[Aplicar cap]
    G -->|Nao| I[Retornar desconto]
    H --> I

Schedulers

Scheduler Intervalo Funcao
AppointmentReminderScheduler 15 min Envia lembretes email + WhatsApp 24h
ScheduledMessageSenderScheduler 5 min Processa fila de msgs agendadas
StaleAppointmentCleanupScheduler Limpa agendamentos draft/stale

Webhook de WhatsApp

POST /webhooks/whatsapp/incoming (sem auth)
  1. Recebe { ownerRef, phoneFrom, message, timestamp } do Herald
  2. Extrai tenantId do ownerRef ("chronos-{tenantId}")
  3. Normaliza mensagem
  4. Se contem "CONFIRMAR" ou "CONFIRMO":
  5. Busca agendamentos nas proximas 48h com esse telefone
  6. Confirma o mais proximo
  7. Envia ack via WhatsApp

Frontend

Arquitetura

chronos-frontend/
├── src/
│   ├── app/
│   │   ├── (auth)/            # Login, signup
│   │   ├── (dashboard)/       # Area protegida
│   │   │   ├── dashboard/
│   │   │   ├── appointments/
│   │   │   ├── schedule/
│   │   │   ├── services/
│   │   │   ├── professionals/
│   │   │   ├── customers/
│   │   │   ├── locations/
│   │   │   ├── rooms/
│   │   │   ├── promotions/
│   │   │   └── settings/
│   │   ├── (public)/          # Booking publico
│   │   │   └── c/[tenantSlug]/
│   │   └── api/auth/          # NextAuth handler
│   ├── actions/               # Server Actions
│   ├── components/
│   │   ├── dashboard/         # Calendar, upcoming
│   │   └── public/            # BookingWizard
│   ├── lib/
│   │   ├── api.ts            # fetchChronosAPI
│   │   ├── tenant.ts         # Tenant resolution
│   │   └── utils.ts          # Formatters
│   └── auth.ts               # NextAuth config

Autenticacao

  • NextAuth com Credentials Provider
  • Login via OATH externo (provider=OATH, application=chronos)
  • JWT armazenado na sessao
  • Middleware protege rotas /dashboard/*

Booking Wizard (Public)

O componente BookingWizard implementa 5 passos:

  1. Servico — Selecao do servico com preco e duracao
  2. Profissional — Selecao do profissional (condicional)
  3. Data/Hora — Calendario + slots do AvailabilityEngine
  4. Confirmacao — Dados do cliente + codigo promocional
  5. Sucesso — Codigo do agendamento

Server Actions

O frontend usa Next.js Server Actions para comunicacao com o backend:

  • getAppointments(), createDashboardAppointment()
  • getAvailability(), getProfessionalAvailability()
  • createPublicBooking(), validatePublicPromotion()
  • getDashboardSummary(), getDashboardCalendar()

Configuracao

Backend

# MongoDB
quarkus.mongodb.connection-string=${QUARKUS_MONGODB_CONNECTION_STRING}
quarkus.mongodb.database=chronosdb

# Porta
quarkus.http.port=5050

# Servicos
quarkus.rest-client.oath-api.url=http://localhost:5001
quarkus.rest-client.guild-api.url=http://localhost:5002
quarkus.rest-client.herald-api.url=http://localhost:5004
quarkus.rest-client.vault-api.url=http://localhost:5006
quarkus.rest-client.coinkeeper-api.url=http://localhost:5005

Frontend

NEXT_PUBLIC_OATH_URL=http://localhost:5001
NEXT_PUBLIC_CHRONOS_API_URL=http://localhost:5050