CommunityPesquisa e Análise de Dadosgithub.com

APS-Framework/aps-template

Template de projeto APS Framework: agentes, skills, comandos e scripts para criar Azure Functions .NET e ASP.NET Core Web Apps com pacotes APS.

O que é aps-template?

Este skill guia o orquestrador (agente de IA) no processo de criação de novas funcionalidades em projetos .NET que utilizam o APS Framework, como Azure Functions e ASP.NET Core Web Apps. Ele é projetado para cenários de 'criação pura', onde não há código pré-existente para modificar, ao contrário de skills de refatoração como `refactor-protocol`. O skill orquestra uma série de fases de análise obrigatórias, incluindo validação da estrutura do projeto, coleta de requisitos do usuário, análise de reutilização de serviços e métodos existentes, análise de necessidades de configuração e avaliação de impacto na API pública. Com base nessa análise, ele gera um plano detalhado de criação e solicita aprovação explícita do usuário antes de invocar workers especializados para gerar o código (interfaces, implementações, endpoints, testes). O skill também exige a execução de testes de regressão para garantir que componentes existentes não sejam quebrados, e só finaliza a funcionalidade após verificação bem-sucedida dos testes.

Funciona com~Claude Code~Codex CLI~Cursor✓OpenCode
npx skills add APS-Framework/aps-template

Installed? Explore more Pesquisa e Análise de Dados skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que eu faço

Eu guio o orquestrador para criar novas funcionalidades (não modificar as existentes) com análise prévia de reutilização, configuração e compatibilidade. Ao contrário dos refactors, aqui não há código prévio a preservar: o design começa a partir dos requisitos do usuário.

Quando usar este skill (em vez de refactor-protocol):

  • O usuário pede um endpoint, serviço, job, handler, evento ou configuração que NÃO existe
  • A tarefa é criação pura, não modificação de comportamento existente
  • O resultado adiciona arquivos ao repositório, não altera a assinatura dos existentes

Quando NÃO usar este skill (usar refactor-protocol em vez disso):

  • Modificar a assinatura de um serviço existente
  • Alterar o comportamento de um endpoint que já existe
  • Renomear, extrair ou mover código

FASE 0 — Validação de estrutura (sempre a primeira)

  1. Carregar o skill project-structure e executar a validação completa
  2. Detectar o tipo de host: FUNCTIONS | WEBAPP | NUGET_LIBRARY
  3. Agir conforme o resultado:
StatusAção
HARD_BLOCKParar. Informar o usuário.
NUGET_LIBRARYCriar um endpoint HTTP é inesperado. Perguntar: "Deseja adicionar uma operação pública à biblioteca ou realmente há um host que não detectei?"
PREGUNTAResolver as perguntas antes de continuar
OK / WARNINGContinuar para a FASE 1

FASE 1 — Coleta de requisitos

O orquestrador infere o que puder da descrição do usuário ($ARGUMENTS) e só pergunta o que não estiver claro. Não fazer perguntas cuja resposta já esteja na descrição.

1.1 Nome, propósito e tipo da funcionalidade

  • Endpoint HTTP (Function/Controller): [VERBO] /rota — descrição
  • Serviço de domínio: nome do serviço e responsabilidade
  • Job/Event handler: trigger + ação
  • Opção de configuração: nome da opção e seu propósito

1.2 Classificação READ vs MUTATION

Determinar se a funcionalidade muda estado ou é somente leitura. Isso afeta:

  • Onde os DTOs de response vão
  • Se é necessário transação / idempotência
  • Quais testes são necessários
TipoCaracterísticasImplicação
READ-ONLYGET, retorna dados existentes, não escreveDTOs efêmeros, testes mínimos
MUTATIONPOST/PUT/DELETE, escreve ou muda estadoRequer testes de sucesso + erro

1.3 Coleta de input/output esperado

  • Request: estrutura do body ou query params
  • Response: estrutura do body de resposta, status codes
  • Erros: quais erros devem ser mapeados para quais status codes

FASE 1.5 — Análise de reutilização (CRÍTICA, não pular)

Objetivo: detectar se a funcionalidade já existe parcial ou totalmente antes de criar qualquer coisa.

Passos

  1. Buscar serviços existentes em *.Impl/ com @explore usando o domínio da funcionalidade
  2. Buscar métodos candidatos que cubram 80%+ do comportamento necessário:
    • Existe um método que já retorna o dado necessário com um filtro trivial?
    • Existe um método que poderia ser sobrecarregado para adicionar o caso?
  3. Buscar endpoints similares em *.API/ com a mesma forma de request/response

Árvore de decisão

Existe método que cobre 100% do caso?
├── SIM → NÃO criar método novo. Criar apenas:
│   · Endpoint (Function/Controller) em *.API/
│   · DTO Request/Response exclusivo em *.API/
│   · Teste do shape do response
│
Existe método quase-ideal (filtro, paginação, ordenação)?
├── SIM → considerar:
│   ├── Adicionar parâmetro opcional ao método existente (com valor padrão)
│   ├── Criar overload com assinatura mais específica
│   └── Criar método de extensão que envolva o existente
└── NÃO → continuar com criação de método novo

Existe serviço relacionado mas diferente (ex.: responsabilidade similar)?
├── SIM → perguntar ao usuário: "Estendo o [CSXxxService] ou crio um novo [CSYyyService]?"
└── NÃO → criar serviço novo

Saída esperada desta fase

Uma destas três decisões, apresentada ao usuário antes de continuar:

  1. Reutilização pura: a funcionalidade se implementa como wrapper de um método existente
  2. Extensão: adicionar overload/método a um serviço existente
  3. Criação nova: serviço e métodos novos (justificar por que não se pode reutilizar)

FASE 1.6 — Análise de configuração (NOVA)

Objetivo: detectar se a funcionalidade requer parâmetros configuráveis e, se sim, onde defini-los.

Perguntas-chave

  1. A funcionalidade tem valores padrão razoáveis sem configuração externa?
  2. Existem limiares, paginação, timeouts, ou flags que deveriam ser configuráveis por ambiente?
  3. Conecta-se a um sistema externo com URL/chave/secret?
  4. Precisa de feature flags para rollout gradual?

Árvore de decisão

A funcionalidade requer configuração?
├── NÃO → não criar IXxxOptions, não tocar em AddCustomConfiguration
└── SIM → continuar

Que tipo de configuração?
├── Connection string ou segredo
│   └── Usar IConfiguration com nome em appsettings.json (gerenciado por AddCustomConfiguration)
├── Valor simples (limiar, timeout, flag)
│   └── Criar IXxxOptions em *.Impl/ (interface) + adicionar a AddCustomConfiguration<T>("chave")
└── Lista de valores (allowed origins, mappings)
    └── Criar IXxxOptions com propriedade do tipo IEnumerable<T>

Convenção do projeto

O projeto usa AddCustomConfiguration<IXxxOptions>("config-section") em IoCExtensions.cs (linhas 43-45 do projeto atual). As interfaces ficam em *.Impl/ e são referenciadas a partir de *.Impl/Services/.

Saída esperada

Se a funcionalidade requer configuração, apresentar ao usuário:

  • Nome da interface (ex.: IPendingPaymentOptions)
  • Propriedades com seus tipos e valores padrão
  • Seção em appsettings.json (ex.: "RAMBLA.PendingPayment")
  • Modificação de IoCExtensions.AddCSLevelBooking()

Se NÃO requer, indicar explicitamente no plano.


FASE 1.7 — Análise de impacto na API pública

Objetivo: evitar quebrar consumidores existentes.

Se a funcionalidade reutiliza um método existente

  • O método se mantém com a mesma assinatura? → sem impacto
  • Adiciona-se um parâmetro opcional? → verificar se nenhum call site quebra
  • Adiciona-se um overload? → verificar se o compilador resolve sem ambiguidade
  • Renomeia-se? → buscar todos os call sites com grep e migrar

Se a funcionalidade adiciona um serviço novo

  • O serviço é registrado na DI? → assegurar registro em IoCExtensions
  • Algum serviço existente tem dependência circular potencial? → verificar

Se a funcionalidade adiciona um endpoint novo

  • A rota colide com outra rota existente? → verificar
  • O método HTTP é coerente com REST? (GET para leitura, POST para mutação)

FASE 1.8 — PREFLIGHT de testes de regressão (obrigatório)

Objetivo: antes de gerar código novo ou modificar existente, verificar que os componentes que vão ser tocados (mesmo que tangencialmente) têm cobertura de testes. Se não tiverem, criá-la e executá-la antes de iniciar a implementação.

Passos

  1. Identificar superfície tangencial: a partir da FASE 1.5 (reutilização vs extensão vs novo), listar:

    • Serviços existentes cujos métodos vão ser estendidos ou sobrecarregados
    • Interfaces existentes que vão ser modificadas
    • Endpoints existentes que podem ser afetados por routing/DI
    • Qualquer arquivo existente que vai ser editado (não criado)
  2. Para cada componente existente que vai ser tocado:

    • Buscar testes em src/*.Test*/** que o exercitem
    • Se tiver cobertura → OK, continuar
    • Se não tiver cobertura → HARD BLOCK:
      • Invocar @refactor-worker-tests para criar testes de caracterização do comportamento atual
      • Invocar @refactor-verifier para confirmar que passam em verde
      • Commit separado:
        test(characterization): add characterization tests for <classes>
        
  3. Se a funcionalidade é 100% criação nova (não toca arquivos existentes):

    • Não há superfície de regressão → pular PREFLIGHT
    • Mas os testes da nova funcionalidade são criados na FASE 4 e devem passar na FASE 5

Critério de fechamento (FASE 5)

Para dar a funcionalidade como correta, @refactor-verifier deve confirmar que passam:

  1. Testes novos da funcionalidade (serviço + endpoint)
  2. Testes existentes dos componentes tangenciais (regressão)

Se algum falhar, a funcionalidade não pode ser fechada.


FASE 2 — Árvore de decisão: o que criar e onde

Aplicar a decisão da FASE 1.5 (reutilização / extensão / novo) mais a FASE 1.6 (config).

Para endpoint READ-ONLY com reutilização

*.API/
  + {Nome}Function.cs       — Function/Controller novo
  + {Nome}Request.cs        — exclusivo de apresentação
  + {Nome}Response.cs       — exclusivo de apresentação
*.Test*/
  + {Nome}FunctionTests.cs  — teste de shape do response (NÃO lógica)

Para endpoint MUTATION com serviço novo

*.Contracts/
  + ICS{Nome}Service.cs     — interface do serviço
  + {Nome}Request.cs        — se Request compartilhado
  + {Nome}Response.cs       — se Response compartilhado
*.Impl/
  + CS{Nome}Service.cs      — implementação
  + I{Nome}Options.cs       — SÓ se FASE 1.6 detectou config
*.API/
  + {Nome}Function.cs       — Function/Controller
  + {Nome}Request.cs        — exclusivo (se não foi colocado em Contracts)
  + {Nome}Response.cs       — exclusivo (se não foi colocado em Contracts)
*.Test*/
  + CS{Nome}ServiceTests.cs — happy path + pelo menos um erro

Para extensão de serviço existente

*.Contracts/
  ~ ICS{Nome}Service.cs     — adicionar assinatura do método (ou criar overload)
*.Impl/
  ~ CS{Nome}Service.cs      — implementar o novo método/overload
*.API/
  + {Nome}Function.cs       — Function/Controller novo
  + {Nome}Request.cs        — se exclusivo
  + {Nome}Response.cs       — se exclusivo
*.Test*/
  + (ou ~) testes do serviço — adicionar caso para o novo método

FASE 3 — Plano de criação

Antes de invocar workers, o orquestrador apresenta este plano ao usuário e espera confirmação explícita:

[PLANO DE CRIAÇÃO] Funcionalidade: <nome> — <descrição breve>
Host: <FUNCTIONS | WEBAPP>
Classificação: <READ-ONLY | MUTATION>
Estratégia: <REUTILIZAÇÃO | EXTENSÃO | NOVO>

Análise de reutilização (FASE 1.5):
  · Serviço candidato: <ICSXxxService> ou "nenhum"
  · Método candidato: <XxxService.YyyMethod> ou "nenhum"
  · Decisão: <REUTILIZAÇÃO | EXTENSÃO | NOVO>

Análise de configuração (FASE 1.6):
  · Requer config: <SIM | NÃO>
  · Se sim: <IXxxOptions + seção appsettings>

Impacto na API pública (FASE 1.7):
  · Call sites afetados: <lista> ou "nenhum"
  · Breaking change: <SIM | NÃO>

Artefatos a criar:

  *.Contracts/ ([N] arquivos):
    + ICS{Nome}Service.cs    — nova interface (ou: adicionar método a IXxx)
    + {Nome}Request.cs       — se tipo compartilhado
    + {Nome}Response.cs      — se tipo compartilhado

  *.Impl/ ([N] arquivos):
    + CS{Nome}Service.cs     — implementação do serviço
    + I{Nome}Options.cs      — SÓ se requer config (FASE 1.6)

  *.API/ ([N] arquivos):
    + {Nome}Function.cs      — Azure Function (ou: {Nome}Controller.cs)
    + {Nome}Request.cs       — se tipo exclusivo
    + {Nome}Response.cs      — se tipo exclusivo

  *.Test*/ ([N] arquivos):
    + CS{Nome}ServiceTests.cs — testes do serviço (happy path + erro)
    + {Nome}FunctionTests.cs  — testes do endpoint (se aplicável)

Modificações em arquivos existentes:
  ~ src/.../IoCExtensions.cs   — registrar serviço e opções (se aplicável)

Ordem de execução: Contracts → Impl → Presentation → Tests

Prosseguir?

Sem aprovação explícita do usuário, não invocar workers.


FASE 4 — Execução

Ordem dos workers

  1. @refactor-worker-contracts — só se houver novos tipos ou assinaturas em *.Contracts/
  2. @refactor-worker-impl — sempre que houver código em *.Impl/
  3. @refactor-worker-presentation — sempre que houver um endpoint
  4. @refactor-worker-tests — sempre ao final

Nota: NÃO invocar @refactor-worker-crosscutting a menos que a funcionalidade exponha um novo Service Gateway. Isso é um caso raro em criação; geralmente é em refactors.

Instruções para cada worker

Incluir no prompt:

  • O plano completo (FASE 3)
  • Os padrões do projeto: ler um arquivo similar antes de criar
  • A lista exata de arquivos com seu conteúdo esperado
  • Se a FASE 1.6 detectou config: o caminho de IXxxOptions e a seção de configuração

FASE 5 — Verificação e commit

  1. Invocar @refactor-verifier
  2. Se PASS → propor commit com formato:
    feat(<escopo>): add funcionalidade <nome-curto>
    
    - Adicionada interface ICS{Nome}Service e implementação CS{Nome}Service
    - Adicionado Function/Controller {VERBO} /{rota}
    - Adicionados contratos {Nome}Request/{Nome}Response
    - Adicionado I{Nome}Options para nova configuração (se aplicável)
    - Adicionados testes de unidade para CS{Nome}Service
    
  3. Se FAIL → identificar camada com falha, re-invocar worker, re-verificar

Padrões por host

FUNCTIONS — Azure Functions Isolated Worker

Antes de criar a Function, ler uma Function HTTP existente e copiar seu estilo. Exemplo típico:

public class {Nome}Function
{
    private readonly I{Nome}Service _{campo};

    public {Nome}Function(I{Nome}Service {campo}) => _{campo} = {campo};

    [Function("{Nome}Function")]
    public async Task<HttpResponseData> RunAsync(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = "{rota}")] HttpRequestData req)
    {
        var request = await req.ReadFromJsonAsync<{Nome}Request>();
        var result = await _{campo}.ExecuteAsync(request);
        var response = req.CreateResponse(HttpStatusCode.OK);
        await response.WriteAsJsonAsync(result);
        return response;
    }
}

Verificar antes de criar:

  • AuthorizationLevel.Function ou AuthorizationLevel.Anonymous?
  • Routing em snake_case?
  • Nome da Function compatível com convenção do projeto?

Habilidades Relacionadas