@seedgrid/ai-toolkit 0.0.0-stage → 0.3.0

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.
Files changed (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -2
  3. package/dist/adapters/claude.js +114 -0
  4. package/dist/adapters/codex.js +108 -0
  5. package/dist/adapters/index.js +17 -0
  6. package/dist/adapters/shared.js +142 -0
  7. package/dist/adapters/types.js +1 -0
  8. package/dist/cli.js +203 -0
  9. package/dist/commands/common.js +98 -0
  10. package/dist/commands/doctor.js +290 -0
  11. package/dist/commands/init.js +9 -0
  12. package/dist/commands/install.js +107 -0
  13. package/dist/commands/remove.js +54 -0
  14. package/dist/commands/review.js +127 -0
  15. package/dist/commands/status.js +73 -0
  16. package/dist/commands/update.js +8 -0
  17. package/dist/commands/validate.js +27 -0
  18. package/dist/core/apply.js +181 -0
  19. package/dist/core/blocks.js +64 -0
  20. package/dist/core/content.js +528 -0
  21. package/dist/core/env.js +40 -0
  22. package/dist/core/frontmatter.js +29 -0
  23. package/dist/core/hash.js +14 -0
  24. package/dist/core/inspect.js +51 -0
  25. package/dist/core/lock.js +124 -0
  26. package/dist/core/paths.js +65 -0
  27. package/dist/core/plan.js +242 -0
  28. package/dist/core/tools.js +62 -0
  29. package/dist/core/types.js +11 -0
  30. package/dist/core/updates.js +121 -0
  31. package/docs/arquitetura.md +80 -0
  32. package/docs/compatibilidade.md +50 -0
  33. package/docs/formato.md +155 -0
  34. package/docs/instalacao.md +105 -0
  35. package/docs/manutencao.md +115 -0
  36. package/package.json +43 -4
  37. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
  38. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
  39. package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
  40. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
  41. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
  42. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
  43. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
  44. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
  45. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
  46. package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
  47. package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
  48. package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
  49. package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
  50. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
  51. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
  52. package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
  53. package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
  54. package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
  55. package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
  56. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
  57. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
  58. package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
  59. package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
  60. package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
  61. package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
  62. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
  63. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
  64. package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
  65. package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
  66. package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
  67. package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
  68. package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
  69. package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
  70. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
  71. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
  72. package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
  73. package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
  74. package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
  75. package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
  76. package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
  77. package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
  78. package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
  79. package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
  80. package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
  81. package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
  82. package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
  83. package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
  84. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
  85. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
  86. package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
  87. package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
  88. package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
  89. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
  90. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
  91. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
  92. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
  93. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
  94. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
  95. package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
  96. package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
  97. package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
  98. package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
  99. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
  100. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
  101. package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
  102. package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
  103. package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
  104. package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
  105. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
  106. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
  107. package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
  108. package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
  109. package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
  110. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
  111. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
  112. package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
  113. package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
  114. package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
  115. package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
  116. package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
  117. package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
  118. package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
  119. package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
  120. package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
  121. package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
  122. package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
  123. package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
  124. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
  125. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
  126. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
  127. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
  128. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
  129. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
  130. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
  131. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
  132. package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
  133. package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
  134. package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
  135. package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
  136. package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
  137. package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
  138. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
  139. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
  140. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
  141. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
  142. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
  143. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
  144. package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
  145. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
  146. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
  147. package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
  148. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
  149. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
  150. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
  151. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
  152. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
  153. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
  154. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
  155. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
  156. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
  157. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
  158. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
  159. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
  160. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
  161. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
  162. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
  163. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
  164. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
  165. package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
  166. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
  167. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
  168. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
  169. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
  170. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
  171. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
  172. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
  173. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
  174. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
  175. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
  176. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
  177. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
  178. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
  179. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
  180. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
  181. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
  182. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
  183. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
  184. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
  185. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
  186. package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
  187. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
  188. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
  189. package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
  190. package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
  191. package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
  192. package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
  193. package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
  194. package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
  195. package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
  196. package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
  197. package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
  198. package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
  199. package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
  200. package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
  201. package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
  202. package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
  203. package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
  204. package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
  205. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
  206. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
  207. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
  208. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
  209. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
  210. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
  211. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
  212. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
  213. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
  214. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
  215. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
  216. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
  217. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
  218. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
  219. package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
  220. package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
  221. package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
  222. package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
  223. package/seedgridKB/SeedGrid/Versoes.md +64 -0
  224. package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
  225. package/seedgridKB/manifest.json +142 -0
@@ -0,0 +1,139 @@
1
+ ---
2
+ tags: [seedgrid, extension, login-tenancy, rust]
3
+ fonte: rust/seedgrid-rust-crate-login-tenancy
4
+ branch: main
5
+ commit: be738a2d1e
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # `seedgrid-rust-crate-login-tenancy` — porte Rust
10
+
11
+ Lado Java: [[SeedGrid/Extensions/login-tenancy/Visao-geral|Visão geral do login-tenancy (Quarkus)]] · [[SeedGrid/Extensions/login-tenancy/Configuracao|Configuração Java]]
12
+ Configuração deste crate: [[SeedGrid/Extensions/login-tenancy/Configuracao-Rust|Configuração Rust do login-tenancy]]
13
+
14
+ ## Objetivo
15
+
16
+ Porte da extensão `seedgrid-quarkus-ext-login-tenancy` (ex-`accounttenancy`): **foundation de banco único** com tenant-por-conta (Company + usuário root por CNPJ), sem subdomínio nem tenant técnico. Oferece:
17
+
18
+ - **Signup institucional** (`/public/signup*`): pedido com código de 6 dígitos por e-mail, confirmação que cria Company + usuário root (ou vincula e-mail existente), evento `SignupConfirmedEvent`.
19
+ - **SPIs de security**: audiência JWT `platform` (empresa-plataforma) / `client` (demais) e super-leitura para membros da empresa-plataforma.
20
+ - **SPIs de audit**: isolamento de leitura por `companyPublicId` e carimbo na escrita.
21
+ - **Orquestrador `assemble_all`**: migra security → audit → login-tenancy e devolve um `Router` agregado (security + signup/status + `/audit-logs` gateado por `LOG_READ`) e a OpenAPI agregada.
22
+ - PII at-rest do `signup_request` via `CryptoProvider` global do `seedgrid-privacy` (bimodal por hash).
23
+
24
+ ## Coordenadas
25
+
26
+ | Item | Valor |
27
+ |---|---|
28
+ | Diretório / pacote / lib | `rust/seedgrid-rust-crate-login-tenancy` / `seedgrid-rust-crate-login-tenancy` / `seedgrid_login_tenancy` |
29
+ | Versão | `version.workspace = true` → `2026.10.14` |
30
+ | Features | nenhuma |
31
+ | Dependências SeedGrid | `seedgrid-security`, `seedgrid-privacy`, `seedgrid-audit`, `seedgrid-resilience`, `seedgrid-billing` (`default-features = false`, só domínio/SPI) |
32
+
33
+ ## API pública
34
+
35
+ | Símbolo | Papel |
36
+ |---|---|
37
+ | `LoginTenancyConfig` (+ `from_env`), `LoginTenancyFoundationConfig`, `ModuleRegistry`, `FoundationModule` | config/fachada — ver [[SeedGrid/Extensions/login-tenancy/Configuracao-Rust\|Configuração Rust]] |
38
+ | `assemble_all(Option<PgPool>, LoginTenancyPlatformOverrides)` → `AssembledLoginTenancy { security, audit, state, router, openapi }` | montagem completa single-DB; sem pool → tudo `None` e router vazio |
39
+ | `LoginTenancyState::builder(pool, foundation)` → `.cipher`, `.cipher_from_base64_key`, `.email`, `.template`, `.password_policy`, `.jwt_issuer`, `.first_admin_email`, `.signup_confirmed_handler`, `.company_public_id_resolver`, `.build()` | estado do signup |
40
+ | `router(LoginTenancyState)` | rotas abaixo |
41
+ | `migrate(&PgPool)` / `MIGRATOR` | `0700`, `0701`, `0703`; histórico `_sqlx_migrations_login_tenancy` |
42
+ | `spi_security::{LoginTenancyAllowedCompaniesResolver, LoginTenancyJwtTokenCustomizer}` (`AUDIENCE_PLATFORM`, `AUDIENCE_CLIENT`) | SPIs para o security |
43
+ | `spi_audit::{LoginTenancyAuditReadScopeProvider, CompanyAuditMetadataContributor, CachedCompanyPublicIdResolver}` | SPIs para o audit (headers `x-seedgrid-company-id` / `x-seedgrid-all-companies`) |
44
+ | `security_gate::{SecurityAuditAuthorizer, FixedAuditStateResolver, inject_trusted_company_scope_middleware}` | auth da leitura de auditoria |
45
+ | `ratelimit::signup_*_rate_limit()` | fábricas `SeedGridRateLimit` (o host aplica) |
46
+ | `openapi()` | spec utoipa |
47
+
48
+ ## Endpoints (Confirmado em `src/routes.rs`)
49
+
50
+ | Método | Path | Observação |
51
+ |---|---|---|
52
+ | POST | `/public/signup` | 202; recusa CNPJ duplicado (409) |
53
+ | GET | `/public/signup/email-exists` | — |
54
+ | POST | `/public/signup/confirm-email` | cria Company + root |
55
+ | POST | `/public/signup/resend-email` | — |
56
+ | GET | `/public/signup/cnpj-status` | — |
57
+ | GET | `/public/login-tenancy/status` | `{app, activeModules, bootstrap{enabled,admin}, security{jwtIssuer, firstAdminConfigured}}`; 404 se status desligado |
58
+
59
+ Via `assemble_all` também entram as rotas do security (incl. `/me/security/users` e `/me/security/roles`, servidas pelo security) e a leitura de auditoria `/audit-logs`.
60
+
61
+ ## Exemplo (Confirmado em `rust/examples/seedgrid-login-tenancy-example/src/main.rs`)
62
+
63
+ ```rust
64
+ use std::sync::Arc;
65
+ use seedgrid_login_tenancy::{assemble_all, LoginTenancyPlatformOverrides};
66
+
67
+ async fn boot(pool: sqlx::PgPool) -> Result<(), Box<dyn std::error::Error>> {
68
+ let overrides = LoginTenancyPlatformOverrides {
69
+ signup_confirmed: Some(Arc::new(MeuHandler)), // impl SignupConfirmedHandler
70
+ ..Default::default()
71
+ };
72
+ let assembled = assemble_all(Some(pool), overrides)
73
+ .await
74
+ .map_err(|e| format!("assemble_all falhou: {e}"))?;
75
+ let app = axum::Router::new().nest("/api/v1", assembled.router);
76
+ let _ = app;
77
+ Ok(())
78
+ }
79
+ ```
80
+
81
+ (`MeuHandler` é ilustrativo; o exemplo usa `LoggingSignupConfirmed`. O exemplo serve o router sem `nest`.)
82
+
83
+ ## Migrations
84
+
85
+ `0700_signup_request.sql`, `0701_privacy_search_hashes.sql`, `0703_signup_request_pending_unique_by_cnpj.sql` (não há `0702`). Rodar depois do security.
86
+
87
+ ## Testes
88
+
89
+ Unitários em `src/**` (config, error, dtos, SPIs) e `tests/foundation_it.rs` (Postgres via Testcontainers). **Não executados** nesta análise.
90
+
91
+ ## Notas de comportamento
92
+
93
+ - A orquestração de migrations e os serviços de lifecycle Quarkus (`AccountTenancyBootstrapService`, readiness) ficam com o host; as flags `bootstrap.*`/`modules.*` só aparecem no status.
94
+ - `assemble_all` não monta billing/apikeys/backup/filemanagement apesar das flags de módulo.
95
+ - O signup usa `PasswordPolicy` própria (não a do security).
96
+
97
+ ## Enums
98
+
99
+ Equivalentes Java em [[SeedGrid/Extensions/login-tenancy/Enums|Enums (Quarkus)]].
100
+
101
+ | Enum | Arquivo | Usado em | Equivalente Java |
102
+ |---|---|---|---|
103
+ | `SignupRequestStatus` | `src/models.rs` | coluna `signup_request.status`; respostas do signup | [[SeedGrid/Extensions/login-tenancy/Enums#SignupRequestStatus\|SignupRequestStatus]] |
104
+ | `CnpjSignupStatus` | `src/dtos.rs` | `GET /public/signup/cnpj-status` | [[SeedGrid/Extensions/login-tenancy/Enums#CnpjSignupStatus\|CnpjSignupStatus]] |
105
+ | `FoundationModule` | `src/config.rs` | `ModuleRegistry`; `activeModules` do status | [[SeedGrid/Extensions/login-tenancy/Enums#FoundationModule\|FoundationModule]] |
106
+ | `StateEnum` | `src/dtos.rs` | `state` do `AddressDto` do signup | `StateEnum` da lib commons (`br.com.seedgrid.commons.core.enums`) |
107
+ | `LoginTenancyError` | `src/error.rs` | erro dos serviços, resposta RFC 7807 | exceções do Java (sem enum) |
108
+
109
+ ### SignupRequestStatus
110
+
111
+ | Variante | Valor | Observação |
112
+ |---|---|---|
113
+ | `PendingEmailVerification` | `PENDING_EMAIL_VERIFICATION` | gravado no signup e no reenvio |
114
+ | `Confirmed` | `CONFIRMED` | gravado em `confirm-email` |
115
+
116
+ Serde `SCREAMING_SNAKE_CASE` (Serialize e Deserialize); `as_db_str()` / `from_db_str()`. **`from_db_str` é tolerante**: qualquer string diferente de `CONFIRMED` vira `PendingEmailVerification`. Coluna `status varchar(64) not null`, sem CHECK (`migrations/0700_signup_request.sql`). Java: mesmos 2 valores.
117
+
118
+ ### CnpjSignupStatus
119
+
120
+ `Available` → `AVAILABLE`, `Registered` → `REGISTERED`, `PendingConfirmation` → `PENDING_CONFIRMATION` (serde `SCREAMING_SNAKE_CASE`, só `Serialize`; não persistido). `pendingEmailMasked` só vem em `PENDING_CONFIRMATION`. Java: mesmos 3 valores.
121
+
122
+ ### FoundationModule
123
+
124
+ `Billing`, `Apikeys`, `Backup`, `Filemanagement` (ordem de `FoundationModule::ALL`). `name_lower()` devolve `billing` / `apikeys` / `backup` / `filemanagement`, usado em `activeModules`. Controlado pelas envs `SEEDGRID_LOGIN_TENANCY_MODULES_<MOD>_ENABLED` ([[SeedGrid/Extensions/login-tenancy/Configuracao-Rust|Configuração Rust]]). Não é serializado nem persistido. Java: `BILLING`, `APIKEYS`, `BACKUP`, `FILEMANAGEMENT`, os mesmos 4 valores.
125
+
126
+ ### StateEnum
127
+
128
+ 27 UFs na ordem do Java (`AC AL AP AM BA CE DF ES GO MA MT MS MG PA PB PR PE PI RJ RN RS RO RR SC SP SE TO`); as variantes Rust são `Ac`, `Al`, ... Serializa como **sigla**; desserializa sigla (sem diferenciar caixa) **ou nome completo** do estado (`from_json`). Valor inválido gera erro de bind, respondido como 400 `Dados invalidos`. `signup.rs` grava `sigla()` em `addr_state`. Mesmo conjunto e ordem do `StateEnum` Java.
129
+
130
+ ### LoginTenancyError
131
+
132
+ | Variante | HTTP |
133
+ |---|---|
134
+ | `CompanyAlreadyExists`, `SignupRequestPending` | 409 |
135
+ | `SignupRequestNotFound` | 404 |
136
+ | `BadRequest` | 400 |
137
+ | `RequiredRoleMissing`, `TemplateProcessing`, `Crypto`, `Database`, `Internal` | 500 |
138
+
139
+ `type` e `title` do corpo seguem o `ProblemType` do Java (`src/error.rs`).
@@ -0,0 +1,130 @@
1
+ ---
2
+ tags: [seedgrid, extension, login-tenancy]
3
+ fonte: java/seedgrid-quarkus-ext-login-tenancy
4
+ branch: main
5
+ commit: c67581bda9
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Login-tenancy (Quarkus) — visão geral
10
+
11
+ Foundation **orquestradora** para aplicações **banco único, multi-empresa (pooled)**: um só PostgreSQL compartilhado por N companies, com isolamento **lógico** (escopo do token + providers SPI). Uma única dependência traz e "fia" os módulos de foundation da v1 (security, audit, billing-core, backup, apikeys, filemanagement, privacy, resilience), orquestra as migrations por módulo, coordena o bootstrap, expõe signup institucional (empresa + usuário root), status técnico e readiness. Não existe `seedgrid.login-tenancy.enabled`: a presença da dependência ativa o baseline.
12
+
13
+ - Configuração: [[SeedGrid/Extensions/login-tenancy/Configuracao|Configuração do login-tenancy]]
14
+ - Exemplos: [[SeedGrid/Extensions/login-tenancy/Exemplos|Exemplos do login-tenancy]]
15
+ - Enums: [[SeedGrid/Extensions/login-tenancy/Enums|Enums do login-tenancy]]
16
+ - Porte Rust (crate `seedgrid-rust-crate-login-tenancy`): [[SeedGrid/Extensions/login-tenancy/Rust|Porte Rust]]
17
+ - Alternativa com isolamento físico por tenant: [[SeedGrid/Extensions/subdomain-tenancy/Visao-geral|subdomain-tenancy]] (mutuamente exclusivas, segundo o README).
18
+
19
+ ## Módulos Maven e coordenadas (Confirmado — `pom.xml`)
20
+
21
+ | Módulo | groupId | artifactId | Versão |
22
+ |---|---|---|---|
23
+ | parent | `br.com.seedgrid` | `seedgrid-login-tenancy-parent` | `2026.10.14-1` |
24
+ | runtime | `br.com.seedgrid` | `seedgrid-login-tenancy` | `2026.10.14-1` |
25
+ | deployment | `br.com.seedgrid` | `seedgrid-login-tenancy-deployment` | `2026.10.14-1` |
26
+
27
+ Parent: `br.com.seedgrid:seedgrid-parent:2026.07.02`. Status `preview`.
28
+
29
+ ## Dependências SeedGrid (versões do `pom.xml` do parent)
30
+
31
+ | Artefato | Versão | Papel |
32
+ |---|---|---|
33
+ | `seedgrid-commons` | `2026.10.08` | embeddables `Address`/`Contact`, `ApiExceptionExtension` |
34
+ | `seedgrid-security` (+ `-deployment`) | `2026.10.14` | `Company`, `User`, `Role`, JWT, `EmailServiceInterface`, SPIs de escopo — ver [[SeedGrid/Extensions/security/Visao-geral|security]] |
35
+ | `seedgrid-audit-core`, `seedgrid-audit-postgresql` (`seedgrid-audit-mongodb` só gerenciado) | `2026.09.25` | auditoria e SPIs `AuditMetadataContributor`/`AuditReadScopeProvider` |
36
+ | `seedgrid-backup` (+ `-deployment`) | `2026.10.09` | backup |
37
+ | `seedgrid-billing-core` (+ `-deployment`) | `2026.10.14-1` | cobrança agnóstica; `AccountProvisioningService` |
38
+ | `seedgrid-apikeys` (+ `-deployment`) | `2026.10.14` | ver [[SeedGrid/Extensions/apikeys/Visao-geral|apikeys]] |
39
+ | `seedgrid-notification` (+ `-deployment`) | `2026.10.15` | catálogo de eventos, regras, outbox e envio por e-mail/WhatsApp; vem transitivamente, o host não precisa declará-la — ver [[SeedGrid/Extensions/notification/Visao-geral|notification]] |
40
+ | `seedgrid-filemanagement` | `2026.07.08` | arquivos |
41
+ | `seedgrid-privacy` | `2026.07.27` | mascaramento/criptografia de PII |
42
+ | `seedgrid-resilience-core` | `2026.10.13` | `@SeedGridRateLimit` |
43
+
44
+ O **provider de billing** concreto (`BillingProvider`) não vem embarcado: o host precisa fornecer (ex.: `seedgrid-billing-stripe`) ou o boot falha (README; o teste usa `NoopBillingProvider`). Também empacota `quarkus-mongodb-client` como dependência opcional (README) para a auditoria MongoDB.
45
+
46
+ ## Arquitetura
47
+
48
+ ### Ordem de inicialização (Confirmado)
49
+
50
+ | Prioridade | Componente | O que faz |
51
+ |---|---|---|
52
+ | 2000 (`APPLICATION`) | `LoginTenancyMigrationService#onStart` | Flyway por módulo no datasource único (Flyway nativo do Quarkus desligado) |
53
+ | 2100 | `LoginTenancyBootstrapService#onStart` | Só coordena/loga o bootstrap de admin (delegado ao security) e os módulos ativos |
54
+ | 2500 (padrão) | `FirstAdminBootstrapService` (security) | company default + primeiro admin |
55
+
56
+ ### Migrations orquestradas (Confirmado — `LoginTenancyMigrationService`)
57
+
58
+ ```mermaid
59
+ flowchart LR
60
+ S[security<br/>flyway_schema_history_security] --> A{audit strategy = jpa?}
61
+ A -- sim --> AU[audit]
62
+ A -- não --> B
63
+ AU --> B{modules.backup}
64
+ B -- on --> BK[backup] --> BI
65
+ B -- off --> BI{modules.billing}
66
+ BI -- on --> BL[billing] --> AK
67
+ BI -- off --> AK{modules.apikeys}
68
+ AK -- on --> AP[apikeys] --> X
69
+ AK -- off --> X{ai-pricing / exchange<br/>migration.enabled}
70
+ X --> LT[login-tenancy<br/>V700-V703] --> APP["app (database.locations)<br/>flyway_schema_history"]
71
+ ```
72
+
73
+ Cada módulo usa `classpath:db/migration/<modulo>` e a tabela `flyway_schema_history_<modulo>` (`ai-pricing` → `flyway_schema_history_ai_pricing`; `login-tenancy` → `flyway_schema_history_login_tenancy`); a aplicação usa `seedgrid.login-tenancy.database.locations` (padrão `classpath:db/migration/app`) e `flyway_schema_history`. Falha em qualquer módulo lança `MigrationExecutionException` e derruba o startup.
74
+
75
+ ### Isolamento lógico por company
76
+
77
+ - `LoginTenancyAllowedCompaniesResolver` (SPI do security): memberships reais em `allowedCompanies`; membros da **default company** recebem super-leitura (`seeAll`) — usada no audit.
78
+ - `LoginTenancyLoginScopeResolver` e `LoginTenancyJwtTokenCustomizer` (SPIs do security): escopo do login e claim `audience` = `platform` se a empresa corrente é a default company (comparação por CNPJ via `DefaultCompanyConfig`), senão `client`.
79
+ - `CompanyAuditMetadataContributor` carimba `companyPublicId` na escrita do audit; `LoginTenancyAuditReadScopeProvider` força o filtro na leitura (sem contexto ⇒ nega).
80
+ - `LoginTenancyAccountUserActivationMailer` (SPI `AccountUserActivationMailer` do security): e-mail de ativação quando admin de empresa cria usuário em `/me/security/users`.
81
+ - `LoginTenancyBillingProvisioner`: ao `SignupConfirmedEvent` (AFTER_SUCCESS, `REQUIRES_NEW`) garante conta de billing com trial, se `modules.billing.enabled`.
82
+
83
+ ## API pública
84
+
85
+ ### REST (Confirmado — `RestControllerPath`)
86
+
87
+ | Método | Path | Rate limit (`configKey`, padrão) | Descrição |
88
+ |---|---|---|---|
89
+ | `POST` | `/public/signup` | `signup`, 10/min | Cadastro institucional → `202 {status, signupRequestId, emailDelivered}`. Reaproveita solicitação pendente do mesmo CNPJ+e-mail; outro e-mail no mesmo CNPJ → `409`. E-mail existente = vinculação de nova empresa (senha ignorada). |
90
+ | `GET` | `/public/signup/email-exists?email=` | `signup-email-exists`, 10/min | `{exists}` |
91
+ | `GET` | `/public/signup/cnpj-status?cnpj=` | `signup-cnpj-status`, 10/min | `{status: AVAILABLE\|REGISTERED\|PENDING_CONFIRMATION, pendingEmailMasked}` |
92
+ | `POST` | `/public/signup/confirm-email` | `signup-confirm-email`, 10/min | `{token}` (6 dígitos, com ou sem traço) → cria `Company` + usuário root com role `ADMIN` por conta, envia boas-vindas, dispara `SignupConfirmedEvent` |
93
+ | `POST` | `/public/signup/resend-email` | `signup-resend-email`, 5/h | Gera novo código e reenvia |
94
+ | `GET` | `/public/login-tenancy/status` | — | `app`, `activeModules`, `bootstrap`, `security.jwtIssuer`, `security.firstAdminConfigured`; `404` se `foundation.status.enabled=false` |
95
+ | health | readiness `login-tenancy-foundation` | — | `Connection.isValid(2)` no datasource; UP sem tocar o banco se `foundation.health.enabled=false` |
96
+
97
+ O código de verificação **não** volta na resposta do signup (`SignupResponse`): só chega pelo e-mail.
98
+
99
+ ### Eventos, SPIs e beans
100
+
101
+ | Símbolo | Tipo | Uso |
102
+ |---|---|---|
103
+ | `br.com.seedgrid.logintenancy.dtos.SignupConfirmedEvent(cnpj, companyPublicId, corporateName, tradeName, rootEmail, representativeName)` | evento CDI | Pós-processamento de domínio no host |
104
+ | `br.com.seedgrid.logintenancy.spis.LoginTenancyTemplateProvider` | SPI (`DefaultLoginTenancyTemplateProvider` é `@DefaultBean`) | `signupConfirmation`, `signupWelcome`, `userActivation`. Override por bean ou por arquivo em `templates/logintenancy/<nome>.html` (fallback `templates/logintenancy-default/html/`) |
105
+ | `LoginTenancyConfig` / `LoginTenancyFoundationConfig` | `@ConfigMapping` / fachada CDI | ver [[SeedGrid/Extensions/login-tenancy/Configuracao|Configuração]] |
106
+ | `LoginTenancyModuleRegistry` | bean | `isActive(FoundationModule)`, `activeModules()` |
107
+ | `LoginTenancyMongoAuditDatabaseProducer` | producer `@DefaultBean` de `MongoDatabase` | registrado só se `com.mongodb.client.MongoClient` estiver no classpath (`LoginTenancyProcessor#registerMongoAuditDatabaseProducer`) |
108
+ | `LoginTenancyApiExceptionExtension` | `ApiExceptionExtension` | `SignupRequestNotFoundException`→404, `SignupRequestPendingException`→409, `RequiredRoleMissingException`→500 (`application/problem+json`) |
109
+
110
+ ## Migrations próprias
111
+
112
+ `runtime/src/main/resources/db/migration/login-tenancy/`: `V700__signup_request.sql`, `V701__privacy_search_hashes.sql`, `V702__timestamps_com_fuso.sql`, `V703__signup_request_pendente_unica_por_cnpj.sql` (faixa 700). Há um `docs/RUNBOOK-remocao-da-V704.md` (não analisado em detalhe).
113
+
114
+ ## Testes existentes (não executados)
115
+
116
+ | Teste | Cobertura |
117
+ |---|---|
118
+ | `runtime/src/test/.../LoginTenancyFoundationIT` | config com defaults, migrations por schema, company default, endpoint de status, readiness (PostgreSQL via Dev Services) |
119
+ | `.../controllers/SignupAccountRootIT` | confirmação torna o dono root da conta, não root global |
120
+ | `.../controllers/SignupBillingAccountIT` | confirmação cria conta de billing com trial |
121
+ | `.../controllers/SignupDedupIT` | reaproveitamento de pendente, conflito com outro e-mail, `emailDelivered`, `cnpj-status` |
122
+ | `.../spis/*Test` | metadata/escopo de audit, resolvedor de escopo de login, defaults de gestão de conta |
123
+ | `.../unit/LoginTenancyFoundationConfigTest`, `LoginTenancyModuleRegistryTest` | lógica da fachada e do registry |
124
+
125
+ ## Limitações
126
+
127
+ - `modules.apikeys.enabled`, `modules.backup.enabled` e `modules.filemanagement.enabled` controlam só migrations e/ou o que aparece no status — **não** removem beans/endpoints desses módulos (Confirmado: não há outro consumo). Só `modules.billing.enabled` também alimenta `seedgrid.billing.api.enabled` e o provisionamento.
128
+ - `bootstrap.admin.enabled=false` não impede o security de criar o admin se `seedgrid.security.first-admin-user.email` estiver preenchido (só gera WARN).
129
+ - Company default é sempre garantida (sem flag).
130
+ - `seeAll` é global para membros da default company.
@@ -0,0 +1,141 @@
1
+ ---
2
+ tags: [seedgrid, extension, notification, configuracao]
3
+ fonte: java/seedgrid-quarkus-ext-notification
4
+ branch: main
5
+ commit: b989a6248a
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Notification (Quarkus) — configuração
10
+
11
+ Voltar: [[SeedGrid/Extensions/notification/Visao-geral|Visão geral do notification]] · [[SeedGrid/Extensions/notification/Exemplos|Exemplos]]
12
+
13
+ ## 1. Cabeçalho
14
+
15
+ | Item | Valor |
16
+ |---|---|
17
+ | Prefixo | `seedgrid.notification` |
18
+ | Classe de config | `java/seedgrid-quarkus-ext-notification/runtime/src/main/java/br/com/seedgrid/notification/config/NotificationConfig.java` → `NotificationConfig` |
19
+ | Mecanismo | SmallRye `@ConfigMapping(prefix = "seedgrid.notification")` (sem `ConfigMappingBuildItem` no processor; descoberto pelo índice Jandex do runtime) + expressão `${seedgrid.notification.poll-interval:10s}` em `@Scheduled` |
20
+ | Fase | Runtime |
21
+ | Validação | `NotificationStartup#initialize` (StartupEvent, `@Priority(APPLICATION + 1)`) lança `IllegalArgumentException("Configuracao seedgrid.notification invalida")` se: `scope` em branco ou > 120 caracteres; `max-attempts` fora de 1–20; `batch-size` fora de 1–1000; `lease` ≤ 0; `retry-delay` ≤ 0. A aplicação **não sobe**. |
22
+
23
+ Variáveis de ambiente: a regra MicroProfile se aplica sem ambiguidade (ex.: `SEEDGRID_NOTIFICATION_MAX_ATTEMPTS`). Não há env lida diretamente no código.
24
+
25
+ ## 2. Propriedades da extension
26
+
27
+ ### Ativação e escopo
28
+
29
+ | Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
30
+ |---|---|---|---|---|---|---|---|---|---|
31
+ | `seedgrid.notification.enabled` | `boolean` | `true`/`false` | `true` | Não | `false`: o subscriber ignora eventos (não cria marcador nem entregas — mas código de evento desconhecido ainda lança erro, pois `catalog.require` vem antes) e o dispatcher não envia. Startup/migrations continuam rodando. | Pausar publicação e envio | Sobrepõe `dispatch-enabled` | Runtime | Decl.: `NotificationConfig#enabled()`. Consumo: `NotificationSubscriber#observe`, `NotificationDispatcher#drain` |
32
+ | `seedgrid.notification.dispatch-enabled` | `boolean` | `true`/`false` | `true` | Não | `false`: só o worker para; eventos continuam sendo enfileirados (fila preservada). | Pausar só o envio | Só vale com `enabled=true` | Runtime | Decl.: `NotificationConfig#dispatchEnabled()`. Consumo: `NotificationDispatcher#drain` |
33
+ | `seedgrid.notification.scope` | `String` | não vazio, ≤ 120 caracteres | `platform` | Não | Namespace fixo da instalação: separa regras, deduplicação, histórico e workers de instalações que compartilham o banco. Nunca vem do navegador. **Não** é company/tenant. | Isolamento entre instalações | Mudar o valor "esconde" regras e histórico gravados com o scope anterior (Inferência: todas as consultas filtram por scope) | Runtime | Decl.: `NotificationConfig#scope()`. Consumo: `NotificationRules`, `NotificationSubscriber`, `NotificationQueue`, `NotificationResource#deliveries`, validação em `NotificationStartup` |
34
+ | `seedgrid.notification.datasource-name` | `Optional<String>` | nome de datasource Agroal existente | — | Não | Se informado (após `trim`), as migrations usam esse datasource; se não resolver, o startup falha com `IllegalStateException`. Ausente: usa o datasource `master` se existir, senão o default. | Escolher onde rodar as migrations da notification | **Não** muda a persistence unit das entidades, que é decidida no build (`master` se houver datasource com esse nome, senão `<default>`) — ver `NotificationProcessor#registerEntities` (Inferência sobre o risco de inconsistência) | Runtime | Decl.: `NotificationConfig#datasourceName()`. Consumo: `NotificationStartup#resolveDataSource` |
35
+
36
+ ### Worker / entrega
37
+
38
+ | Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
39
+ |---|---|---|---|---|---|---|---|---|---|
40
+ | `seedgrid.notification.poll-interval` | `String` (expressão `every` do Quarkus Scheduler) | duração do scheduler (`10s`, `PT10S`...) | `10s` | Não | Intervalo do `NotificationDispatcher#drain` (`concurrentExecution = SKIP`). | Frequência do worker | Cada execução processa até `batch-size` claims | Runtime (resolvido pelo scheduler na subida) | Decl./consumo: `NotificationDispatcher#drain` — `@Scheduled(every = "${seedgrid.notification.poll-interval:10s}")`. Não está em `NotificationConfig`. |
41
+ | `seedgrid.notification.batch-size` | `int` | 1–1000 | `20` | Não | Máximo de claims por execução do worker. | Vazão | — | Runtime | Decl.: `NotificationConfig#batchSize()`. Consumo: `NotificationDispatcher#drain`; validação em `NotificationStartup` |
42
+ | `seedgrid.notification.max-attempts` | `int` | 1–20 | `5` | Não | Tentativas por entrega; ao atingir, status `FAILED` (`ATTEMPTS_EXHAUSTED` no claim ou `TRANSPORT_FAILED` na última falha). | Limite de retry | Com `retry-delay` define a janela total de retry | Runtime | Decl.: `NotificationConfig#maxAttempts()`. Consumo: `NotificationQueue#claim`, `#complete` |
43
+ | `seedgrid.notification.retry-delay` | `Duration` | > 0 | `PT30S` | Não | Base do backoff exponencial: próxima tentativa = agora + `retry-delay × 2^min(tentativas-1, 10)`. | Espaçamento entre tentativas | — | Runtime | Decl.: `NotificationConfig#retryDelay()`. Consumo: `NotificationQueue#complete` |
44
+ | `seedgrid.notification.lease` | `Duration` | > 0 | `PT5M` | Não | Prazo de posse de uma entrega em `SENDING`; depois dele outro worker pode retomá-la. | Recuperação após queda do worker | Deve exceder o timeout máximo do transporte (SMTP/WhatsApp) com margem, senão há risco de envio duplicado (`docs/ARCHITECTURE.md`) | Runtime | Decl.: `NotificationConfig#lease()`. Consumo: `NotificationQueue#claim` |
45
+
46
+ Total: **9 propriedades públicas** (8 em `NotificationConfig` + `poll-interval`).
47
+
48
+ ## 3. Propriedades de frameworks/bibliotecas usadas pela extension
49
+
50
+ | Propriedade | Por quê | Fonte |
51
+ |---|---|---|
52
+ | `quarkus.mailer.security.*` (`from`, `host`, `port`, `mock`, `timeout`, `start-tls`, credenciais/TLS) | O transporte de e-mail injeta `@MailerName("security") Mailer`. Produção precisa de `mock=false` e timeouts finitos. | `NotificationTransport`; README; `docs/ARCHITECTURE.md` |
53
+ | `seedgrid.whatsapp.api` e a configuração do provider (URL/credencial) | Envio WhatsApp via `WhatsAppApi` da extensão WhatsApp; a instância (`whatsappChannelId`) vem da regra. Ver [[SeedGrid/Extensions/whatsapp/Configuracao|configuração do whatsapp]]. | README; `integration-tests/.../application.properties` |
54
+ | `quarkus.datasource.*` / `quarkus.datasource."master".*` | Datasource das migrations e da PU (`master` preferido). | `NotificationStartup`, `NotificationProcessor` |
55
+ | `quarkus.scheduler.*` | O worker é um `@Scheduled`; nos ITs `quarkus.scheduler.start-mode=halted`. | `NotificationDispatcher` |
56
+
57
+ A extension não registra defaults de framework (sem `microprofile-config.properties`).
58
+
59
+ ## 4. Propriedades usadas só em testes
60
+
61
+ `integration-tests/src/main/resources/application.properties` e `NotificationContainers`:
62
+
63
+ | Propriedade | Valor/observação |
64
+ |---|---|
65
+ | `quarkus.datasource.db-kind` | `postgresql` |
66
+ | `quarkus.datasource.devservices.enabled` | `false` (containers próprios) |
67
+ | `quarkus.hibernate-orm.schema-management.strategy` | `none` |
68
+ | `quarkus.mailer.security.from` / `.mock` / `.start-tls` / `.timeout` | `notification@example.invalid`, `false`, `DISABLED`, `5S` |
69
+ | `quarkus.mailer.security.host` / `.port` | injetados pelo `NotificationContainers` (MailHog) |
70
+ | `quarkus.datasource.jdbc.url` / `.username` / `.password` | injetados pelo `NotificationContainers` |
71
+ | `quarkus.scheduler.start-mode` | `halted` |
72
+ | `quarkus.http.test-port` | `0` |
73
+ | `seedgrid.notification.scope` | `notification-it` |
74
+ | `seedgrid.notification.max-attempts` | `2` |
75
+ | `seedgrid.whatsapp.api` | `evolution` |
76
+ | 🔒 `seedgrid.whatsapp.evolution.api-key` | `<SEGREDO:evolution-api-key>` (valor local de teste não copiado) |
77
+ | `quarkus.rest-client.evolution.url` / `.connect-timeout` / `.read-timeout` | URL do servidor simulado; `2000` / `2000` |
78
+ | `test.mail.url` | lida por `@ConfigProperty` em `NotificationIT` (URL do MailHog) |
79
+
80
+ ## 5. Aliases, obsoletas, renomeações
81
+
82
+ - Nenhum alias. O CHANGELOG `2026.10.13` registra que a escolha da persistence unit passou a ser feita no build "sem chave de configuração que possa divergir".
83
+ - A migration antiga `V950` foi substituída por `V1000` antes da adoção (README).
84
+
85
+ ## 6. Configuração mínima
86
+
87
+ Nada em `seedgrid.notification.*` é obrigatório. É preciso configurar o transporte:
88
+
89
+ ```properties
90
+ quarkus.mailer.security.from=<REMETENTE>
91
+ quarkus.mailer.security.host=<SMTP-HOST>
92
+ quarkus.mailer.security.port=<SMTP-PORTA>
93
+ quarkus.mailer.security.mock=false
94
+ # WhatsApp (opcional): ver configuração do seedgrid-whatsapp
95
+ seedgrid.whatsapp.api=<evolution|...>
96
+ ```
97
+
98
+ ## 7. Configuração completa comentada
99
+
100
+ ```properties
101
+ # Namespace fixo da instalação (padrão: platform; não vazio, até 120 caracteres)
102
+ seedgrid.notification.scope=platform
103
+ # Liga enfileiramento e envio (padrão: true)
104
+ seedgrid.notification.enabled=true
105
+ # Liga só o worker de envio (padrão: true)
106
+ seedgrid.notification.dispatch-enabled=true
107
+ # Datasource das migrations (padrão: master se existir, senão o default)
108
+ #seedgrid.notification.datasource-name=master
109
+ # Intervalo do worker (padrão: 10s)
110
+ seedgrid.notification.poll-interval=10s
111
+ # Claims por execução (padrão: 20; 1-1000)
112
+ seedgrid.notification.batch-size=20
113
+ # Tentativas por entrega (padrão: 5; 1-20)
114
+ seedgrid.notification.max-attempts=5
115
+ # Base do backoff exponencial (padrão: PT30S; > 0)
116
+ seedgrid.notification.retry-delay=PT30S
117
+ # Posse de uma entrega pelo worker (padrão: PT5M; > 0; maior que o timeout do transporte)
118
+ seedgrid.notification.lease=PT5M
119
+
120
+ # Transporte de e-mail (mailer nomeado do security)
121
+ quarkus.mailer.security.from=<REMETENTE>
122
+ quarkus.mailer.security.host=<SMTP-HOST>
123
+ quarkus.mailer.security.port=<SMTP-PORTA>
124
+ quarkus.mailer.security.username=<USUARIO-SMTP>
125
+ quarkus.mailer.security.password=<SEGREDO:smtp-password>
126
+ quarkus.mailer.security.mock=false
127
+ quarkus.mailer.security.timeout=30S
128
+ ```
129
+
130
+ ## 8. Receitas
131
+
132
+ - **Manutenção do SMTP sem perder avisos**: `seedgrid.notification.dispatch-enabled=false` — a fila cresce; ao religar, o worker drena.
133
+ - **Desligar notificações totalmente**: `seedgrid.notification.enabled=false` (eventos publicados nesse período não são enfileirados).
134
+ - **Duas instalações no mesmo banco**: um `scope` distinto em cada uma.
135
+ - **Transporte lento**: aumente `lease` acima do timeout do transporte; ajuste `retry-delay`/`max-attempts` (com padrão 5 tentativas e 30 s, as esperas são 30 s, 60 s, 120 s, 240 s).
136
+ - **Host multi-datasource (subdomain-tenancy)**: a extension usa o datasource `master` automaticamente; `datasource-name` só se precisar de outro para as migrations.
137
+
138
+ ## 9. Dúvidas e lacunas
139
+
140
+ - `poll-interval` aceita o formato de `every` do Quarkus Scheduler; se valores como `off`/`disabled` desligam o worker depende da versão do Quarkus (Não confirmado neste repositório).
141
+ - Possível inconsistência entre `datasource-name` (migrations) e a PU escolhida no build (entidades) — Inferência, não testada.
@@ -0,0 +1,52 @@
1
+ ---
2
+ tags: [seedgrid, extension, notification, enum]
3
+ fonte: java/seedgrid-quarkus-ext-notification
4
+ branch: main
5
+ commit: b989a6248a
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Notification (Quarkus) — enums
10
+
11
+ Voltar: [[SeedGrid/Extensions/notification/Visao-geral|Visão geral do notification]] · [[SeedGrid/Extensions/notification/Configuracao|Configuração]]
12
+
13
+ ## Índice
14
+
15
+ | Enum | Pacote/arquivo | Usado em | Público? |
16
+ |---|---|---|---|
17
+ | [[#Channel]] | `br.com.seedgrid.notification.config` — `runtime/src/main/java/br/com/seedgrid/notification/config/Channel.java` | `NotificationRule#channels`, `ConditionalRecipient#channel`, corpo do `PUT /admin/notifications/events/{code}`, resposta do `GET /admin/notifications/events`, coluna `sg_notification_delivery.channel` | Sim |
18
+
19
+ O módulo `api` (`seedgrid-notification-api`) não define enums.
20
+
21
+ ## Channel
22
+
23
+ FQN: `br.com.seedgrid.notification.config.Channel`.
24
+
25
+ | Valor | Significado | Efeito / onde é tratado | Observações |
26
+ |---|---|---|---|
27
+ | `EMAIL` | Entrega por e-mail | `NotificationSubscriber` enfileira para `rule.emails()` (+ condicionais do canal); `NotificationTransport` envia com `Mailer` nomeado `security`; `RuleValidator` normaliza endereços (trim, minúsculas, validação) | Confirmado |
28
+ | `WHATSAPP` | Entrega por WhatsApp | Enfileira para `rule.phones()` (+ condicionais), com `rule.whatsappChannelId()`; `NotificationTransport` usa `WhatsAppApi#sendTextMessage`; exige telefone E.164 e instância; resposta sem `messageId` é falha | Confirmado |
29
+
30
+ - Sem campos nem métodos.
31
+ - **JSON**: nome da constante, sensível a maiúsculas (padrão Jackson): `"channels": ["EMAIL","WHATSAPP"]`; `ConditionalRecipient.channel` idem (nulo → `IllegalArgumentException` "Canal do destinatario condicional obrigatorio", devolvido como `400`). `GET /admin/notifications/events` devolve `channels: Channel.values()` (lista dos canais suportados, **não** atesta credenciais válidas).
32
+ - **Persistência**: a regra é gravada como JSON em `sg_notification_rule.rule_json`. A entrega grava `channel.name()` em `sg_notification_delivery.channel varchar(16)` com `CHECK (channel in ('EMAIL','WHATSAPP'))` (V1000) — **coerente** com as constantes. Em `NotificationTransport` o canal volta como string: valores fora de `EMAIL`/`WHATSAPP` lançam `IllegalStateException("Canal desconhecido")` (inalcançável com o CHECK).
33
+ - Adicionar uma constante exige: novo ramo no `NotificationSubscriber` (não há laço genérico), `RuleValidator` (a lista usa `c == Channel.EMAIL ? emails : phones`, tratando tudo que não é EMAIL como telefone), `NotificationTransport` e o CHECK da tabela.
34
+ - Usado em: sem propriedade de config; ver endpoints em [[SeedGrid/Extensions/notification/Visao-geral|Visão geral]].
35
+
36
+ ## Status de entrega (não é enum Java)
37
+
38
+ `sg_notification_delivery.status` é `String` com `CHECK (status in ('PENDING','SENDING','SENT','FAILED'))` e constantes literais em `NotificationSubscriber`, `NotificationQueue` e `NotificationDeliveryRepository`; aparece em `GET /admin/notifications/deliveries`. Não existe enum Java para esses valores.
39
+
40
+ ```mermaid
41
+ stateDiagram-v2
42
+ [*] --> PENDING: NotificationSubscriber (enqueue)
43
+ PENDING --> SENDING: NotificationQueue.claim (attempts+1, lease)
44
+ SENDING --> SENT: complete(success)
45
+ SENDING --> PENDING: complete(falha) e attempts < max-attempts (backoff)
46
+ SENDING --> FAILED: complete(falha) e attempts >= max-attempts
47
+ PENDING --> FAILED: claim com attempts >= max-attempts (ATTEMPTS_EXHAUSTED)
48
+ ```
49
+
50
+ ## Internos
51
+
52
+ Nenhum.
@@ -0,0 +1,141 @@
1
+ ---
2
+ tags: [seedgrid, extension, notification, exemplos]
3
+ fonte: java/seedgrid-quarkus-ext-notification
4
+ branch: main
5
+ commit: b989a6248a
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Notification (Quarkus) — exemplos
10
+
11
+ Voltar: [[SeedGrid/Extensions/notification/Visao-geral|Visão geral do notification]] · [[SeedGrid/Extensions/notification/Configuracao|Configuração]]
12
+
13
+ ## 1. Dependências
14
+
15
+ Fonte: `README.md` / poms.
16
+
17
+ ```xml
18
+ <!-- Extensão produtora: só o contrato -->
19
+ <dependency>
20
+ <groupId>br.com.seedgrid</groupId>
21
+ <artifactId>seedgrid-notification-api</artifactId>
22
+ <version>2026.10.15</version>
23
+ </dependency>
24
+
25
+ <!-- Produto que quer catálogo, API administrativa e entrega -->
26
+ <dependency>
27
+ <groupId>br.com.seedgrid</groupId>
28
+ <artifactId>seedgrid-notification</artifactId>
29
+ <version>2026.10.15</version>
30
+ </dependency>
31
+ ```
32
+
33
+ ## 2. Declarar eventos (extensão produtora)
34
+
35
+ Fonte: `README.md`; assinatura de `EventDefinition(code, group, label, description, variables, subjectTemplate, bodyTemplate)`.
36
+
37
+ ```java
38
+ import br.com.seedgrid.notification.api.EventDefinition;
39
+ import br.com.seedgrid.notification.api.NotificationCatalogContributor;
40
+ import jakarta.enterprise.context.ApplicationScoped;
41
+ import java.util.Collection;
42
+ import java.util.List;
43
+ import java.util.Set;
44
+
45
+ @ApplicationScoped
46
+ public class PricingNotifications implements NotificationCatalogContributor {
47
+ @Override
48
+ public Collection<EventDefinition> events() {
49
+ return List.of(new EventDefinition(
50
+ "ai-pricing.approval-pending", "Preços de IA", "Aprovação pendente",
51
+ "Novos preços aguardam revisão", Set.of("quantity"),
52
+ "Preços aguardando aprovação", "Há {quantity} preços para revisar."));
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## 3. Publicar dentro da transação de negócio
58
+
59
+ Fonte: `README.md`; `NotificationPublisher#publish(NotificationEvent)`; `NotificationEvent(id, code, variables)`.
60
+
61
+ ```java
62
+ import br.com.seedgrid.notification.api.NotificationEvent;
63
+ import br.com.seedgrid.notification.api.NotificationPublisher;
64
+
65
+ @Inject NotificationPublisher notifications;
66
+
67
+ @Transactional
68
+ public void proporPrecos(...) {
69
+ // ... grava a proposta ...
70
+ // id estável da ocorrência (não gerar UUID novo a cada retry)
71
+ notifications.publish(new NotificationEvent(
72
+ proposalPublicId, "ai-pricing.approval-pending", Map.of("quantity", "3")));
73
+ }
74
+ ```
75
+
76
+ Evento operacional embutido (publicável por qualquer host): código `platform.email-delivery-failed`, variáveis `recipient`, `subject`, `cause`, `accumulated` (`OperationalNotificationCatalog`).
77
+
78
+ ## 4. Configurar uma regra (admin)
79
+
80
+ Fonte: `docs/API.md`, `README.md`.
81
+
82
+ ```http
83
+ PUT /admin/notifications/events/ai-pricing.approval-pending
84
+ Content-Type: application/json
85
+ Authorization: Bearer <JWT-COM-NOTIFICATION_UPDATE>
86
+
87
+ {
88
+ "enabled": true,
89
+ "channels": ["EMAIL", "WHATSAPP"],
90
+ "emails": ["financeiro@example.com"],
91
+ "phones": ["+5511999999999"],
92
+ "whatsappChannelId": "administrativo",
93
+ "conditionalRecipients": [
94
+ {"channel": "WHATSAPP", "address": "+5511911111111", "attribute": "partnerPublicId", "value": "8f1c..."},
95
+ {"channel": "WHATSAPP", "address": "+5511922222222", "attribute": "partnerPublicId", "value": null}
96
+ ]
97
+ }
98
+ ```
99
+
100
+ E-mails são normalizados (trim, minúsculas, dedup); telefones em E.164; até 50 destinatários por canal (incondicionais + condicionais); WhatsApp exige `whatsappChannelId`.
101
+
102
+ ## 5. Destinatários condicionais: enricher do host
103
+
104
+ Fonte: `README.md`; interface `NotificationEventEnricher` e `RoutingAttribute`.
105
+
106
+ ```java
107
+ import br.com.seedgrid.notification.api.NotificationEvent;
108
+ import br.com.seedgrid.notification.api.NotificationEventEnricher;
109
+ import br.com.seedgrid.notification.api.RoutingAttribute;
110
+
111
+ @ApplicationScoped
112
+ public class PartnerRouting implements NotificationEventEnricher {
113
+ @Override
114
+ public Map<String, String> attributes(NotificationEvent event) {
115
+ String account = event.variables().get("accountPublicId");
116
+ String partner = account == null ? null : partners.partnerOf(account);
117
+ return partner == null ? Map.of() : Map.of("partnerPublicId", partner);
118
+ }
119
+
120
+ @Override
121
+ public List<RoutingAttribute> describe() {
122
+ return List.of(new RoutingAttribute("partnerPublicId", "Parceiro",
123
+ partners.list().stream()
124
+ .map(p -> new RoutingAttribute.Option(p.publicId(), p.name())).toList()));
125
+ }
126
+ }
127
+ ```
128
+
129
+ Não anote o enricher com `@Transactional` (uma exceção marcaria a transação de negócio para rollback); exceções do enricher são logadas e ignoradas.
130
+
131
+ ## 6. Consultar histórico
132
+
133
+ ```http
134
+ GET /admin/notifications/deliveries?page=0&size=30
135
+ ```
136
+
137
+ Resposta: `{ items: [{id, eventCode, channel, status, attempts, createdAt, sentAt, lastError}], totalRecords, page, size }`.
138
+
139
+ ## 7. Configuração
140
+
141
+ Ver [[SeedGrid/Extensions/notification/Configuracao|Configuração]] (mailer `quarkus.mailer.security.*`, `seedgrid.notification.*`).