[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M79FFQTHZ7HACKAF10GA3V86":3,"skill-same:01M79FFQTHZ7HACKAF10GA3V86":43},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":28,"install":29,"resources":42},"01M79FFQTHZ7HACKAF10GA3V86","dare-layered-design",null,"Enforce arquitetura estrita de 4 camadas (Handlers, Services, Repositories, Models) em todos os projetos DARE, independente de linguagem ou framework. Inspirado em \"Layered Design for Ruby on Rails Applications\" de Vladimir Dementyev (Evil Martians).","darelabs-tech\u002Fdare-cli","darelabs-tech","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F297032253?v=4","01M79FCCY9B6SQYRDH94K6BP59","01M79FCCZ8GN6HPPEQJSJYC3FP",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fdare-layered-design\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: dare-layered-design\ndescription: Enforce arquitetura estrita de 4 camadas (Handlers, Services, Repositories, Models) em todos os projetos DARE, independente de linguagem ou framework. Inspirado em \"Layered Design for Ruby on Rails Applications\" de Vladimir Dementyev (Evil Martians).\n---\n\n# DARE Layered Design Skill\n\nVocê é um especialista em arquitetura de software e Layered Design. Seu papel é garantir que todo projeto DARE — independente da stack — siga estritamente o pipeline **Handler → Service → Repository → Model**, sem atalhos.\n\n## Quando usar esta skill\n\n- Você está revisando um Pull Request e quer verificar se as camadas foram respeitadas\n- Você está gerando código de scaffold (CRUD, novo módulo, novo endpoint)\n- Você está auditando um projeto legado que vai começar a usar DARE\n- Você está em `\u002Fdare-blueprint` decidindo a estrutura de pastas\n\n## As 4 camadas (regra única, sem exceção)\n\n```\n┌──────────────────────────────────────────┐\n│  Handler  (HTTP, gRPC, CLI, queue worker) │ ← entrada\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Service  (lógica de negócio, 1 operação) │ ← coração\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Repository  (acesso a dados, abstração)  │ ← I\u002FO\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Model  (entidade pura, sem HTTP\u002FDB)      │ ← domínio\n└──────────────────────────────────────────┘\n```\n\n### Handlers (controllers, routers, routes)\n\n**Responsabilidades**\n- Receber request HTTP\u002FgRPC\u002FCLI\n- Validar input (delegar para FormRequest\u002FPydantic\u002FZod\u002Fserde)\n- Chamar **um** service\n- Retornar response formatada\n\n**NUNCA**\n- Acessar Repository diretamente\n- Conter lógica de negócio\n- Fazer query em banco\n- Instanciar Service com `new` (use injeção)\n\n### Services (use_cases, interactors, commands)\n\n**Responsabilidades**\n- Implementar **uma** operação de negócio (`RegisterUser`, `RefundPayment`)\n- Orquestrar Repositories\n- Validar regras de negócio\n- Lançar exceções de domínio (`UserAlreadyExists`, `InsufficientFunds`)\n\n**NUNCA**\n- Saber sobre HTTP (status code, headers)\n- Saber sobre framework web\n- Conter SQL inline (usa Repository)\n\n### Repositories (repos, data_access, stores)\n\n**Responsabilidades**\n- Abstrair persistência (Postgres, Redis, S3, Stripe API)\n- Retornar Models ou primitivos\n- Esconder detalhes de SQL\u002FHTTP externo\n\n**NUNCA**\n- Retornar HTTP status code\n- Lançar exceções de domínio (retorna `Option\u003CModel>` ou `null`)\n- Conter regra de negócio\n\n### Models (entities, domain, structs)\n\n**Responsabilidades**\n- Representar entidade do domínio\n- Conter invariantes (`Email` válido, `Money` positivo)\n\n**NUNCA**\n- Conter referência a HTTP, DB, framework\n- Importar de Repository\u002FService\u002FHandler\n\n## Métricas obrigatórias\n\n| ID | Métrica | Como medir |\n|---|---|---|\n| M-01 | 100% dos Services têm testes unitários (sem DB\u002FHTTP real) | linter checa `tests\u002Fservices\u002F*` |\n| M-02 | 0% de chamadas Handler→Repository diretas | linter AST\u002Fgrep |\n| M-03 | 100% dos Handlers usam injeção (sem `new Service()` inline) | linter AST\u002Fgrep |\n| M-04 | 100% dos Repositories são agnósticos das camadas superiores (não retornam HTTP status) | linter |\n\n## Tabela tradução por linguagem\n\n| Camada DARE | Laravel | NestJS | FastAPI | Rails | Rust\u002FAxum | Go\u002FGin |\n|---|---|---|---|---|---|---|\n| Handler | `Http\u002FControllers\u002F` | `*.controller.ts` | `routers\u002F*.py` | `app\u002Fcontrollers\u002F` | `handlers\u002F*.rs` | `handlers\u002F*.go` |\n| Service | `Services\u002F` | `*.service.ts` | `services\u002F*.py` | `app\u002Fservices\u002F` | `services\u002F*.rs` | `services\u002F*.go` |\n| Repository | `Repositories\u002F` | `*.repository.ts` | `repositories\u002F*.py` | `app\u002Frepositories\u002F` | `repositories\u002F*.rs` | `repositories\u002F*.go` |\n| Model | `Models\u002F` | `entities\u002F*.ts` | `models\u002F*.py` | `app\u002Fmodels\u002F` | `domain\u002F*.rs` | `models\u002F*.go` |\n\n## Antipatterns\n\n| AP | Antipattern | Sinal | Correção |\n|---|---|---|---|\n| AP-01 | Handler chama Repository | `controller.repo.find()` | Criar Service entre eles |\n| AP-02 | Service faz SQL inline | `db.query(\"SELECT...\")` em Service | Mover para Repository |\n| AP-03 | Repository lança exceção de domínio | `throw UserNotFound` em Repo | Retornar `null`\u002F`Option`\u002F`Maybe` |\n| AP-04 | Model importa Service | `Model.payment_service` | Refatorar: Service usa Model, não o contrário |\n| AP-05 | God Service (tudo em uma classe) | `UserService` com 30 métodos | Quebrar em `RegisterUser`, `ResetPassword`, ... |\n| AP-06 | Fat Controller | Controller > 100 linhas | Mover lógica para Service |\n\n## Como aplicar na prática\n\n### Passo 1: Identificar as camadas no projeto\n\nMapear pastas existentes para as 4 camadas. Se faltarem (ex: projeto Laravel só com Controllers + Models), planejar refactor incremental.\n\n### Passo 2: Adicionar lint\n\nUse ESLint plugin custom, Rubocop cop custom, clippy lint custom, ou apenas grep em CI:\n\n```bash\n# Detecta Handler→Repository direto\ngrep -rn \"import.*Repository\" src\u002Fcontrollers\u002F && exit 1\n```\n\n### Passo 3: Cobrir Services com testes unitários\n\nService NÃO depende de DB nem HTTP real — usa Repository mockado. Suite roda em milissegundos.\n\n```typescript\n\u002F\u002F Exemplo NestJS\ndescribe('RegisterUserService', () => {\n  it('falha se email já existe', async () => {\n    const repo = { findByEmail: jest.fn().mockResolvedValue({id: 1}) };\n    const sut = new RegisterUserService(repo as any);\n    await expect(sut.execute({email: 'x@y.com'})).rejects.toThrow('email exists');\n  });\n});\n```\n\n### Passo 4: Validar com Ralph Loop\n\nA cada task:\n- `npm test` \u002F `cargo test` \u002F `pytest` — Services 100% verde\n- `npm run lint` — sem AP-01 a AP-06\n\n## Boas práticas\n\n1. **Uma operação = um Service** — facilita teste, reuso e nomeação\n2. **Repository devolve Model, não DTO** — DTO é responsabilidade do Handler\u002FPresenter\n3. **Models são imutáveis quando possível** — mudanças passam por Service\n4. **Presenter como 5ª camada opcional** — converte Model → JSON\u002FXML\n\n## Dicas para melhor resultado\n\n- **Leia** `docs\u002Fdesign\u002Fskills\u002Fdare-layered-design\u002FDESIGN.md` para o \"porquê\" e exemplos detalhados\n- **Combine** com `dare-feature-design` ao adicionar feature em código legado — siga as 4 camadas mesmo se o legado não seguir\n- **Templates de scaffold** estão em `packages\u002Fskills\u002Fdare-layered-design\u002F` por linguagem\n\n---\n\nEsta skill é parte do DARE Method e está sob licença MIT.\n","# DARE Layered Design Skill\n\nVocê é um especialista em arquitetura de software e Layered Design. Seu papel é garantir que todo projeto DARE — independente da stack — siga estritamente o pipeline **Handler → Service → Repository → Model**, sem atalhos.\n\n## Quando usar esta skill\n\n- Você está revisando um Pull Request e quer verificar se as camadas foram respeitadas\n- Você está gerando código de scaffold (CRUD, novo módulo, novo endpoint)\n- Você está auditando um projeto legado que vai começar a usar DARE\n- Você está em `\u002Fdare-blueprint` decidindo a estrutura de pastas\n\n## As 4 camadas (regra única, sem exceção)\n\n```\n┌──────────────────────────────────────────┐\n│  Handler  (HTTP, gRPC, CLI, queue worker) │ ← entrada\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Service  (lógica de negócio, 1 operação) │ ← coração\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Repository  (acesso a dados, abstração)  │ ← I\u002FO\n└──────────────────────────────────────────┘\n              ↓\n┌──────────────────────────────────────────┐\n│  Model  (entidade pura, sem HTTP\u002FDB)      │ ← domínio\n└──────────────────────────────────────────┘\n```\n\n### Handlers (controllers, routers, routes)\n\n**Responsabilidades**\n- Receber request HTTP\u002FgRPC\u002FCLI\n- Validar input (delegar para FormRequest\u002FPydantic\u002FZod\u002Fserde)\n- Chamar **um** service\n- Retornar response formatada\n\n**NUNCA**\n- Acessar Repository diretamente\n- Conter lógica de negócio\n- Fazer query em banco\n- Instanciar Service com `new` (use injeção)\n\n### Services (use_cases, interactors, commands)\n\n**Responsabilidades**\n- Implementar **uma** operação de negócio (`RegisterUser`, `RefundPayment`)\n- Orquestrar Repositories\n- Validar regras de negócio\n- Lançar exceções de domínio (`UserAlreadyExists`, `InsufficientFunds`)\n\n**NUNCA**\n- Saber sobre HTTP (status code, headers)\n- Saber sobre framework web\n- Conter SQL inline (usa Repository)\n\n### Repositories (repos, data_access, stores)\n\n**Responsabilidades**\n- Abstrair persistência (Postgres, Redis, S3, Stripe API)\n- Retornar Models ou primitivos\n- Esconder detalhes de SQL\u002FHTTP externo\n\n**NUNCA**\n- Retornar HTTP status code\n- Lançar exceções de domínio (retorna `Option\u003CModel>` ou `null`)\n- Conter regra de negócio\n\n### Models (entities, domain, structs)\n\n**Responsabilidades**\n- Representar entidade do domínio\n- Conter invariantes (`Email` válido, `Money` positivo)\n\n**NUNCA**\n- Conter referência a HTTP, DB, framework\n- Importar de Repository\u002FService\u002FHandler\n\n## Métricas obrigatórias\n\n| ID | Métrica | Como medir |\n|---|---|---|\n| M-01 | 100% dos Services têm testes unitários (sem DB\u002FHTTP real) | linter checa `tests\u002Fservices\u002F*` |\n| M-02 | 0% de chamadas Handler→Repository diretas | linter AST\u002Fgrep |\n| M-03 | 100% dos Handlers usam injeção (sem `new Service()` inline) | linter AST\u002Fgrep |\n| M-04 | 100% dos Repositories são agnósticos das camadas superiores (não retornam HTTP status) | linter |\n\n## Tabela tradução por linguagem\n\n| Camada DARE | Laravel | NestJS | FastAPI | Rails | Rust\u002FAxum | Go\u002FGin |\n|---|---|---|---|---|---|---|\n| Handler | `Http\u002FControllers\u002F` | `*.controller.ts` | `routers\u002F*.py` | `app\u002Fcontrollers\u002F` | `handlers\u002F*.rs` | `handlers\u002F*.go` |\n| Service | `Services\u002F` | `*.service.ts` | `services\u002F*.py` | `app\u002Fservices\u002F` | `services\u002F*.rs` | `services\u002F*.go` |\n| Repository | `Repositories\u002F` | `*.repository.ts` | `repositories\u002F*.py` | `app\u002Frepositories\u002F` | `repositories\u002F*.rs` | `repositories\u002F*.go` |\n| Model | `Models\u002F` | `entities\u002F*.ts` | `models\u002F*.py` | `app\u002Fmodels\u002F` | `domain\u002F*.rs` | `models\u002F*.go` |\n\n## Antipatterns\n\n| AP | Antipattern | Sinal | Correção |\n|---|---|---|---|\n| AP-01 | Handler chama Repository | `controller.repo.find()` | Criar Service entre eles |\n| AP-02 | Service faz SQL inline | `db.query(\"SELECT...\")` em Service | Mover para Repository |\n| AP-03 | Repository lança exceção de domínio | `throw UserNotFound` em Repo | Retornar `null`\u002F`Option`\u002F`Maybe` |\n| AP-04 | Model importa Service | `Model.payment_service` | Refatorar: Service usa Model, não o contrário |\n| AP-05 | God Service (tudo em uma classe) | `UserService` com 30 métodos | Quebrar em `RegisterUser`, `ResetPassword`, ... |\n| AP-06 | Fat Controller | Controller > 100 linhas | Mover lógica para Service |\n\n## Como aplicar na prática\n\n### Passo 1: Identificar as camadas no projeto\n\nMapear pastas existentes para as 4 camadas. Se faltarem (ex: projeto Laravel só com Controllers + Models), planejar refactor incremental.\n\n### Passo 2: Adicionar lint\n\nUse ESLint plugin custom, Rubocop cop custom, clippy lint custom, ou apenas grep em CI:\n\n```bash\n# Detecta Handler→Repository direto\ngrep -rn \"import.*Repository\" src\u002Fcontrollers\u002F && exit 1\n```\n\n### Passo 3: Cobrir Services com testes unitários\n\nService NÃO depende de DB nem HTTP real — usa Repository mockado. Suite roda em milissegundos.\n\n```typescript\n\u002F\u002F Exemplo NestJS\ndescribe('RegisterUserService', () => {\n  it('falha se email já existe', async () => {\n    const repo = { findByEmail: jest.fn().mockResolvedValue({id: 1}) };\n    const sut = new RegisterUserService(repo as any);\n    await expect(sut.execute({email: 'x@y.com'})).rejects.toThrow('email exists');\n  });\n});\n```\n\n### Passo 4: Validar com Ralph Loop\n\nA cada task:\n- `npm test` \u002F `cargo test` \u002F `pytest` — Services 100% verde\n- `npm run lint` — sem AP-01 a AP-06\n\n## Boas práticas\n\n1. **Uma operação = um Service** — facilita teste, reuso e nomeação\n2. **Repository devolve Model, não DTO** — DTO é responsabilidade do Handler\u002FPresenter\n3. **Models são imutáveis quando possível** — mudanças passam por Service\n4. **Presenter como 5ª camada opcional** — converte Model → JSON\u002FXML\n\n## Dicas para melhor resultado\n\n- **Leia** `docs\u002Fdesign\u002Fskills\u002Fdare-layered-design\u002FDESIGN.md` para o \"porquê\" e exemplos detalhados\n- **Combine** com `dare-feature-design` ao adicionar feature em código legado — siga as 4 camadas mesmo se o legado não seguir\n- **Templates de scaffold** estão em `packages\u002Fskills\u002Fdare-layered-design\u002F` por linguagem\n\n---\n\nEsta skill é parte do DARE Method e está sob licença MIT.\n",{"name":5,"description":7},"main","3597b5ea0f4e90a0b47e4c036afc7eeb087d5ea5",".agents\u002Fskills\u002Fdare-layered-design","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech","2026-10-23 09:15:53",{"source":8,"skillName":5,"commands":30,"prompt":40,"zipAvailable":41},[31,34,37],{"tool":32,"command":33},"npx","npx skills add darelabs-tech\u002Fdare-cli --skill dare-layered-design",{"tool":35,"command":36},"bunx","bunx skills add darelabs-tech\u002Fdare-cli --skill dare-layered-design",{"tool":38,"command":39},"pnpm","pnpm dlx skills add darelabs-tech\u002Fdare-cli --skill dare-layered-design","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fdare-layered-design\u002FSKILL.md",true,[],[44,50,55,62,69,76],{"skillNo":45,"name":46,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":47,"categories":48,"keywords":49,"publishedAt":18},"01M79FRYATNTKSEW78ZF8YPTMP","commands","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fbook\u002Fpt\u002Fsrc\u002Fcommands\u002Fskill.md",[],[],{"skillNo":51,"name":46,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":52,"categories":53,"keywords":54,"publishedAt":18},"01M79FRX217T58KNDCKKXWRMP1","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fbook\u002Fen\u002Fsrc\u002Fcommands\u002Fskill.md",[],[],{"skillNo":56,"name":57,"nameZh":6,"description":58,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":59,"categories":60,"keywords":61,"publishedAt":18},"01M79FRS84X15ZCGTK7C2SAMXM","skill-rails-api","Padrões DARE para APIs em Ruby on Rails 8 — API mode, ActiveRecord, Solid Queue, Solid Cable, Action Cable, strong parameters, services (interactors), serializers (Blueprinter\u002FAlba), Devise\u002FJWT, rack-attack, rswag\u002Fgrape-swagger.","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fassets\u002Fnpm\u002Fide\u002Fantigravity\u002F.agents\u002Fskills\u002Fskill-rails-api\u002FSKILL.md",[],[],{"skillNo":63,"name":64,"nameZh":6,"description":65,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":68,"publishedAt":18},"01M79FRN9NQ4DXWBFFPWJF39RA","skill-nestjs-api","Padrões DARE para APIs REST em NestJS + TypeScript + Prisma + Swagger. Modules, Controllers, Services, DTOs com class-validator, Guards, Interceptors, exceções globais, Jest + Supertest, OpenAPI auto-gerado, rate limiting com @nestjs\u002Fthrottler.","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fassets\u002Fnpm\u002Fide\u002Fantigravity\u002F.agents\u002Fskills\u002Fskill-nestjs-api\u002FSKILL.md",[],[],{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":18},"01M79FRGSECX4GBGN2X3ZM27TD","skill-mcp-server","Padrões DARE para servidores MCP (Model Context Protocol) em TypeScript ou Python. Define tools, resources, prompts; suporta transports stdio, SSE e HTTP; validação Zod\u002FPydantic; autorização por tool; tracing estruturado; testes; publicação no MCP registry.","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fassets\u002Fnpm\u002Fide\u002Fantigravity\u002F.agents\u002Fskills\u002Fskill-mcp-server\u002FSKILL.md",[],[],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":18},"01M79FRCY80X3GKQ36YTB4TYTQ","skill-go-gin-api","Padrões DARE para APIs REST em Go + Gin (ou stdlib net\u002Fhttp) + sqlc + PostgreSQL. Handlers, services, repositories, middleware, validação com go-playground\u002Fvalidator, JWT, rate limit, swag (OpenAPI), testes com testify e httptest.","https:\u002F\u002Fgithub.com\u002Fdarelabs-tech\u002Fdare-cli\u002Fblob\u002Fmain\u002Fassets\u002Fnpm\u002Fide\u002Fantigravity\u002F.agents\u002Fskills\u002Fskill-go-gin-api\u002FSKILL.md",[],[]]