Arquitetura

Estado atual (v4.1.0) e evolução planejada até v9.x

Arquitetura atual — v7.6.0 (Hexagonal)

  Cliente HTTP
    │  POST /api/transcriptions
    │  multipart/form-data { file: audio }
    ▼
  TranscriptionController  (adapter/in/http)
    │  MultipartFile → TranscribeCommand(bytes, filename, contentType, size)
    ▼
  TranscribeAudioPort  (interface — domain/port/in)
    │
    ▼
  TranscribeAudioUseCase  (application)
    │  1. validate(contentType) → 400 se inválido
    │  2. sha256(bytes)
    │  3. TranscriptionCachePort.get(hash)
    │        HIT  → retorna em ~15ms com cached=true
    │        MISS → continua
    │  4. SpeechToTextPort.transcribe(bytes)
    │  5. TranscriptionCachePort.put(hash, result)
    │  6. TranscriptionEventPort.publish(Transcription)
    │  7. TranscriptionMetrics
    │
    ├── SpeechToTextPort → WhisperAdapter  (infrastructure/speechtotext/whisper)
    │     @Retry + @CircuitBreaker
    │     ByteArrayResource → POST speaches:8000/v1/audio/transcriptions
    │
    ├── TranscriptionCachePort → RedisTranscriptionCacheAdapter  (infrastructure/cache)
    │     SHA-256 → "transcription:{hash}" → Redis (TTL 24h)
    │
    └── TranscriptionEventPort → NoOpTranscriptionEventAdapter  (infrastructure/messaging)
          log.debug — substituído por RabbitMQ na Fase 8

  shared/
    ├── config/  MdcLoggingFilter · OpenApiConfig · WebClientConfig · RedisConfig
    └── exception/  GlobalExceptionHandler (ProblemDetail RFC 9457)

  Infraestrutura (Docker Compose)
    ├── speaches    :8000  — Whisper
    ├── redis       :6379  — Cache SHA-256 (TTL 24h)
    ├── prometheus  :9090  — Métricas
    ├── grafana     :3000  — Dashboards
    ├── zipkin      :9411  — Tracing
    └── sonarqube   :9000  — Análise local (apenas dev)

Arquitetura alvo — v9.x planejado

  [ HTTP ]       [ RabbitMQ: requests ]        ← Adapters de ENTRADA
       │                   │
       ▼                   ▼
  ┌─────────────────────────────────────────────────────────────────┐
  │  TranscribeAudioUseCase (APPLICATION)                           │
  │    1. SHA-256 dos bytes                                         │
  │    2. TranscriptionCachePort.get() → HIT retorna                │
  │    3. SpeechToTextPort.transcribe() → Whisper (ou outro)        │
  │    4. TranscriptionCachePort.put()                              │
  │    5. TranscriptionEventPort.publish()                          │
  └─────────────────────────────────────────────────────────────────┘
       │                   │                   │
       ▼                   ▼                   ▼
  WhisperAdapter   RedisCache          RabbitMQ:events   ← Adapters de SAÍDA
  (ou OpenAI...)   Adapter             (TranscriptionCompletedEvent)
                                              │
                              ┌───────────────┼───────────────┐
                              ▼               ▼               ▼
                         E-mail svc      SMS svc       WhatsApp svc
                         (Spring Mail)   (Twilio...)   (Meta API...)

O domínio não conhece Redis, Whisper, RabbitMQ, Twilio ou Spring. Trocar qualquer tecnologia = criar um novo adapter. Domínio intocado.

Pipeline CI/CD Fase 5

  Push (qualquer branch) / PR para main
    │
    ├── ci.yml ──────────────────────────────────────────────────────
    │     JDK 25 + cache Gradle
    │     ./gradlew clean build  (testes + Jacoco 70%)
    │     ./gradlew sonar        (SonarCloud Quality Gate)
    │     Upload Codecov         (cobertura visual no PR)
    │
    └── docker.yml ──────────────────────────────────────────────────
          Docker Buildx + BuildKit + cache GHA
          metadata-action → tags: sha / branch / latest (main) / pr-N
          Push apenas se não for PR
          Trivy scan (CRITICAL+HIGH)

  Push tag v*
    │
    ├── release.yml ─────────────────────────────────────────────────
    │     Re-tag imagem latest → vX.Y.Z
    │     GitHub Release com release notes automáticas + instruções Docker
    │
    └── docs.yml ────────────────────────────────────────────────────
          pandoc + xelatex → readme_pdf.md → .pdf
          Artifact 30 dias + anexado ao release

Secrets necessários

SecretDescrição
DOCKERHUB_USERNAMEerichiroshi
DOCKERHUB_TOKENToken Docker Hub (não senha)
SONAR_TOKENToken SonarCloud
CODECOV_TOKENToken Codecov

Estrutura de pacotes — alvo v7.x planejado

  com.example.diospeechai/
  │
  ├── shared/                        # Transversal
  │   ├── config/                    # WebClient, Redis, MDC, OpenAPI
  │   └── exception/                 # GlobalExceptionHandler
  │
  ├── auth/
  │   ├── domain/port/               # TokenServicePort (interface)
  │   ├── application/               # GenerateTokenUseCase
  │   ├── infrastructure/jwt/        # JwtTokenAdapter, JwtProperties
  │   └── adapter/in/http/           # AuthController, DTOs, documentação
  │
  └── transcription/
      ├── domain/
      │   ├── model/                 # Transcription (entidade)
      │   └── port/
      │       ├── in/                # TranscribeAudioPort
      │       └── out/               # SpeechToTextPort
      │                              # TranscriptionCachePort
      │                              # TranscriptionEventPort
      ├── application/               # TranscribeAudioUseCase
      │   ├── command/               # TranscribeCommand
      │   └── result/                # TranscriptionResult
      ├── infrastructure/
      │   ├── speechtotext/whisper/  # WhisperAdapter
      │   ├── cache/                 # RedisTranscriptionCacheAdapter
      │   └── messaging/rabbit/      # RabbitConfig, RabbitEventAdapter
      ├── adapter/
      │   ├── in/http/               # TranscriptionController
      │   ├── in/messaging/          # TranscriptionRequestConsumer
      │   └── out/messaging/event/   # TranscriptionCompletedEvent
      ├── metrics/                   # TranscriptionMetrics
      └── exception/                 # TranscriptionException, ServiceUnavailable

Evolução por fase

FaseVersõesO que muda
Fase 1 v1.0.0API REST, Docker Compose, ProblemDetail RFC 9457
Fase 2 v2.1–v2.7Prometheus, Grafana, Zipkin/OTel, Redis, Cache SHA-256, Logs JSON
Fase 3 v3.1–v3.5CircuitBreaker, Retry, JWT (temporário), Testcontainers
Fase 4 v4.1.0SpringDoc OpenAPI 3.1, Swagger UI, interfaces de documentação
Fase 5 v5.1.0–v5.3.0Jacoco 70%, SonarCloud, ci.yml, docker.yml, release.yml, docs.yml. JWT removido. SonarQube local no docker-compose.dev.yml.
Fase 6 pendentev6.xBean Validation — pendente. Retorna quando houver DTOs de entrada com campos validáveis (ex: JSON body). Sem previsão de versão.
Fase 7 v7.1.0–v7.6.0Arquitetura hexagonal completa. TranscribeAudioUseCase, WhisperAdapter, RedisTranscriptionCacheAdapter, pacotes shared/. contentType no TranscribeCommand. ByteArrayResource no WhisperAdapter.
Fase 8 v8.1–v8.3RabbitMQ: produtor de eventos + consumer de pedidos + DLQ + Testcontainers
Fase 9 v9.1–v9.3Notificações: e-mail (Spring Mail), SMS, WhatsApp via consumers RabbitMQ