Guia Extra: Engenharia de Software e Modelagem UML • Bloco 4: Comportamento e Arquitetura • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 16.1 — Qual Nível do C4?

Contexto: Perguntas da equipe.

Requisitos de Execução:

  1. Indique o nível do C4: (a) o app mobile fala direto com o banco ou passa pela API? (b) quais sistemas externos o nosso sistema usa? (c) dentro da API, onde ficam as regras de multa? (d) quais atributos tem a classe Emprestimo?

Resultado Esperado

Quatro respostas com o nível.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_16_1_SeuNome.md
  2. Envie na tarefa: Atividade Cap 16 - Documentando a Arquitetura: Modelo C4, ADRs e arc42
🔑 Gabarito de Código & Solução Comentada
  • (a) Nível 2 — Contêineres: relações entre app, API e banco.
  • (b) Nível 1 — Contexto: o sistema e seus vizinhos.
  • (c) Nível 3 — Componentes: blocos dentro do contêiner API.
  • (d) Nível 4 — Código: diagrama de classes.

🎯 Nível 2: Prática

Problema 16.2 — Escrever um ADR

Contexto: O time do SGB discutiu se o portal seria renderizado no servidor (templates) ou uma SPA. Pesou: as bibliotecárias usam computadores antigos; o time conhece Python e pouco JavaScript; os leitores pedem uso no celular.

Requisitos de Execução:

  1. Escreva o ADR 0006 com status, contexto (incluindo as alternativas), decisão e consequências (pelo menos uma negativa).

Resultado Esperado

Um ADR completo no formato de Nygard.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_16_2_SeuNome.md
  2. Envie na tarefa: Atividade Cap 16 - Documentando a Arquitetura: Modelo C4, ADRs e arc42
🔑 Gabarito de Código & Solução Comentada
# 0006 — Renderizar o portal no servidor com templates

**Status:** Aceito (2026-04-02)

## Contexto
Alternativas: (a) SPA em TypeScript; (b) páginas renderizadas no servidor
(templates Jinja2) com pequenos trechos interativos. Os computadores do balcão
são antigos; o time domina Python e tem pouca experiência em JavaScript; os
leitores usam o celular.

## Decisão
Vamos renderizar as páginas no servidor, com layout responsivo e JavaScript
apenas onde necessário (busca com sugestões).

## Consequências
+ Páginas leves nos computadores antigos e bom funcionamento no celular.
+ O time trabalha na linguagem que conhece.
- Interações muito ricas (arrastar e soltar) ficam mais trabalhosas.
- Se no futuro houver app nativo, a API JSON precisará ser criada à parte.

🎯 Nível 3: Integração

Problema 16.3 — C4 de um Sistema de Clínica

Contexto: Uma clínica tem agendamento online (web e app), prontuário eletrônico usado pelos médicos, integração com convênios (sistema externo) e envio de lembretes por WhatsApp (serviço externo).

Requisitos de Execução:

  1. Desenhe o nível 1 (Contexto) com flowchart no estilo C4 (pessoas em azul-escuro, o sistema em azul, externos em cinza).
  2. Desenhe o nível 2 (Contêineres) com flowchart, com tecnologia e responsabilidade de cada contêiner.
  3. Escreva um cenário de qualidade para disponibilidade do agendamento.

Resultado Esperado

Dois diagramas e um cenário no formato fonte → estímulo → ambiente → artefato → resposta → medida.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_16_3_SeuNome.md
  2. Envie na tarefa: Atividade Cap 16 - Documentando a Arquitetura: Modelo C4, ADRs e arc42
🔑 Gabarito de Código & Solução Comentada
flowchart TB
    P["🧑 Paciente
[Pessoa]
agenda consultas"]
    M["🩺 Médico
[Pessoa]
atende e registra prontuário"]
    C["Sistema da Clínica
[Sistema]
agenda e prontuário"]
    V["Sistema do convênio
[Sistema externo]
autoriza procedimentos"]
    W["API do WhatsApp
[Sistema externo]
envia lembretes"]
    P -- "agenda (HTTPS)" --> C
    M -- "registra atendimento (HTTPS)" --> C
    C -- "pede autorização (HTTPS)" --> V
    C -- "envia lembrete (HTTPS)" --> W
    style P fill:#08427b,stroke:#052e56,color:#ffffff
    style M fill:#08427b,stroke:#052e56,color:#ffffff
    style C fill:#1168bd,stroke:#0b4884,color:#ffffff
    style V fill:#8a8a8a,stroke:#5e5e5e,color:#ffffff
    style W fill:#8a8a8a,stroke:#5e5e5e,color:#ffffff
flowchart LR
    P["Paciente"] --> WEB["Site e app\n[React Native / Web]\nagendamento"]
    M["Médico"] --> PR["Prontuário\n[Web, Java]\nregistro clínico"]
    WEB --> API["API\n[Java, Spring]\nagenda, pacientes, convênios"]
    PR --> API
    API --> DB[("Banco\n[PostgreSQL]")]
    API --> CONV["Convênio\n[externo]"]
    API --> WPP["WhatsApp\n[externo]"]

Cenário: pacientes (fonte) tentam agendar (estímulo) durante uma falha de um servidor da API (ambiente) no contêiner API (artefato); o sistema continua aceitando agendamentos pelas outras instâncias (resposta) com disponibilidade mensal ≥ 99,5% (medida).


🎯 Nível 4: Desafio

Problema 16.4 — Validador de ADRs

Contexto: A equipe quer barrar no CI pull requests com ADRs malformados.

Requisitos de Execução:

  1. Escreva uma função que receba o texto de um ADR e verifique: título começando com número de 4 dígitos; seções Contexto, Decisão e Consequências; status válido (Proposto, Aceito, Rejeitado, Obsoleto ou “Substituído por NNNN”).
  2. Se o status for “Substituído por NNNN”, confira se o ADR NNNN existe na lista de ADRs conhecidos.
  3. Teste com um ADR válido e um inválido.

Resultado Esperado

“ok” para o válido e a lista de problemas para o inválido.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_16_4_SeuNome.md
  2. Envie na tarefa: Atividade Cap 16 - Documentando a Arquitetura: Modelo C4, ADRs e arc42
🔑 Gabarito de Código & Solução Comentada
# validar_adr.py
import re

CONHECIDOS = {"0001", "0002", "0003", "0004", "0005"}
STATUS = re.compile(r"\*\*Status:\*\* (Proposto|Aceito|Rejeitado|Obsoleto|Substituído por (\d{4}))")

def validar(texto: str) -> list[str]:
    problemas = []
    if not re.match(r"# \d{4} — ", texto):
        problemas.append("título deve começar com '# NNNN — '")
    for secao in ("Contexto", "Decisão", "Consequências"):
        if f"## {secao}" not in texto:
            problemas.append(f"falta a seção {secao}")
    m = STATUS.search(texto)
    if not m:
        problemas.append("status ausente ou inválido")
    elif m.group(2) and m.group(2) not in CONHECIDOS:
        problemas.append(f"substituído por ADR inexistente: {m.group(2)}")
    return problemas

BOM = """# 0001 — Usar arquitetura em camadas
**Status:** Substituído por 0005
## Contexto
...
## Decisão
...
## Consequências
..."""

RUIM = """# Usar Redis
**Status:** Substituído por 0099
## Contexto
..."""

print("BOM :", validar(BOM) or "ok")
print("RUIM:", validar(RUIM))

Saída:

BOM : ok
RUIM: ["título deve começar com '# NNNN — '", 'falta a seção Decisão', 'falta a seção Consequências', 'substituído por ADR inexistente: 0099']