@maestro-ai/mcp-server 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -227
- package/dist/content/design-system/README.md +231 -231
- package/dist/content/design-system/indexes/README.md +211 -211
- package/dist/content/design-system/indexes/colors-index.md +156 -156
- package/dist/content/design-system/indexes/quick-search.md +111 -111
- package/dist/content/design-system/indexes/stacks-index.md +341 -341
- package/dist/content/examples/Exemplo de Fluxo Completo com Java e Spring Boot.md +249 -249
- package/dist/content/examples/Exemplo de Fluxo Completo com Laravel e Filament.md +277 -277
- package/dist/content/examples/Exemplo de Fluxo Completo com Laravel e Livewire.md +260 -260
- package/dist/content/examples/Exemplo de Fluxo Completo com Node e NestJS.md +257 -257
- package/dist/content/guides/Cat/303/241logo de Stacks para Cloud Moderna.md" +119 -119
- package/dist/content/guides/Cat/303/241logo de Stacks para Hospedagem Compartilhada.md" +147 -147
- package/dist/content/guides/Checklist Mestre de Entrega.md +68 -68
- package/dist/content/guides/Gates de Qualidade.md +209 -209
- package/dist/content/guides/Guia de Adi/303/247/303/243o de Novas Funcionalidades.md" +355 -355
- package/dist/content/guides/Guia de Chaos Engineering.md +267 -267
- package/dist/content/guides/Guia de Debugging com IA.md +135 -135
- package/dist/content/guides/Guia de Estrat/303/251gias de Cache.md" +352 -352
- package/dist/content/guides/Guia de Migrations Zero-Downtime.md +311 -311
- package/dist/content/guides/Guia de Multi-tenancy.md +368 -368
- package/dist/content/guides/Guia de Otimiza/303/247/303/243o de Custos Cloud.md" +195 -195
- package/dist/content/guides/Guia de Refatora/303/247/303/243o de C/303/263digo Legado com IA.md" +162 -162
- package/dist/content/guides/Guia de SLOs e Error Budgets.md +315 -315
- package/dist/content/guides/M/303/251tricas de Efici/303/252ncia do Desenvolvimento com IA.md" +93 -93
- package/dist/content/guides/Rules base.md +90 -90
- package/dist/content/playbook/Playbook de Desenvolvimento com IA.md +364 -364
- package/dist/content/prompts/README.md +203 -203
- package/dist/content/prompts/acessibilidade/analise-acessibilidade.md +257 -257
- package/dist/content/prompts/apis/design-api-rest.md +303 -303
- package/dist/content/prompts/apis/idempotencia.md +254 -254
- package/dist/content/prompts/apis/versionamento.md +313 -313
- package/dist/content/prompts/arquitetura/arquitetura-c4-completo.md +190 -190
- package/dist/content/prompts/arquitetura/clean-architecture.md +151 -151
- package/dist/content/prompts/arquitetura/ddd-bounded-contexts.md +183 -183
- package/dist/content/prompts/arquitetura/ddd-cqrs.md +176 -176
- package/dist/content/prompts/arquitetura/modelo-dominio.md +207 -207
- package/dist/content/prompts/arquitetura/multi-tenancy.md +235 -235
- package/dist/content/prompts/database/migrations-zero-downtime.md +192 -192
- package/dist/content/prompts/database/otimizacao-queries.md +296 -296
- package/dist/content/prompts/desenvolvimento/code-review.md +301 -301
- package/dist/content/prompts/desenvolvimento/gerar-servico.md +271 -271
- package/dist/content/prompts/devops/docker-compose.md +336 -336
- package/dist/content/prompts/devops/feature-flags.md +374 -374
- package/dist/content/prompts/devops/kubernetes-deploy.md +460 -460
- package/dist/content/prompts/devops/pipeline-cicd.md +358 -358
- package/dist/content/prompts/devops/terraform-iac.md +502 -502
- package/dist/content/prompts/escalabilidade/analise-performance.md +240 -240
- package/dist/content/prompts/escalabilidade/analise-performance.txt +94 -94
- package/dist/content/prompts/escalabilidade/caching.md +255 -255
- package/dist/content/prompts/observabilidade/chaos-testing.md +237 -237
- package/dist/content/prompts/observabilidade/estrategia-observabilidade.md +263 -263
- package/dist/content/prompts/observabilidade/estrategia-observabilidade.txt +134 -134
- package/dist/content/prompts/observabilidade/slos.md +215 -215
- package/dist/content/prompts/produto/discovery-inicial.md +203 -203
- package/dist/content/prompts/produto/discovery-inicial.txt +33 -33
- package/dist/content/prompts/requisitos/refinar-requisitos.md +232 -232
- package/dist/content/prompts/requisitos/refinar-requisitos.txt +40 -40
- package/dist/content/prompts/seguranca/analise-seguranca.md +243 -243
- package/dist/content/prompts/seguranca/pentest-checklist.md +333 -333
- package/dist/content/prompts/seguranca/rate-limiting.md +356 -356
- package/dist/content/prompts/seguranca/revisao-lgpd.md +227 -227
- package/dist/content/prompts/seguranca/threat-modeling.md +224 -224
- package/dist/content/prompts/testes/contract-testing.md +340 -340
- package/dist/content/prompts/testes/gerar-testes-unitarios.md +474 -474
- package/dist/content/prompts/testes/testes-e2e.md +460 -460
- package/dist/content/prompts/testes/testes-integracao.md +418 -418
- package/dist/content/prompts/testes/testes-performance.md +458 -458
- package/dist/content/prompts/ux/gerar-ui-stitch.md +151 -151
- package/dist/content/rules/RULES.md +835 -835
- package/dist/content/rules/adapters/copilot.md +10 -10
- package/dist/content/rules/adapters/cursor.md +10 -10
- package/dist/content/rules/adapters/gemini.md +13 -13
- package/dist/content/rules/adapters/windsurf.md +10 -10
- package/dist/content/specialists/Especialista em Acessibilidade.md +266 -266
- package/dist/content/specialists/Especialista em An/303/241lise de Testes.md" +434 -434
- package/dist/content/specialists/Especialista em Arquitetura Avan/303/247ada.md" +358 -358
- package/dist/content/specialists/Especialista em Arquitetura de Software.md +177 -177
- package/dist/content/specialists/Especialista em Banco de Dados.md +260 -260
- package/dist/content/specialists/Especialista em Contrato de API.md +172 -172
- package/dist/content/specialists/Especialista em Dados e Analytics com IA.md +246 -246
- package/dist/content/specialists/Especialista em Debugging e Troubleshooting.md +191 -191
- package/dist/content/specialists/Especialista em Desenvolvimento Frontend.md +477 -477
- package/dist/content/specialists/Especialista em Desenvolvimento Mobile.md +241 -241
- package/dist/content/specialists/Especialista em Desenvolvimento e Vibe Coding Estruturado.md +417 -417
- package/dist/content/specialists/Especialista em DevOps e Infraestrutura.md +294 -294
- package/dist/content/specialists/Especialista em Documenta/303/247/303/243o T/303/251cnica.md" +227 -227
- package/dist/content/specialists/Especialista em Engenharia de Requisitos com IA.md +299 -299
- package/dist/content/specialists/Especialista em Explora/303/247/303/243o de Codebase.md" +179 -179
- package/dist/content/specialists/Especialista em Gest/303/243o de Produto.md" +179 -179
- package/dist/content/specialists/Especialista em Migra/303/247/303/243o e Moderniza/303/247/303/243o.md" +410 -410
- package/dist/content/specialists/Especialista em Modelagem e Arquitetura de Dom/303/255nio com IA.md" +248 -248
- package/dist/content/specialists/Especialista em Observabilidade.md +415 -415
- package/dist/content/specialists/Especialista em Performance e Escalabilidade.md +373 -373
- package/dist/content/specialists/Especialista em Plano de Execu/303/247/303/243o com IA.md" +341 -341
- package/dist/content/specialists/Especialista em Prototipagem R/303/241pida com Google Stitch.md" +419 -419
- package/dist/content/specialists/Especialista em Seguran/303/247a da Informa/303/247/303/243o.md" +508 -508
- package/dist/content/specialists/Especialista em UX Design.md +453 -453
- package/dist/content/specialists/INDEX.md +43 -43
- package/dist/content/templates/PRD.md +165 -165
- package/dist/content/templates/README.md +65 -65
- package/dist/content/templates/adr.md +103 -103
- package/dist/content/templates/arquitetura.md +279 -279
- package/dist/content/templates/backlog.md +185 -185
- package/dist/content/templates/checklist-seguranca.md +180 -180
- package/dist/content/templates/contexto.md +120 -120
- package/dist/content/templates/criterios-aceite.md +99 -99
- package/dist/content/templates/design-banco.md +270 -270
- package/dist/content/templates/design-doc.md +240 -240
- package/dist/content/templates/feature.md +88 -88
- package/dist/content/templates/historia-backend.md +84 -84
- package/dist/content/templates/historia-frontend.md +75 -75
- package/dist/content/templates/historia-usuario.md +125 -125
- package/dist/content/templates/mapa-navegacao.md +133 -133
- package/dist/content/templates/matriz-rastreabilidade.md +121 -121
- package/dist/content/templates/modelo-dominio.md +219 -219
- package/dist/content/templates/plano-testes.md +199 -199
- package/dist/content/templates/prototipo-stitch.md +138 -138
- package/dist/content/templates/requisitos.md +162 -162
- package/dist/content/templates/slo-sli.md +197 -197
- package/dist/content/workflows/README-MCP.md +363 -363
- package/dist/content/workflows/mcp-debug.md +506 -506
- package/dist/content/workflows/mcp-feature.md +385 -385
- package/dist/content/workflows/mcp-gate.md +413 -413
- package/dist/content/workflows/mcp-next.md +388 -388
- package/dist/content/workflows/mcp-refactor.md +600 -600
- package/dist/content/workflows/mcp-start.md +304 -304
- package/dist/content/workflows/mcp-status.md +400 -400
- package/dist/gates/tiers.test.js +14 -14
- package/dist/index.js +133 -133
- package/dist/resources/index.js +61 -61
- package/dist/stdio.js +39 -32
- package/dist/stdio.js.map +1 -1
- package/dist/tools/analise/performance.js +23 -23
- package/dist/tools/analise/qualidade.js +23 -23
- package/dist/tools/analise/relatorio.js +24 -24
- package/dist/tools/analise/seguranca.js +28 -28
- package/dist/tools/aprovar-gate.js +81 -81
- package/dist/tools/atualizar-codebase.js +18 -18
- package/dist/tools/avaliar-entregavel.js +18 -18
- package/dist/tools/carregar-projeto.js +103 -103
- package/dist/tools/classificar.js +36 -36
- package/dist/tools/confirmar-classificacao.js +36 -36
- package/dist/tools/confirmar-stitch.js +75 -75
- package/dist/tools/contexto.js +56 -56
- package/dist/tools/fluxos-alternativos.js +98 -98
- package/dist/tools/implementar-historia.js +63 -63
- package/dist/tools/iniciar-projeto.js +174 -174
- package/dist/tools/proximo.js +239 -239
- package/dist/tools/salvar.js +59 -59
- package/dist/tools/status.js +76 -76
- package/dist/tools/validar-gate.js +35 -35
- package/dist/types/response.js +11 -11
- package/dist/utils/instructions.js +48 -48
- package/dist/utils/prompt-mapper.js +16 -16
- package/dist/utils/system-md.js +33 -33
- package/package.json +67 -67
- package/dist/content/content/design-system/README.md +0 -231
- package/dist/content/content/design-system/data/charts.csv +0 -26
- package/dist/content/content/design-system/data/colors.csv +0 -97
- package/dist/content/content/design-system/data/icons.csv +0 -101
- package/dist/content/content/design-system/data/landing.csv +0 -31
- package/dist/content/content/design-system/data/products.csv +0 -97
- package/dist/content/content/design-system/data/prompts.csv +0 -24
- package/dist/content/content/design-system/data/react-performance.csv +0 -45
- package/dist/content/content/design-system/data/styles.csv +0 -59
- package/dist/content/content/design-system/data/typography.csv +0 -58
- package/dist/content/content/design-system/data/ui-reasoning.csv +0 -101
- package/dist/content/content/design-system/data/ux-guidelines.csv +0 -100
- package/dist/content/content/design-system/data/web-interface.csv +0 -31
- package/dist/content/content/design-system/indexes/README.md +0 -211
- package/dist/content/content/design-system/indexes/colors-index.md +0 -156
- package/dist/content/content/design-system/indexes/quick-search.md +0 -111
- package/dist/content/content/design-system/indexes/stacks-index.md +0 -341
- package/dist/content/content/design-system/stacks/flutter.csv +0 -53
- package/dist/content/content/design-system/stacks/html-tailwind.csv +0 -56
- package/dist/content/content/design-system/stacks/jetpack-compose.csv +0 -53
- package/dist/content/content/design-system/stacks/nextjs.csv +0 -53
- package/dist/content/content/design-system/stacks/nuxt-ui.csv +0 -51
- package/dist/content/content/design-system/stacks/nuxtjs.csv +0 -59
- package/dist/content/content/design-system/stacks/react-native.csv +0 -52
- package/dist/content/content/design-system/stacks/react.csv +0 -54
- package/dist/content/content/design-system/stacks/shadcn.csv +0 -61
- package/dist/content/content/design-system/stacks/svelte.csv +0 -54
- package/dist/content/content/design-system/stacks/swiftui.csv +0 -51
- package/dist/content/content/design-system/stacks/vue.csv +0 -50
- package/dist/content/content/examples/Exemplo de Fluxo Completo com Java e Spring Boot.md +0 -250
- package/dist/content/content/examples/Exemplo de Fluxo Completo com Laravel e Filament.md +0 -278
- package/dist/content/content/examples/Exemplo de Fluxo Completo com Laravel e Livewire.md +0 -261
- package/dist/content/content/examples/Exemplo de Fluxo Completo com Node e NestJS.md +0 -258
- package/dist/content/content/guides/Cat/303/241logo de Stacks para Cloud Moderna.md" +0 -119
- package/dist/content/content/guides/Cat/303/241logo de Stacks para Hospedagem Compartilhada.md" +0 -147
- package/dist/content/content/guides/Checklist Mestre de Entrega.md +0 -68
- package/dist/content/content/guides/Gates de Qualidade.md +0 -209
- package/dist/content/content/guides/Guia de Adi/303/247/303/243o de Novas Funcionalidades.md" +0 -355
- package/dist/content/content/guides/Guia de Chaos Engineering.md +0 -267
- package/dist/content/content/guides/Guia de Debugging com IA.md +0 -135
- package/dist/content/content/guides/Guia de Estrat/303/251gias de Cache.md" +0 -352
- package/dist/content/content/guides/Guia de Migrations Zero-Downtime.md +0 -311
- package/dist/content/content/guides/Guia de Multi-tenancy.md +0 -368
- package/dist/content/content/guides/Guia de Otimiza/303/247/303/243o de Custos Cloud.md" +0 -195
- package/dist/content/content/guides/Guia de Refatora/303/247/303/243o de C/303/263digo Legado com IA.md" +0 -162
- package/dist/content/content/guides/Guia de SLOs e Error Budgets.md +0 -315
- package/dist/content/content/guides/M/303/251tricas de Efici/303/252ncia do Desenvolvimento com IA.md" +0 -93
- package/dist/content/content/guides/Rules base.md +0 -90
- package/dist/content/content/playbook/Playbook de Desenvolvimento com IA.md +0 -364
- package/dist/content/content/prompts/README.md +0 -203
- package/dist/content/content/prompts/acessibilidade/analise-acessibilidade.md +0 -257
- package/dist/content/content/prompts/apis/design-api-rest.md +0 -303
- package/dist/content/content/prompts/apis/idempotencia.md +0 -254
- package/dist/content/content/prompts/apis/versionamento.md +0 -313
- package/dist/content/content/prompts/arquitetura/arquitetura-c4-completo.md +0 -190
- package/dist/content/content/prompts/arquitetura/clean-architecture.md +0 -151
- package/dist/content/content/prompts/arquitetura/ddd-bounded-contexts.md +0 -183
- package/dist/content/content/prompts/arquitetura/ddd-cqrs.md +0 -176
- package/dist/content/content/prompts/arquitetura/modelo-dominio.md +0 -207
- package/dist/content/content/prompts/arquitetura/multi-tenancy.md +0 -235
- package/dist/content/content/prompts/database/migrations-zero-downtime.md +0 -192
- package/dist/content/content/prompts/database/otimizacao-queries.md +0 -296
- package/dist/content/content/prompts/desenvolvimento/code-review.md +0 -301
- package/dist/content/content/prompts/desenvolvimento/gerar-servico.md +0 -271
- package/dist/content/content/prompts/devops/docker-compose.md +0 -336
- package/dist/content/content/prompts/devops/feature-flags.md +0 -374
- package/dist/content/content/prompts/devops/kubernetes-deploy.md +0 -460
- package/dist/content/content/prompts/devops/pipeline-cicd.md +0 -358
- package/dist/content/content/prompts/devops/terraform-iac.md +0 -502
- package/dist/content/content/prompts/escalabilidade/analise-performance.md +0 -240
- package/dist/content/content/prompts/escalabilidade/analise-performance.txt +0 -94
- package/dist/content/content/prompts/escalabilidade/caching.md +0 -255
- package/dist/content/content/prompts/observabilidade/chaos-testing.md +0 -237
- package/dist/content/content/prompts/observabilidade/estrategia-observabilidade.md +0 -263
- package/dist/content/content/prompts/observabilidade/estrategia-observabilidade.txt +0 -134
- package/dist/content/content/prompts/observabilidade/slos.md +0 -215
- package/dist/content/content/prompts/produto/discovery-inicial.md +0 -203
- package/dist/content/content/prompts/produto/discovery-inicial.txt +0 -33
- package/dist/content/content/prompts/requisitos/refinar-requisitos.md +0 -232
- package/dist/content/content/prompts/requisitos/refinar-requisitos.txt +0 -40
- package/dist/content/content/prompts/seguranca/analise-seguranca.md +0 -243
- package/dist/content/content/prompts/seguranca/pentest-checklist.md +0 -333
- package/dist/content/content/prompts/seguranca/rate-limiting.md +0 -356
- package/dist/content/content/prompts/seguranca/revisao-lgpd.md +0 -227
- package/dist/content/content/prompts/seguranca/threat-modeling.md +0 -224
- package/dist/content/content/prompts/testes/contract-testing.md +0 -340
- package/dist/content/content/prompts/testes/gerar-testes-unitarios.md +0 -474
- package/dist/content/content/prompts/testes/testes-e2e.md +0 -460
- package/dist/content/content/prompts/testes/testes-integracao.md +0 -418
- package/dist/content/content/prompts/testes/testes-performance.md +0 -458
- package/dist/content/content/prompts/ux/gerar-ui-stitch.md +0 -151
- package/dist/content/content/rules/GEMINI.md +0 -841
- package/dist/content/content/rules/RULES.md +0 -835
- package/dist/content/content/rules/adapters/copilot.md +0 -10
- package/dist/content/content/rules/adapters/cursor.md +0 -10
- package/dist/content/content/rules/adapters/gemini.md +0 -13
- package/dist/content/content/rules/adapters/windsurf.md +0 -10
- package/dist/content/content/skills/api-patterns/SKILL.md +0 -81
- package/dist/content/content/skills/api-patterns/api-style.md +0 -42
- package/dist/content/content/skills/api-patterns/auth.md +0 -24
- package/dist/content/content/skills/api-patterns/documentation.md +0 -26
- package/dist/content/content/skills/api-patterns/graphql.md +0 -41
- package/dist/content/content/skills/api-patterns/rate-limiting.md +0 -31
- package/dist/content/content/skills/api-patterns/response.md +0 -37
- package/dist/content/content/skills/api-patterns/rest.md +0 -40
- package/dist/content/content/skills/api-patterns/scripts/api_validator.py +0 -211
- package/dist/content/content/skills/api-patterns/security-testing.md +0 -122
- package/dist/content/content/skills/api-patterns/trpc.md +0 -41
- package/dist/content/content/skills/api-patterns/versioning.md +0 -22
- package/dist/content/content/skills/app-builder/SKILL.md +0 -75
- package/dist/content/content/skills/app-builder/agent-coordination.md +0 -71
- package/dist/content/content/skills/app-builder/feature-building.md +0 -53
- package/dist/content/content/skills/app-builder/project-detection.md +0 -34
- package/dist/content/content/skills/app-builder/scaffolding.md +0 -118
- package/dist/content/content/skills/app-builder/tech-stack.md +0 -40
- package/dist/content/content/skills/app-builder/templates/SKILL.md +0 -39
- package/dist/content/content/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/dist/content/content/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/dist/content/content/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/dist/content/content/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/dist/content/content/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/dist/content/content/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/dist/content/content/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/dist/content/content/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -82
- package/dist/content/content/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -100
- package/dist/content/content/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -106
- package/dist/content/content/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -101
- package/dist/content/content/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/dist/content/content/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -93
- package/dist/content/content/skills/architecture/SKILL.md +0 -55
- package/dist/content/content/skills/architecture/context-discovery.md +0 -43
- package/dist/content/content/skills/architecture/examples.md +0 -94
- package/dist/content/content/skills/architecture/pattern-selection.md +0 -68
- package/dist/content/content/skills/architecture/patterns-reference.md +0 -50
- package/dist/content/content/skills/architecture/trade-off-analysis.md +0 -77
- package/dist/content/content/skills/bash-linux/SKILL.md +0 -199
- package/dist/content/content/skills/behavioral-modes/SKILL.md +0 -242
- package/dist/content/content/skills/brainstorming/SKILL.md +0 -163
- package/dist/content/content/skills/brainstorming/dynamic-questioning.md +0 -350
- package/dist/content/content/skills/clean-code/SKILL.md +0 -201
- package/dist/content/content/skills/code-review-checklist/SKILL.md +0 -109
- package/dist/content/content/skills/database-design/SKILL.md +0 -52
- package/dist/content/content/skills/database-design/database-selection.md +0 -43
- package/dist/content/content/skills/database-design/indexing.md +0 -39
- package/dist/content/content/skills/database-design/migrations.md +0 -48
- package/dist/content/content/skills/database-design/optimization.md +0 -36
- package/dist/content/content/skills/database-design/orm-selection.md +0 -30
- package/dist/content/content/skills/database-design/schema-design.md +0 -56
- package/dist/content/content/skills/database-design/scripts/schema_validator.py +0 -172
- package/dist/content/content/skills/deployment-procedures/SKILL.md +0 -241
- package/dist/content/content/skills/doc.md +0 -177
- package/dist/content/content/skills/documentation-templates/SKILL.md +0 -194
- package/dist/content/content/skills/frontend-design/SKILL.md +0 -396
- package/dist/content/content/skills/frontend-design/animation-guide.md +0 -331
- package/dist/content/content/skills/frontend-design/color-system.md +0 -311
- package/dist/content/content/skills/frontend-design/decision-trees.md +0 -418
- package/dist/content/content/skills/frontend-design/motion-graphics.md +0 -306
- package/dist/content/content/skills/frontend-design/scripts/accessibility_checker.py +0 -183
- package/dist/content/content/skills/frontend-design/scripts/ux_audit.py +0 -722
- package/dist/content/content/skills/frontend-design/typography-system.md +0 -345
- package/dist/content/content/skills/frontend-design/ux-psychology.md +0 -541
- package/dist/content/content/skills/frontend-design/visual-effects.md +0 -383
- package/dist/content/content/skills/game-development/2d-games/SKILL.md +0 -119
- package/dist/content/content/skills/game-development/3d-games/SKILL.md +0 -135
- package/dist/content/content/skills/game-development/SKILL.md +0 -167
- package/dist/content/content/skills/game-development/game-art/SKILL.md +0 -185
- package/dist/content/content/skills/game-development/game-audio/SKILL.md +0 -190
- package/dist/content/content/skills/game-development/game-design/SKILL.md +0 -129
- package/dist/content/content/skills/game-development/mobile-games/SKILL.md +0 -108
- package/dist/content/content/skills/game-development/multiplayer/SKILL.md +0 -132
- package/dist/content/content/skills/game-development/pc-games/SKILL.md +0 -144
- package/dist/content/content/skills/game-development/vr-ar/SKILL.md +0 -123
- package/dist/content/content/skills/game-development/web-games/SKILL.md +0 -150
- package/dist/content/content/skills/geo-fundamentals/SKILL.md +0 -156
- package/dist/content/content/skills/geo-fundamentals/scripts/geo_checker.py +0 -289
- package/dist/content/content/skills/i18n-localization/SKILL.md +0 -154
- package/dist/content/content/skills/i18n-localization/scripts/i18n_checker.py +0 -241
- package/dist/content/content/skills/intelligent-routing/SKILL.md +0 -334
- package/dist/content/content/skills/lint-and-validate/SKILL.md +0 -45
- package/dist/content/content/skills/lint-and-validate/scripts/lint_runner.py +0 -172
- package/dist/content/content/skills/lint-and-validate/scripts/type_coverage.py +0 -173
- package/dist/content/content/skills/mcp-builder/SKILL.md +0 -176
- package/dist/content/content/skills/mobile-design/SKILL.md +0 -394
- package/dist/content/content/skills/mobile-design/decision-trees.md +0 -516
- package/dist/content/content/skills/mobile-design/mobile-backend.md +0 -491
- package/dist/content/content/skills/mobile-design/mobile-color-system.md +0 -420
- package/dist/content/content/skills/mobile-design/mobile-debugging.md +0 -122
- package/dist/content/content/skills/mobile-design/mobile-design-thinking.md +0 -357
- package/dist/content/content/skills/mobile-design/mobile-navigation.md +0 -458
- package/dist/content/content/skills/mobile-design/mobile-performance.md +0 -767
- package/dist/content/content/skills/mobile-design/mobile-testing.md +0 -356
- package/dist/content/content/skills/mobile-design/mobile-typography.md +0 -433
- package/dist/content/content/skills/mobile-design/platform-android.md +0 -666
- package/dist/content/content/skills/mobile-design/platform-ios.md +0 -561
- package/dist/content/content/skills/mobile-design/scripts/mobile_audit.py +0 -670
- package/dist/content/content/skills/mobile-design/touch-psychology.md +0 -537
- package/dist/content/content/skills/nextjs-best-practices/SKILL.md +0 -203
- package/dist/content/content/skills/nodejs-best-practices/SKILL.md +0 -333
- package/dist/content/content/skills/parallel-agents/SKILL.md +0 -175
- package/dist/content/content/skills/performance-profiling/SKILL.md +0 -143
- package/dist/content/content/skills/performance-profiling/scripts/lighthouse_audit.py +0 -76
- package/dist/content/content/skills/plan-writing/SKILL.md +0 -152
- package/dist/content/content/skills/powershell-windows/SKILL.md +0 -167
- package/dist/content/content/skills/python-patterns/SKILL.md +0 -441
- package/dist/content/content/skills/react-patterns/SKILL.md +0 -198
- package/dist/content/content/skills/red-team-tactics/SKILL.md +0 -199
- package/dist/content/content/skills/seo-fundamentals/SKILL.md +0 -129
- package/dist/content/content/skills/seo-fundamentals/scripts/seo_checker.py +0 -219
- package/dist/content/content/skills/server-management/SKILL.md +0 -161
- package/dist/content/content/skills/systematic-debugging/SKILL.md +0 -109
- package/dist/content/content/skills/tailwind-patterns/SKILL.md +0 -269
- package/dist/content/content/skills/tdd-workflow/SKILL.md +0 -149
- package/dist/content/content/skills/testing-patterns/SKILL.md +0 -178
- package/dist/content/content/skills/testing-patterns/scripts/test_runner.py +0 -219
- package/dist/content/content/skills/vulnerability-scanner/SKILL.md +0 -276
- package/dist/content/content/skills/vulnerability-scanner/checklists.md +0 -121
- package/dist/content/content/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/dist/content/content/skills/webapp-testing/SKILL.md +0 -187
- package/dist/content/content/skills/webapp-testing/scripts/playwright_runner.py +0 -173
- package/dist/content/content/specialists/Especialista em Acessibilidade.md +0 -266
- package/dist/content/content/specialists/Especialista em An/303/241lise de Testes.md" +0 -434
- package/dist/content/content/specialists/Especialista em Arquitetura Avan/303/247ada.md" +0 -358
- package/dist/content/content/specialists/Especialista em Arquitetura de Software.md +0 -177
- package/dist/content/content/specialists/Especialista em Banco de Dados.md +0 -260
- package/dist/content/content/specialists/Especialista em Contrato de API.md +0 -172
- package/dist/content/content/specialists/Especialista em Dados e Analytics com IA.md +0 -246
- package/dist/content/content/specialists/Especialista em Debugging e Troubleshooting.md +0 -191
- package/dist/content/content/specialists/Especialista em Desenvolvimento Frontend.md +0 -477
- package/dist/content/content/specialists/Especialista em Desenvolvimento Mobile.md +0 -241
- package/dist/content/content/specialists/Especialista em Desenvolvimento e Vibe Coding Estruturado.md +0 -417
- package/dist/content/content/specialists/Especialista em DevOps e Infraestrutura.md +0 -294
- package/dist/content/content/specialists/Especialista em Documenta/303/247/303/243o T/303/251cnica.md" +0 -227
- package/dist/content/content/specialists/Especialista em Engenharia de Requisitos com IA.md +0 -299
- package/dist/content/content/specialists/Especialista em Explora/303/247/303/243o de Codebase.md" +0 -179
- package/dist/content/content/specialists/Especialista em Gest/303/243o de Produto.md" +0 -179
- package/dist/content/content/specialists/Especialista em Migra/303/247/303/243o e Moderniza/303/247/303/243o.md" +0 -410
- package/dist/content/content/specialists/Especialista em Modelagem e Arquitetura de Dom/303/255nio com IA.md" +0 -248
- package/dist/content/content/specialists/Especialista em Observabilidade.md +0 -415
- package/dist/content/content/specialists/Especialista em Performance e Escalabilidade.md +0 -373
- package/dist/content/content/specialists/Especialista em Plano de Execu/303/247/303/243o com IA.md" +0 -341
- package/dist/content/content/specialists/Especialista em Prototipagem R/303/241pida com Google Stitch.md" +0 -419
- package/dist/content/content/specialists/Especialista em Seguran/303/247a da Informa/303/247/303/243o.md" +0 -508
- package/dist/content/content/specialists/Especialista em UX Design.md +0 -453
- package/dist/content/content/specialists/INDEX.md +0 -43
- package/dist/content/content/templates/PRD.md +0 -165
- package/dist/content/content/templates/README.md +0 -65
- package/dist/content/content/templates/adr.md +0 -103
- package/dist/content/content/templates/arquitetura.md +0 -279
- package/dist/content/content/templates/backlog.md +0 -185
- package/dist/content/content/templates/checklist-seguranca.md +0 -180
- package/dist/content/content/templates/contexto.md +0 -120
- package/dist/content/content/templates/criterios-aceite.md +0 -99
- package/dist/content/content/templates/design-banco.md +0 -270
- package/dist/content/content/templates/design-doc.md +0 -240
- package/dist/content/content/templates/feature.md +0 -88
- package/dist/content/content/templates/historia-backend.md +0 -84
- package/dist/content/content/templates/historia-frontend.md +0 -75
- package/dist/content/content/templates/historia-usuario.md +0 -125
- package/dist/content/content/templates/mapa-navegacao.md +0 -133
- package/dist/content/content/templates/matriz-rastreabilidade.md +0 -121
- package/dist/content/content/templates/modelo-dominio.md +0 -219
- package/dist/content/content/templates/plano-testes.md +0 -199
- package/dist/content/content/templates/prototipo-stitch.md +0 -138
- package/dist/content/content/templates/requisitos.md +0 -162
- package/dist/content/content/templates/slo-sli.md +0 -197
- package/dist/content/content/workflows/README-MCP.md +0 -363
- package/dist/content/content/workflows/brainstorm.md +0 -113
- package/dist/content/content/workflows/create.md +0 -59
- package/dist/content/content/workflows/debug.md +0 -103
- package/dist/content/content/workflows/deploy.md +0 -176
- package/dist/content/content/workflows/enhance.md +0 -63
- package/dist/content/content/workflows/mcp-debug.md +0 -506
- package/dist/content/content/workflows/mcp-feature.md +0 -385
- package/dist/content/content/workflows/mcp-gate.md +0 -413
- package/dist/content/content/workflows/mcp-next.md +0 -388
- package/dist/content/content/workflows/mcp-refactor.md +0 -600
- package/dist/content/content/workflows/mcp-start.md +0 -304
- package/dist/content/content/workflows/mcp-status.md +0 -400
- package/dist/content/content/workflows/orchestrate.md +0 -237
- package/dist/content/content/workflows/plan.md +0 -89
- package/dist/content/content/workflows/preview.md +0 -81
- package/dist/content/content/workflows/status.md +0 -86
- package/dist/content/content/workflows/test.md +0 -144
- package/dist/content/content/workflows/ui-ux-pro-max.md +0 -296
|
@@ -1,368 +1,368 @@
|
|
|
1
|
-
# Guia de Multi-tenancy
|
|
2
|
-
|
|
3
|
-
> **Prioridade**: 🟡 MÉDIA
|
|
4
|
-
> **Aplicável a**: SaaS, plataformas com múltiplos clientes/organizações
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## O que é Multi-tenancy?
|
|
9
|
-
|
|
10
|
-
Multi-tenancy é uma arquitetura onde uma única instância de software serve múltiplos clientes (tenants) com isolamento de dados.
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
┌─────────────────────────────────────────────────────────┐
|
|
14
|
-
│ Aplicação SaaS │
|
|
15
|
-
├─────────────────────────────────────────────────────────┤
|
|
16
|
-
│ Tenant A │ Tenant B │ Tenant C │ Tenant D │
|
|
17
|
-
│ (Empresa X)│ (Empresa Y) │ (Startup Z)│ (Corp W) │
|
|
18
|
-
└─────────────────────────────────────────────────────────┘
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Modelos de Isolamento
|
|
24
|
-
|
|
25
|
-
### 1. Database per Tenant
|
|
26
|
-
|
|
27
|
-
Cada tenant tem seu próprio banco de dados.
|
|
28
|
-
|
|
29
|
-
```mermaid
|
|
30
|
-
graph TD
|
|
31
|
-
App[Aplicação] --> DB1[(Tenant A DB)]
|
|
32
|
-
App --> DB2[(Tenant B DB)]
|
|
33
|
-
App --> DB3[(Tenant C DB)]
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
| Prós | Contras |
|
|
37
|
-
|------|---------|
|
|
38
|
-
| Isolamento máximo | Maior custo de infra |
|
|
39
|
-
| Fácil backups por tenant | Complexidade operacional |
|
|
40
|
-
| Boa para compliance | Migrations em muitos DBs |
|
|
41
|
-
| Customização por tenant | Não escala para muitos tenants |
|
|
42
|
-
|
|
43
|
-
**Usar quando**: Enterprise customers, compliance rígido (HIPAA, PCI), <100 tenants
|
|
44
|
-
|
|
45
|
-
### 2. Schema per Tenant
|
|
46
|
-
|
|
47
|
-
Um banco, mas schemas separados por tenant.
|
|
48
|
-
|
|
49
|
-
```mermaid
|
|
50
|
-
graph TD
|
|
51
|
-
App[Aplicação] --> DB[(Database)]
|
|
52
|
-
DB --> S1[schema_tenant_a]
|
|
53
|
-
DB --> S2[schema_tenant_b]
|
|
54
|
-
DB --> S3[schema_tenant_c]
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
| Prós | Contras |
|
|
58
|
-
|------|---------|
|
|
59
|
-
| Bom isolamento | Migrations por schema |
|
|
60
|
-
| Mais barato que DB separado | Limite de schemas |
|
|
61
|
-
| Fácil backup por tenant | Consultas cross-tenant complexas |
|
|
62
|
-
|
|
63
|
-
**Usar quando**: Poucas centenas de tenants, isolamento importante
|
|
64
|
-
|
|
65
|
-
### 3. Row-Level Security (Shared Database)
|
|
66
|
-
|
|
67
|
-
Todos os tenants na mesma tabela, filtrados por tenant_id.
|
|
68
|
-
|
|
69
|
-
```sql
|
|
70
|
-
-- Todas as tabelas têm tenant_id
|
|
71
|
-
CREATE TABLE orders (
|
|
72
|
-
id UUID PRIMARY KEY,
|
|
73
|
-
tenant_id UUID NOT NULL,
|
|
74
|
-
customer_name VARCHAR(255),
|
|
75
|
-
...
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
CREATE INDEX idx_orders_tenant ON orders(tenant_id);
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
| Prós | Contras |
|
|
82
|
-
|------|---------|
|
|
83
|
-
| Escala para milhares de tenants | Risco de vazamento de dados |
|
|
84
|
-
| Operação simples | Queries precisam sempre filtrar |
|
|
85
|
-
| Migrations únicas | Backup por tenant é complexo |
|
|
86
|
-
| Menor custo | Menos isolamento de performance |
|
|
87
|
-
|
|
88
|
-
**Usar quando**: Muitos tenants pequenos (1000+), dados similares, startups
|
|
89
|
-
|
|
90
|
-
### 4. Híbrido
|
|
91
|
-
|
|
92
|
-
Tenants pequenos compartilham, grandes têm DB próprio.
|
|
93
|
-
|
|
94
|
-
```mermaid
|
|
95
|
-
graph TD
|
|
96
|
-
App[Aplicação] --> DB1[(Shared DB)]
|
|
97
|
-
App --> DB2[(Enterprise A DB)]
|
|
98
|
-
App --> DB3[(Enterprise B DB)]
|
|
99
|
-
DB1 --> T1[tenant_1..99]
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Usar quando**: Freemium + Enterprise, mix de necessidades
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Implementação: Row-Level Security
|
|
107
|
-
|
|
108
|
-
### PostgreSQL RLS
|
|
109
|
-
|
|
110
|
-
```sql
|
|
111
|
-
-- Habilitar RLS
|
|
112
|
-
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
|
113
|
-
|
|
114
|
-
-- Policy: usuários só veem dados do seu tenant
|
|
115
|
-
CREATE POLICY tenant_isolation ON orders
|
|
116
|
-
FOR ALL
|
|
117
|
-
USING (tenant_id = current_setting('app.current_tenant')::uuid);
|
|
118
|
-
|
|
119
|
-
-- No código, antes de cada requisição:
|
|
120
|
-
-- SET app.current_tenant = 'tenant-uuid';
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Middleware de Tenant (Node.js)
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
// middleware/tenantContext.ts
|
|
127
|
-
import { AsyncLocalStorage } from 'async_hooks';
|
|
128
|
-
|
|
129
|
-
interface TenantContext {
|
|
130
|
-
tenantId: string;
|
|
131
|
-
tenantConfig?: TenantConfig;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export const tenantStorage = new AsyncLocalStorage<TenantContext>();
|
|
135
|
-
|
|
136
|
-
export function tenantMiddleware(req, res, next) {
|
|
137
|
-
// Extrair tenant de: subdomain, header, JWT, etc.
|
|
138
|
-
const tenantId = extractTenantId(req);
|
|
139
|
-
|
|
140
|
-
if (!tenantId) {
|
|
141
|
-
return res.status(400).json({ error: 'Tenant not identified' });
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
tenantStorage.run({ tenantId }, () => {
|
|
145
|
-
// Setar no Prisma/TypeORM para RLS
|
|
146
|
-
db.$executeRaw`SET app.current_tenant = ${tenantId}`;
|
|
147
|
-
next();
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function extractTenantId(req): string | null {
|
|
152
|
-
// Opção 1: Subdomain (tenant1.app.com)
|
|
153
|
-
const subdomain = req.hostname.split('.')[0];
|
|
154
|
-
if (subdomain !== 'www' && subdomain !== 'app') {
|
|
155
|
-
return getTenantIdBySubdomain(subdomain);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Opção 2: Header
|
|
159
|
-
if (req.headers['x-tenant-id']) {
|
|
160
|
-
return req.headers['x-tenant-id'];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Opção 3: JWT claim
|
|
164
|
-
if (req.user?.tenantId) {
|
|
165
|
-
return req.user.tenantId;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Helper para acessar tenant em qualquer lugar
|
|
172
|
-
export function getCurrentTenant(): TenantContext {
|
|
173
|
-
const context = tenantStorage.getStore();
|
|
174
|
-
if (!context) throw new Error('No tenant context');
|
|
175
|
-
return context;
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Repository Pattern com Tenant Scope
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
// repositories/BaseRepository.ts
|
|
183
|
-
import { getCurrentTenant } from '../middleware/tenantContext';
|
|
184
|
-
|
|
185
|
-
export abstract class BaseRepository<T> {
|
|
186
|
-
protected abstract tableName: string;
|
|
187
|
-
|
|
188
|
-
async findAll(): Promise<T[]> {
|
|
189
|
-
const { tenantId } = getCurrentTenant();
|
|
190
|
-
return db.query(
|
|
191
|
-
`SELECT * FROM ${this.tableName} WHERE tenant_id = $1`,
|
|
192
|
-
[tenantId]
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async findById(id: string): Promise<T | null> {
|
|
197
|
-
const { tenantId } = getCurrentTenant();
|
|
198
|
-
return db.queryOne(
|
|
199
|
-
`SELECT * FROM ${this.tableName} WHERE id = $1 AND tenant_id = $2`,
|
|
200
|
-
[id, tenantId]
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async create(data: Omit<T, 'id' | 'tenant_id'>): Promise<T> {
|
|
205
|
-
const { tenantId } = getCurrentTenant();
|
|
206
|
-
return db.insert(this.tableName, { ...data, tenant_id: tenantId });
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Uso
|
|
211
|
-
class OrderRepository extends BaseRepository<Order> {
|
|
212
|
-
tableName = 'orders';
|
|
213
|
-
|
|
214
|
-
async findByStatus(status: string): Promise<Order[]> {
|
|
215
|
-
const { tenantId } = getCurrentTenant();
|
|
216
|
-
return db.query(
|
|
217
|
-
`SELECT * FROM orders WHERE status = $1 AND tenant_id = $2`,
|
|
218
|
-
[status, tenantId]
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
## Identificação de Tenant
|
|
227
|
-
|
|
228
|
-
| Método | Exemplo | Prós | Contras |
|
|
229
|
-
|--------|---------|------|---------|
|
|
230
|
-
| **Subdomain** | `acme.app.com` | Óbvio para usuário | DNS/SSL por tenant |
|
|
231
|
-
| **Path** | `app.com/acme/...` | Simples | Polui URLs |
|
|
232
|
-
| **Header** | `X-Tenant-ID` | Limpo | Só para APIs |
|
|
233
|
-
| **JWT Claim** | `{ tenantId: '...' }` | Seguro, autenticado | Precisa de auth |
|
|
234
|
-
| **Query Param** | `?tenant=acme` | Fácil testar | Fácil vazar |
|
|
235
|
-
|
|
236
|
-
**Recomendação**: Subdomain para apps, Header/JWT para APIs.
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
## Customização por Tenant
|
|
241
|
-
|
|
242
|
-
### Configurações
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
interface TenantConfig {
|
|
246
|
-
id: string;
|
|
247
|
-
name: string;
|
|
248
|
-
subdomain: string;
|
|
249
|
-
plan: 'free' | 'pro' | 'enterprise';
|
|
250
|
-
features: {
|
|
251
|
-
maxUsers: number;
|
|
252
|
-
customBranding: boolean;
|
|
253
|
-
ssoEnabled: boolean;
|
|
254
|
-
apiAccess: boolean;
|
|
255
|
-
};
|
|
256
|
-
branding?: {
|
|
257
|
-
logo: string;
|
|
258
|
-
primaryColor: string;
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Cache de config por tenant
|
|
263
|
-
const tenantConfigCache = new Map<string, TenantConfig>();
|
|
264
|
-
|
|
265
|
-
async function getTenantConfig(tenantId: string): Promise<TenantConfig> {
|
|
266
|
-
if (tenantConfigCache.has(tenantId)) {
|
|
267
|
-
return tenantConfigCache.get(tenantId)!;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const config = await db.tenants.findById(tenantId);
|
|
271
|
-
tenantConfigCache.set(tenantId, config);
|
|
272
|
-
return config;
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Feature Flags por Tenant
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
async function hasFeature(feature: string): Promise<boolean> {
|
|
280
|
-
const { tenantId } = getCurrentTenant();
|
|
281
|
-
const config = await getTenantConfig(tenantId);
|
|
282
|
-
return config.features[feature] === true;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Uso
|
|
286
|
-
if (await hasFeature('ssoEnabled')) {
|
|
287
|
-
// Mostrar opções de SSO
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Segurança
|
|
294
|
-
|
|
295
|
-
### Checklist de Isolamento
|
|
296
|
-
|
|
297
|
-
- [ ] Todas as queries filtram por tenant_id
|
|
298
|
-
- [ ] Índices incluem tenant_id
|
|
299
|
-
- [ ] Uploads/Storage segregados por tenant
|
|
300
|
-
- [ ] Logs incluem tenant para auditoria
|
|
301
|
-
- [ ] Rate limiting por tenant
|
|
302
|
-
- [ ] Testes verificam isolamento
|
|
303
|
-
|
|
304
|
-
### Testes de Isolamento
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
describe('Tenant Isolation', () => {
|
|
308
|
-
it('should not access data from other tenants', async () => {
|
|
309
|
-
// Setup: criar dados em dois tenants
|
|
310
|
-
await asTenant('tenant-a', async () => {
|
|
311
|
-
await orderRepo.create({ product: 'A' });
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
await asTenant('tenant-b', async () => {
|
|
315
|
-
await orderRepo.create({ product: 'B' });
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// Verificar isolamento
|
|
319
|
-
await asTenant('tenant-a', async () => {
|
|
320
|
-
const orders = await orderRepo.findAll();
|
|
321
|
-
expect(orders.every(o => o.tenant_id === 'tenant-a')).toBe(true);
|
|
322
|
-
expect(orders.find(o => o.product === 'B')).toBeUndefined();
|
|
323
|
-
});
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
## Migrations Multi-tenant
|
|
331
|
-
|
|
332
|
-
### Para Shared Database
|
|
333
|
-
|
|
334
|
-
```sql
|
|
335
|
-
-- Migration normal - aplica para todos
|
|
336
|
-
ALTER TABLE orders ADD COLUMN priority INT DEFAULT 0;
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Para Schema per Tenant
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
# Script para aplicar migration em todos os schemas
|
|
343
|
-
for schema in $(psql -t -c "SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'tenant_%'"); do
|
|
344
|
-
psql -c "SET search_path TO $schema; -- migration SQL here;"
|
|
345
|
-
done
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
---
|
|
349
|
-
|
|
350
|
-
## Checklist de Implementação
|
|
351
|
-
|
|
352
|
-
- [ ] Modelo de isolamento escolhido e documentado
|
|
353
|
-
- [ ] Middleware de identificação de tenant
|
|
354
|
-
- [ ] Todas as queries incluem tenant_id
|
|
355
|
-
- [ ] Testes de isolamento automatizados
|
|
356
|
-
- [ ] Config/features por tenant
|
|
357
|
-
- [ ] Rate limiting por tenant
|
|
358
|
-
- [ ] Logs e métricas por tenant
|
|
359
|
-
- [ ] Backup/restore por tenant (se necessário)
|
|
360
|
-
- [ ] Provisioning de novo tenant automatizado
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## Referências
|
|
365
|
-
|
|
366
|
-
- [Multi-tenancy Patterns (Microsoft)](https://docs.microsoft.com/en-us/azure/architecture/guide/multitenant/overview)
|
|
367
|
-
- [PostgreSQL Row-Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
|
|
368
|
-
- [Multi-tenant SaaS Patterns (AWS)](https://aws.amazon.com/solutions/implementations/saas-tenant-isolation/)
|
|
1
|
+
# Guia de Multi-tenancy
|
|
2
|
+
|
|
3
|
+
> **Prioridade**: 🟡 MÉDIA
|
|
4
|
+
> **Aplicável a**: SaaS, plataformas com múltiplos clientes/organizações
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## O que é Multi-tenancy?
|
|
9
|
+
|
|
10
|
+
Multi-tenancy é uma arquitetura onde uma única instância de software serve múltiplos clientes (tenants) com isolamento de dados.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
┌─────────────────────────────────────────────────────────┐
|
|
14
|
+
│ Aplicação SaaS │
|
|
15
|
+
├─────────────────────────────────────────────────────────┤
|
|
16
|
+
│ Tenant A │ Tenant B │ Tenant C │ Tenant D │
|
|
17
|
+
│ (Empresa X)│ (Empresa Y) │ (Startup Z)│ (Corp W) │
|
|
18
|
+
└─────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Modelos de Isolamento
|
|
24
|
+
|
|
25
|
+
### 1. Database per Tenant
|
|
26
|
+
|
|
27
|
+
Cada tenant tem seu próprio banco de dados.
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
graph TD
|
|
31
|
+
App[Aplicação] --> DB1[(Tenant A DB)]
|
|
32
|
+
App --> DB2[(Tenant B DB)]
|
|
33
|
+
App --> DB3[(Tenant C DB)]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Prós | Contras |
|
|
37
|
+
|------|---------|
|
|
38
|
+
| Isolamento máximo | Maior custo de infra |
|
|
39
|
+
| Fácil backups por tenant | Complexidade operacional |
|
|
40
|
+
| Boa para compliance | Migrations em muitos DBs |
|
|
41
|
+
| Customização por tenant | Não escala para muitos tenants |
|
|
42
|
+
|
|
43
|
+
**Usar quando**: Enterprise customers, compliance rígido (HIPAA, PCI), <100 tenants
|
|
44
|
+
|
|
45
|
+
### 2. Schema per Tenant
|
|
46
|
+
|
|
47
|
+
Um banco, mas schemas separados por tenant.
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
graph TD
|
|
51
|
+
App[Aplicação] --> DB[(Database)]
|
|
52
|
+
DB --> S1[schema_tenant_a]
|
|
53
|
+
DB --> S2[schema_tenant_b]
|
|
54
|
+
DB --> S3[schema_tenant_c]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Prós | Contras |
|
|
58
|
+
|------|---------|
|
|
59
|
+
| Bom isolamento | Migrations por schema |
|
|
60
|
+
| Mais barato que DB separado | Limite de schemas |
|
|
61
|
+
| Fácil backup por tenant | Consultas cross-tenant complexas |
|
|
62
|
+
|
|
63
|
+
**Usar quando**: Poucas centenas de tenants, isolamento importante
|
|
64
|
+
|
|
65
|
+
### 3. Row-Level Security (Shared Database)
|
|
66
|
+
|
|
67
|
+
Todos os tenants na mesma tabela, filtrados por tenant_id.
|
|
68
|
+
|
|
69
|
+
```sql
|
|
70
|
+
-- Todas as tabelas têm tenant_id
|
|
71
|
+
CREATE TABLE orders (
|
|
72
|
+
id UUID PRIMARY KEY,
|
|
73
|
+
tenant_id UUID NOT NULL,
|
|
74
|
+
customer_name VARCHAR(255),
|
|
75
|
+
...
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
CREATE INDEX idx_orders_tenant ON orders(tenant_id);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Prós | Contras |
|
|
82
|
+
|------|---------|
|
|
83
|
+
| Escala para milhares de tenants | Risco de vazamento de dados |
|
|
84
|
+
| Operação simples | Queries precisam sempre filtrar |
|
|
85
|
+
| Migrations únicas | Backup por tenant é complexo |
|
|
86
|
+
| Menor custo | Menos isolamento de performance |
|
|
87
|
+
|
|
88
|
+
**Usar quando**: Muitos tenants pequenos (1000+), dados similares, startups
|
|
89
|
+
|
|
90
|
+
### 4. Híbrido
|
|
91
|
+
|
|
92
|
+
Tenants pequenos compartilham, grandes têm DB próprio.
|
|
93
|
+
|
|
94
|
+
```mermaid
|
|
95
|
+
graph TD
|
|
96
|
+
App[Aplicação] --> DB1[(Shared DB)]
|
|
97
|
+
App --> DB2[(Enterprise A DB)]
|
|
98
|
+
App --> DB3[(Enterprise B DB)]
|
|
99
|
+
DB1 --> T1[tenant_1..99]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Usar quando**: Freemium + Enterprise, mix de necessidades
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Implementação: Row-Level Security
|
|
107
|
+
|
|
108
|
+
### PostgreSQL RLS
|
|
109
|
+
|
|
110
|
+
```sql
|
|
111
|
+
-- Habilitar RLS
|
|
112
|
+
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
|
113
|
+
|
|
114
|
+
-- Policy: usuários só veem dados do seu tenant
|
|
115
|
+
CREATE POLICY tenant_isolation ON orders
|
|
116
|
+
FOR ALL
|
|
117
|
+
USING (tenant_id = current_setting('app.current_tenant')::uuid);
|
|
118
|
+
|
|
119
|
+
-- No código, antes de cada requisição:
|
|
120
|
+
-- SET app.current_tenant = 'tenant-uuid';
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Middleware de Tenant (Node.js)
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// middleware/tenantContext.ts
|
|
127
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
128
|
+
|
|
129
|
+
interface TenantContext {
|
|
130
|
+
tenantId: string;
|
|
131
|
+
tenantConfig?: TenantConfig;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const tenantStorage = new AsyncLocalStorage<TenantContext>();
|
|
135
|
+
|
|
136
|
+
export function tenantMiddleware(req, res, next) {
|
|
137
|
+
// Extrair tenant de: subdomain, header, JWT, etc.
|
|
138
|
+
const tenantId = extractTenantId(req);
|
|
139
|
+
|
|
140
|
+
if (!tenantId) {
|
|
141
|
+
return res.status(400).json({ error: 'Tenant not identified' });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
tenantStorage.run({ tenantId }, () => {
|
|
145
|
+
// Setar no Prisma/TypeORM para RLS
|
|
146
|
+
db.$executeRaw`SET app.current_tenant = ${tenantId}`;
|
|
147
|
+
next();
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function extractTenantId(req): string | null {
|
|
152
|
+
// Opção 1: Subdomain (tenant1.app.com)
|
|
153
|
+
const subdomain = req.hostname.split('.')[0];
|
|
154
|
+
if (subdomain !== 'www' && subdomain !== 'app') {
|
|
155
|
+
return getTenantIdBySubdomain(subdomain);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Opção 2: Header
|
|
159
|
+
if (req.headers['x-tenant-id']) {
|
|
160
|
+
return req.headers['x-tenant-id'];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Opção 3: JWT claim
|
|
164
|
+
if (req.user?.tenantId) {
|
|
165
|
+
return req.user.tenantId;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Helper para acessar tenant em qualquer lugar
|
|
172
|
+
export function getCurrentTenant(): TenantContext {
|
|
173
|
+
const context = tenantStorage.getStore();
|
|
174
|
+
if (!context) throw new Error('No tenant context');
|
|
175
|
+
return context;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Repository Pattern com Tenant Scope
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// repositories/BaseRepository.ts
|
|
183
|
+
import { getCurrentTenant } from '../middleware/tenantContext';
|
|
184
|
+
|
|
185
|
+
export abstract class BaseRepository<T> {
|
|
186
|
+
protected abstract tableName: string;
|
|
187
|
+
|
|
188
|
+
async findAll(): Promise<T[]> {
|
|
189
|
+
const { tenantId } = getCurrentTenant();
|
|
190
|
+
return db.query(
|
|
191
|
+
`SELECT * FROM ${this.tableName} WHERE tenant_id = $1`,
|
|
192
|
+
[tenantId]
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async findById(id: string): Promise<T | null> {
|
|
197
|
+
const { tenantId } = getCurrentTenant();
|
|
198
|
+
return db.queryOne(
|
|
199
|
+
`SELECT * FROM ${this.tableName} WHERE id = $1 AND tenant_id = $2`,
|
|
200
|
+
[id, tenantId]
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async create(data: Omit<T, 'id' | 'tenant_id'>): Promise<T> {
|
|
205
|
+
const { tenantId } = getCurrentTenant();
|
|
206
|
+
return db.insert(this.tableName, { ...data, tenant_id: tenantId });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Uso
|
|
211
|
+
class OrderRepository extends BaseRepository<Order> {
|
|
212
|
+
tableName = 'orders';
|
|
213
|
+
|
|
214
|
+
async findByStatus(status: string): Promise<Order[]> {
|
|
215
|
+
const { tenantId } = getCurrentTenant();
|
|
216
|
+
return db.query(
|
|
217
|
+
`SELECT * FROM orders WHERE status = $1 AND tenant_id = $2`,
|
|
218
|
+
[status, tenantId]
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Identificação de Tenant
|
|
227
|
+
|
|
228
|
+
| Método | Exemplo | Prós | Contras |
|
|
229
|
+
|--------|---------|------|---------|
|
|
230
|
+
| **Subdomain** | `acme.app.com` | Óbvio para usuário | DNS/SSL por tenant |
|
|
231
|
+
| **Path** | `app.com/acme/...` | Simples | Polui URLs |
|
|
232
|
+
| **Header** | `X-Tenant-ID` | Limpo | Só para APIs |
|
|
233
|
+
| **JWT Claim** | `{ tenantId: '...' }` | Seguro, autenticado | Precisa de auth |
|
|
234
|
+
| **Query Param** | `?tenant=acme` | Fácil testar | Fácil vazar |
|
|
235
|
+
|
|
236
|
+
**Recomendação**: Subdomain para apps, Header/JWT para APIs.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Customização por Tenant
|
|
241
|
+
|
|
242
|
+
### Configurações
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
interface TenantConfig {
|
|
246
|
+
id: string;
|
|
247
|
+
name: string;
|
|
248
|
+
subdomain: string;
|
|
249
|
+
plan: 'free' | 'pro' | 'enterprise';
|
|
250
|
+
features: {
|
|
251
|
+
maxUsers: number;
|
|
252
|
+
customBranding: boolean;
|
|
253
|
+
ssoEnabled: boolean;
|
|
254
|
+
apiAccess: boolean;
|
|
255
|
+
};
|
|
256
|
+
branding?: {
|
|
257
|
+
logo: string;
|
|
258
|
+
primaryColor: string;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Cache de config por tenant
|
|
263
|
+
const tenantConfigCache = new Map<string, TenantConfig>();
|
|
264
|
+
|
|
265
|
+
async function getTenantConfig(tenantId: string): Promise<TenantConfig> {
|
|
266
|
+
if (tenantConfigCache.has(tenantId)) {
|
|
267
|
+
return tenantConfigCache.get(tenantId)!;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const config = await db.tenants.findById(tenantId);
|
|
271
|
+
tenantConfigCache.set(tenantId, config);
|
|
272
|
+
return config;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Feature Flags por Tenant
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
async function hasFeature(feature: string): Promise<boolean> {
|
|
280
|
+
const { tenantId } = getCurrentTenant();
|
|
281
|
+
const config = await getTenantConfig(tenantId);
|
|
282
|
+
return config.features[feature] === true;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Uso
|
|
286
|
+
if (await hasFeature('ssoEnabled')) {
|
|
287
|
+
// Mostrar opções de SSO
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Segurança
|
|
294
|
+
|
|
295
|
+
### Checklist de Isolamento
|
|
296
|
+
|
|
297
|
+
- [ ] Todas as queries filtram por tenant_id
|
|
298
|
+
- [ ] Índices incluem tenant_id
|
|
299
|
+
- [ ] Uploads/Storage segregados por tenant
|
|
300
|
+
- [ ] Logs incluem tenant para auditoria
|
|
301
|
+
- [ ] Rate limiting por tenant
|
|
302
|
+
- [ ] Testes verificam isolamento
|
|
303
|
+
|
|
304
|
+
### Testes de Isolamento
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
describe('Tenant Isolation', () => {
|
|
308
|
+
it('should not access data from other tenants', async () => {
|
|
309
|
+
// Setup: criar dados em dois tenants
|
|
310
|
+
await asTenant('tenant-a', async () => {
|
|
311
|
+
await orderRepo.create({ product: 'A' });
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
await asTenant('tenant-b', async () => {
|
|
315
|
+
await orderRepo.create({ product: 'B' });
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Verificar isolamento
|
|
319
|
+
await asTenant('tenant-a', async () => {
|
|
320
|
+
const orders = await orderRepo.findAll();
|
|
321
|
+
expect(orders.every(o => o.tenant_id === 'tenant-a')).toBe(true);
|
|
322
|
+
expect(orders.find(o => o.product === 'B')).toBeUndefined();
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Migrations Multi-tenant
|
|
331
|
+
|
|
332
|
+
### Para Shared Database
|
|
333
|
+
|
|
334
|
+
```sql
|
|
335
|
+
-- Migration normal - aplica para todos
|
|
336
|
+
ALTER TABLE orders ADD COLUMN priority INT DEFAULT 0;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Para Schema per Tenant
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Script para aplicar migration em todos os schemas
|
|
343
|
+
for schema in $(psql -t -c "SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'tenant_%'"); do
|
|
344
|
+
psql -c "SET search_path TO $schema; -- migration SQL here;"
|
|
345
|
+
done
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Checklist de Implementação
|
|
351
|
+
|
|
352
|
+
- [ ] Modelo de isolamento escolhido e documentado
|
|
353
|
+
- [ ] Middleware de identificação de tenant
|
|
354
|
+
- [ ] Todas as queries incluem tenant_id
|
|
355
|
+
- [ ] Testes de isolamento automatizados
|
|
356
|
+
- [ ] Config/features por tenant
|
|
357
|
+
- [ ] Rate limiting por tenant
|
|
358
|
+
- [ ] Logs e métricas por tenant
|
|
359
|
+
- [ ] Backup/restore por tenant (se necessário)
|
|
360
|
+
- [ ] Provisioning de novo tenant automatizado
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Referências
|
|
365
|
+
|
|
366
|
+
- [Multi-tenancy Patterns (Microsoft)](https://docs.microsoft.com/en-us/azure/architecture/guide/multitenant/overview)
|
|
367
|
+
- [PostgreSQL Row-Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
|
|
368
|
+
- [Multi-tenant SaaS Patterns (AWS)](https://aws.amazon.com/solutions/implementations/saas-tenant-isolation/)
|