🧩 Exercícios — Cap 16: Documentando a Arquitetura: Modelo C4, ADRs e arc42
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:
- 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)
- Salve o arquivo como:
Atividade_16_1_SeuNome.md - 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:
- 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)
- Salve o arquivo como:
Atividade_16_2_SeuNome.md - 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:
- Desenhe o nível 1 (Contexto) com
flowchartno estilo C4 (pessoas em azul-escuro, o sistema em azul, externos em cinza). - Desenhe o nível 2 (Contêineres) com
flowchart, com tecnologia e responsabilidade de cada contêiner. - 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)
- Salve o arquivo como:
Atividade_16_3_SeuNome.md - 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:
- 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”).
- Se o status for “Substituído por NNNN”, confira se o ADR NNNN existe na lista de ADRs conhecidos.
- 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)
- Salve o arquivo como:
Atividade_16_4_SeuNome.md - 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']