Clean architecture
Skill tbc-servicos/dataagile-agent-kit/fluig/skills/clean-architecture
Aplica os princípios de Clean Architecture (livro de Robert Martin, o Uncle Bob) ao desenvolvimento Fluig — regra de dependência e camadas no widget Angular + PO-UI (component → service de aplicação → domínio puro → adapter HTTP/Dataset), datasets server-side e eventos de workflow como adaptadores finos, SOLID em TypeScript com a DI do Angular. Use quando o dev pedir para "organizar o widget em camadas", "desacoplar regra de negócio do componente", "aplicar clean architecture", "aplicar SOLID", "onde colocar essa regra", "dataset está gigante" ou quando o brainstorm/plan/review precisar de critério estrutural de design.From its SKILL.md
npx -y skills add tbc-servicos/dataagile-agent-kit --skill clean-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.3 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it
Clean Architecture aplicada ao Fluig
Destilação prática dos princípios de Clean Architecture para os dois mundos do Fluig: o widget Angular + PO-UI (front) e o lado plataforma (datasets, eventos de workflow e formulários). Objetivo: regra de negócio que sobrevive a troca de tela, de endpoint e de versão — e é testável com Jasmine/Karma sem HTTP nem plataforma no ar.
Skills irmãs:
/fluig:ddd(modelagem — o que construir), esta (estrutura — como organizar). Se o time também usa o plugin protheus, os equivalentes são/protheus:clean-architecturee/protheus:ddd— mesmos princípios, outro stack.
Consulta MCP (antes de gerar código)
- Versão do Angular/PO-UI: nunca fixe em código novo. Leia o
package.jsondo projeto; para projeto novo, use a versão estável atual do Angular (o PO-UI acompanha o major do Angular). Confirme via MCP — não confie na memória do modelo para versão. - MCP do Angular CLI (
npx -y @angular/cli mcp):get_best_practicesesearch_documentationantes de decidir padrão (standalone, signals, control flow);list_projectspara entender o workspace;modernize/onpush_zoneless_migrationem código legado. - MCP do PO-UI (
@po-ui/mcp, já configurado no plugin):list_components+get_component_docsantes de escrever qualquer componente visual;get_guidepara temas (acessibilidade, theming). - MCP tbc-knowledge:
searchFluigPatterns({ category: "conventions" })para as convenções do plugin (estrutura de pastas, namingwg_/ds_/wf_).
A Regra de Dependência
Dependências apontam para dentro: apresentação → aplicação → domínio ← infraestrutura. A regra de negócio não conhece componente, template, HttpClient nem DatasetFactory.
[ Component/Page PO-UI · template · evento de form · evento de workflow ] ← entrada/saída
↓ chama
[ Service de aplicação (caso de uso): orquestra, coordena estado ] ← aplicação
↓ chama ↓ chama (via interface)
[ Domínio: classes/funções TS puras ] [ Adapter: HttpClient, DatasetFactory, hAPI ]
Teste rápido de violação: se o mesmo arquivo tem template/HTTP E um cálculo/decisão de
negócio, ele está em duas camadas — dividir. Vale para .component.ts e para ds_*.js.
Mapa de camadas → artefatos Fluig
No widget (Angular + PO-UI)
| Camada | Artefato | Regra |
|---|---|---|
| Domínio | domain/ — classes e funções TS puras (cálculo, validação, decisão) | Zero import de @angular/* ou @po-ui/*. Testável com Jasmine puro, sem TestBed |
| Casos de uso | services/ de aplicação (aprovacao.service.ts) | Orquestra: chama domínio + repositórios, expõe estado (signal/observable) para a página |
| Adaptadores de dados | services/api/ (pedido-api.service.ts) | Só HTTP/DatasetFactory: monta request, traduz response em modelo do domínio. Nenhum if de negócio |
| Apresentação | components/, pages/ | Dumb por padrão: recebe input, emite output, delega ao service. Lógica no template = só exibição |
- A DI do Angular já entrega o DIP: o caso de uso recebe o adapter pelo construtor
(
inject()); para testar, provê-se um dublê noTestBed— semHttpTestingControllerpara testar regra de negócio. - Componente com
HttpClientinjetado = violação direta (pula duas camadas).
No lado plataforma (server-side JS)
| Camada | Artefato | Regra |
|---|---|---|
| Adaptador | createDataset() / evento (afterStateEntry, validateForm) | Fino: extrai entrada (constraints, hAPI, campos), chama as funções de regra, devolve/grava. try/catch + log aqui |
| Domínio | Funções puras no mesmo arquivo (Rhino não tem import) | Recebem dados, devolvem resultado. Sem DatasetFactory, sem hAPI, sem log |
| Infra | Funções buscarX()/gravarY() que encapsulam DatasetFactory/SQL/REST | Todo acesso a dado externo vive aqui; a URL/serviço do Protheus aparece num único lugar |
O antipadrão nº 1 do Fluig é o god-dataset: createDataset() com 300 linhas fazendo
constraint parsing + REST + regra + montagem de dataset. A refatoração guiada está em
references/plataforma-datasets-eventos.md.
SOLID em TypeScript/Angular — resumo operacional
- SRP — um service = um assunto; componente > ~200 linhas ou service que mistura HTTP + regra + formatação → dividir.
- OCP — variação por estratégia injetada (token de DI + implementações), não
switchde tipo replicado. - LSP — implementações de uma interface honram o contrato (sem
throw "não suportado"). - ISP — interfaces por papel (
ConsultaPedidos,AprovaPedidos), não umApiServicegordo. - DIP — casos de uso dependem de abstração (
abstract class/token); Angular DI injeta a concreta. Detalhes e exemplos:references/camadas-widget-angular.md.
Quando aplicar (pragmatismo)
| Tamanho | Estrutura mínima |
|---|---|
| Dataset de consulta simples, evento trivial | Só a regra de sempre: função extraída se houver decisão de negócio |
| Widget pequeno (1 página, 1 fonte de dados) | api.service separado do service de aplicação; domínio se houver cálculo |
| Widget grande / processo com regra rica | Camadas completas + domain/ com specs próprios |
Não crie domain/ para um widget que só lista um dataset — sobre-engenharia também é dívida.
Fluxo de uso
- Design (
/fluig:brainstorm//fluig:plan): por caso de uso, defina os artefatos por camada antes de codar; marque o que é regra pura (testável sem TestBed/plataforma). - Implementação (
/fluig:widget,/fluig:dataset,/fluig:workflow,/fluig:implement): siga os esqueletos das references. - Review (
/fluig:review): checklist estrutural emreferences/plataforma-datasets-eventos.mdereferences/camadas-widget-angular.md. - Teste (
/fluig:test): a recompensa — domínio com Jasmine puro (rápido, sem TestBed); adapter comHttpTestingController; componente só com teste de interação.
Regras inegociáveis
- Componente/página nunca injeta
HttpClientnem chamaDatasetFactory— sempre via service. - Regra de negócio nunca importa
@angular/*,@po-ui/*, nem tocahAPI/DatasetFactory. - Evento de workflow/form delega para função nomeada — a lógica nunca mora inline no evento.
- Integração REST Protheus: URL/rota/parse em um único adapter por recurso.
- Toda regra pura nasce com spec Jasmine (o
/fluig:testcobra cobertura ≥ 70%). - try/catch + log nos adaptadores server-side (regra do plugin) — mas o catch não engole: loga e propaga/devolve erro estruturado.
What ships with it: 2 files
10.6 KB alongside SKILL.md