@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.
- package/LICENSE +21 -0
- package/README.md +151 -2
- package/dist/adapters/claude.js +114 -0
- package/dist/adapters/codex.js +108 -0
- package/dist/adapters/index.js +17 -0
- package/dist/adapters/shared.js +142 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli.js +203 -0
- package/dist/commands/common.js +98 -0
- package/dist/commands/doctor.js +290 -0
- package/dist/commands/init.js +9 -0
- package/dist/commands/install.js +107 -0
- package/dist/commands/remove.js +54 -0
- package/dist/commands/review.js +127 -0
- package/dist/commands/status.js +73 -0
- package/dist/commands/update.js +8 -0
- package/dist/commands/validate.js +27 -0
- package/dist/core/apply.js +181 -0
- package/dist/core/blocks.js +64 -0
- package/dist/core/content.js +528 -0
- package/dist/core/env.js +40 -0
- package/dist/core/frontmatter.js +29 -0
- package/dist/core/hash.js +14 -0
- package/dist/core/inspect.js +51 -0
- package/dist/core/lock.js +124 -0
- package/dist/core/paths.js +65 -0
- package/dist/core/plan.js +242 -0
- package/dist/core/tools.js +62 -0
- package/dist/core/types.js +11 -0
- package/dist/core/updates.js +121 -0
- package/docs/arquitetura.md +80 -0
- package/docs/compatibilidade.md +50 -0
- package/docs/formato.md +155 -0
- package/docs/instalacao.md +105 -0
- package/docs/manutencao.md +115 -0
- package/package.json +43 -4
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
- package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
- package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
- package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
- package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
- package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
- package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
- package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
- package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
- package/seedgridKB/SeedGrid/Versoes.md +64 -0
- package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
- package/seedgridKB/manifest.json +142 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, extension, filemanagement, rust, configuracao]
|
|
3
|
+
fonte: rust/seedgrid-rust-crate-filemanagent
|
|
4
|
+
branch: main
|
|
5
|
+
commit: be738a2d1e
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# filemanagement — Configuração Rust
|
|
10
|
+
|
|
11
|
+
Visão do crate: [[SeedGrid/Extensions/filemanagement/Rust|Porte Rust do filemanagement]] · Java: [[SeedGrid/Extensions/filemanagement/Configuracao|Configuração do filemanagement (Java)]].
|
|
12
|
+
|
|
13
|
+
## Cabeçalho
|
|
14
|
+
| Item | Valor |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Mecanismo | **não lê variáveis de ambiente** nem tem struct de config: cada backend recebe um `HashMap<String, String>` em `FileStorageRegistry::get(tipo, &config)` → `FileStorageFactory::create(&config)` |
|
|
17
|
+
| Equivalente Java | idem: `Map<String,String>` passado ao registry; sem `@ConfigMapping` |
|
|
18
|
+
| Seleção de backend | pelo `tipo` passado ao registry (`type_identifier`); disponibilidade depende das features Cargo |
|
|
19
|
+
| Leitura | na criação do storage (`create`), uma vez por `(tipo, config)` (cache do registry) |
|
|
20
|
+
| Verificação | `grep` por `env::var` em `src/` não encontra nada (**Confirmado**); só `tests/minio_smoke.rs` lê env |
|
|
21
|
+
|
|
22
|
+
Quem fornece o mapa no workspace: `seedgrid-rust-crate-backup` (`BackupConfig::build_storage_config`, ver [[SeedGrid/Extensions/backup/Configuracao-Rust|Configuração Rust do backup]]) e o exemplo `seedgrid-filemanagement-example` (env `MINIO_*`).
|
|
23
|
+
|
|
24
|
+
## Chaves por backend
|
|
25
|
+
A coluna "Leitura" é sempre `create(&config)`. Valores são `trim`ados e vazios contam como ausentes, salvo indicação.
|
|
26
|
+
|
|
27
|
+
### filesystem (sempre disponível)
|
|
28
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
29
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
30
|
+
| `base-path` | String | caminho de diretório | — | Sim | cria o diretório se faltar; valida que é diretório e gravável (arquivo de teste `.seedgrid-write-test-*`) | `FilesystemStorage` | — | `create` | `src/factories.rs` → `FilesystemStorageFactory::create` |
|
|
31
|
+
|
|
32
|
+
### s3 (feature `s3`)
|
|
33
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
34
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
35
|
+
| `bucket` | String | nome | — | Sim | bucket alvo | `S3CompatStorage` | — | `create` | `src/providers/s3.rs` → `S3StorageFactory` |
|
|
36
|
+
| `region` | String | região AWS | `us-east-1` | Não | sem `endpoint`, precisa ser região válida (`Invalid S3 region`) | idem | `endpoint` | `create` | idem |
|
|
37
|
+
| `endpoint` | String | URL | — | Não | se presente: região custom + **path-style** (MinIO/LocalStack) | idem | — | `create` | idem |
|
|
38
|
+
| 🔒 `access-key` / 🔒 `secret-key` | String | texto | — | Não | só usadas se **ambas** presentes; senão cadeia default de credenciais do `rust-s3` | idem | — | `create` | `credentials_from` |
|
|
39
|
+
|
|
40
|
+
Cadeia default: o comentário do código diz "env/perfil/instância, igual ao Java"; os nomes exatos das variáveis vêm da biblioteca `rust-s3` (**Inferência**: variáveis AWS padrão como `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`; não verificado na dependência).
|
|
41
|
+
|
|
42
|
+
### minio (feature `s3` ou `minio`)
|
|
43
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
44
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
45
|
+
| `endpoint` | String | URL | — | Sim | sempre path-style | `S3CompatStorage` | — | `create` | `src/providers/s3.rs` → `MinioStorageFactory` |
|
|
46
|
+
| 🔒 `access-key` | String | texto | — | Sim | | idem | — | `create` | idem |
|
|
47
|
+
| 🔒 `secret-key` | String | texto | — | Sim | | idem | — | `create` | idem |
|
|
48
|
+
| `bucket` | String | nome | — | Sim | | idem | — | `create` | idem |
|
|
49
|
+
| `region` | String | texto | `us-east-1` | Não | | idem | — | `create` | idem |
|
|
50
|
+
|
|
51
|
+
### azure-blob (feature `azure`)
|
|
52
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
53
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
54
|
+
| `container` | String | nome | — | Sim | criado se não existir (`ensure_container`) | `AzureBlobStorage` | — | `create` | `src/providers/azure.rs` → `AzureBlobStorageFactory` |
|
|
55
|
+
| 🔒 `connection-string` | String | `AccountName=...;AccountKey=...;[EndpointSuffix=...;DefaultEndpointsProtocol=...]` | — | Condicional: ela **ou** `account-name`+`account-key` | tem precedência; `EndpointSuffix` padrão `core.windows.net`, protocolo padrão `https` | idem | — | `create` | `parse_connection_string` |
|
|
56
|
+
| `account-name` | String | texto | — | Condicional | host `https://<conta>.blob.core.windows.net` | idem | `account-key` | `create` | idem |
|
|
57
|
+
| 🔒 `account-key` | String | base64 | — | Condicional | assinatura SharedKey | idem | `account-name` | `create` | idem |
|
|
58
|
+
|
|
59
|
+
### gcs (feature `gcs`)
|
|
60
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
61
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
62
|
+
| `bucket` | String | nome | — | Sim | | `GcsStorage` | — | `create` | `src/providers/gcs.rs` |
|
|
63
|
+
| `project-id` | String | texto | — | Sim | só validado (paridade com o Java) | — | — | `create` | idem |
|
|
64
|
+
| `credentials-file` | String | caminho de JSON de service account | — | Condicional: um dos dois | lido do disco; tem precedência | `GoogleTokenProvider` | `credentials-json` | `create` | `src/providers/google_auth.rs` → `from_config` |
|
|
65
|
+
| 🔒 `credentials-json` | String | JSON de service account | — | Condicional | usado se não houver `credentials-file` | idem | — | `create` | idem |
|
|
66
|
+
|
|
67
|
+
### google-drive (feature `google-drive`)
|
|
68
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
69
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
70
|
+
| `root-folder-id` | String | id da pasta | — | Sim | pasta raiz | `GoogleDriveStorage` | — | `create` | `src/providers/drive.rs` |
|
|
71
|
+
| `credentials-file` / 🔒 `credentials-json` | String | idem GCS | — | Condicional (um dos dois) | idem GCS | `GoogleTokenProvider` | — | `create` | `google_auth.rs` |
|
|
72
|
+
|
|
73
|
+
### onedrive (feature `onedrive`)
|
|
74
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Leitura | Origem |
|
|
75
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
76
|
+
| `client-id` | String | texto | — | Sim | OAuth client-credentials | `OneDriveStorage` | os três juntos | `create` | `src/providers/onedrive.rs` |
|
|
77
|
+
| 🔒 `client-secret` | String | texto | — | Sim | | idem | | `create` | idem |
|
|
78
|
+
| `tenant-id` | String | texto | — | Sim | | idem | | `create` | idem |
|
|
79
|
+
| `root-folder-path` | String | caminho | `/seedgrid/files` | Não | pasta raiz | idem | — | `create` | idem |
|
|
80
|
+
|
|
81
|
+
## Features Cargo
|
|
82
|
+
| Feature | Padrão | Efeito |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| (nenhuma) | sim | só `filesystem` |
|
|
85
|
+
| `s3` | não | registra `s3` **e** `minio` em `BuiltInStorageFactories::all()` |
|
|
86
|
+
| `minio` | não | alias de `s3` |
|
|
87
|
+
| `azure` | não | `azure-blob` |
|
|
88
|
+
| `gcs` | não | `gcs` (+ `_google-auth`) |
|
|
89
|
+
| `google-drive` | não | `google-drive` (+ `_google-auth`) |
|
|
90
|
+
| `onedrive` | não | `onedrive` |
|
|
91
|
+
| `full` | não | todos |
|
|
92
|
+
| `_google-auth` | não | interna (JWT RS256 de service account) |
|
|
93
|
+
|
|
94
|
+
## Somente testes / exemplos
|
|
95
|
+
| Variável | Onde |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `MINIO_ENDPOINT`, `MINIO_ACCESS_KEY` 🔒, `MINIO_SECRET_KEY` 🔒, `MINIO_BUCKET` | `examples/seedgrid-filemanagement-example/src/main.rs` (`env_or`) e `tests/minio_smoke.rs` |
|
|
98
|
+
|
|
99
|
+
## Configuração mínima
|
|
100
|
+
```rust
|
|
101
|
+
let mut cfg = HashMap::new();
|
|
102
|
+
cfg.insert("base-path".into(), "/var/seedgrid/files".into());
|
|
103
|
+
let storage = FileStorageRegistry::new(BuiltInStorageFactories::all())?.get("filesystem", &cfg)?;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Receitas
|
|
107
|
+
- **MinIO**: compile com `features = ["s3"]`; mapa `endpoint`, `access-key`, `secret-key`, `bucket` (+ `region`).
|
|
108
|
+
- **AWS S3 com credenciais da instância**: `features = ["s3"]`; mapa só com `bucket` (+ `region`).
|
|
109
|
+
- **Azure**: `features = ["azure"]`; `container` + `connection-string` (`<SEGREDO:azure-connection-string>`).
|
|
110
|
+
- **GCS / Drive**: `credentials-file` apontando para o JSON da service account.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, library, filemanagement, configuracao]
|
|
3
|
+
fonte: java/seedgrid-quarkus-lib-filemanagement
|
|
4
|
+
branch: main
|
|
5
|
+
commit: 35c89c7cf7
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# SeedGrid File Management — Configuração
|
|
10
|
+
|
|
11
|
+
Voltar: [[SeedGrid/Extensions/filemanagement/Visao-geral|Visão geral do filemanagement]] · [[SeedGrid/Extensions/filemanagement/Exemplos|Exemplos do filemanagement]] · [[SeedGrid/Extensions/filemanagement/Rust|Porte Rust]]
|
|
12
|
+
|
|
13
|
+
## 1. Cabeçalho
|
|
14
|
+
|
|
15
|
+
| Item | Valor |
|
|
16
|
+
|---|---|
|
|
17
|
+
| Prefixos MicroProfile Config | **Nenhum.** A lib não lê `application.properties`/env |
|
|
18
|
+
| Mecanismo | **Mapa de configuração por chamada**: `FileStorageRegistry#get(String type, Map<String,String> config)` → `FileStorageFactory#create(config)`. Cada factory lê chaves fixas do mapa com `config.get(...)`/`getOrDefault(...)` |
|
|
19
|
+
| Quem preenche o mapa | O host/extension consumidora, a partir de onde quiser (MP Config, env, banco, Vault). Ex.: backup mapeia `seedgrid.backup.<tipo>.*`; o exemplo usa `app.storage.*` |
|
|
20
|
+
| Fase | Runtime, **lazy**: validado no primeiro `get(type, config)` com aquele conteúdo de mapa; instâncias cacheadas por (tipo + conteúdo do mapa) |
|
|
21
|
+
| Arquivos de config da lib | `src/main/resources/application.properties` existe e está **vazio** |
|
|
22
|
+
|
|
23
|
+
Investigação (**Confirmado**): nenhum `@ConfigMapping`, `@ConfigRoot`, `@ConfigProperty`, `ConfigProvider`, `System.getenv`/`getProperty` em `src/main`. As únicas leituras de config são `config.get/getOrDefault` nos factories em `java/seedgrid-quarkus-lib-filemanagement/src/main/java/br/com/seedgrid/filemanagement/factories/`.
|
|
24
|
+
|
|
25
|
+
Como os nomes abaixo são **chaves do mapa**, não propriedades MP, não existem variáveis de ambiente associadas pela lib. A coluna "Propriedade" usa a notação `<type>` → `<chave>`.
|
|
26
|
+
|
|
27
|
+
## 2. Chaves do mapa por backend
|
|
28
|
+
|
|
29
|
+
### 2.1 `filesystem`
|
|
30
|
+
|
|
31
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
32
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
33
|
+
| `filesystem` → `base-path` | `String` (caminho) | diretório gravável | — | Sim | Cria o diretório se não existir; falha se não for diretório ou não for gravável (`StorageConfigurationException`) | Raiz de todos os arquivos; `prefix` vira subpasta | — | Runtime (lazy) | `FilesystemStorageFactory#create` → `FilesystemStorage(basePath)` |
|
|
34
|
+
|
|
35
|
+
### 2.2 `s3`
|
|
36
|
+
|
|
37
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
38
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
39
|
+
| `s3` → `bucket` | `String` | nome de bucket | — | Sim | Ausente/vazio → `StorageConfigurationException` | Todas as operações | — | Runtime (lazy) | `S3StorageFactory#create` |
|
|
40
|
+
| `s3` → `region` | `String` | região AWS (`Region.of`) | `us-east-1` | Não | Região do `S3Client` e do `S3Presigner` | Cliente/presigner | — | Runtime (lazy) | `S3StorageFactory#create` (`getOrDefault`) |
|
|
41
|
+
| `s3` → `access-key` 🔒 | `String` | — | — | Condicional: só é usada se `secret-key` também vier | Com ambas, usa `StaticCredentialsProvider`; sem, usa a cadeia padrão do AWS SDK | Credenciais | par com `secret-key` | Runtime (lazy) | `S3StorageFactory.S3StorageImpl` (construtor) |
|
|
42
|
+
| `s3` → `secret-key` 🔒 | `String` | — | — | Condicional (par com `access-key`) | idem | Credenciais | par com `access-key` | Runtime (lazy) | idem |
|
|
43
|
+
| `s3` → `endpoint` | `String` (URI) | URL de serviço S3-compatível (MinIO, LocalStack) | — | Não | `endpointOverride` no cliente e no presigner | Cliente/presigner | — | Runtime (lazy) | idem |
|
|
44
|
+
|
|
45
|
+
### 2.3 `minio`
|
|
46
|
+
|
|
47
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
48
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
49
|
+
| `minio` → `endpoint` | `String` (URL) | ex.: `http://<host>:9000` | — | Sim | Ausente → `StorageConfigurationException` | `MinioClient` | — | Runtime (lazy) | `MinIOStorageFactory#create` |
|
|
50
|
+
| `minio` → `access-key` 🔒 | `String` | — | — | Sim | idem | Credenciais | — | Runtime (lazy) | idem |
|
|
51
|
+
| `minio` → `secret-key` 🔒 | `String` | — | — | Sim | idem | Credenciais | — | Runtime (lazy) | idem |
|
|
52
|
+
| `minio` → `bucket` | `String` | — | — | Sim | idem | Bucket alvo | — | Runtime (lazy) | idem |
|
|
53
|
+
| `minio` → `region` | `String` | — | `us-east-1` | Não | Repassado ao `MinIOStorage` | Cliente | — | Runtime (lazy) | idem (`getOrDefault`) |
|
|
54
|
+
|
|
55
|
+
### 2.4 `azure-blob`
|
|
56
|
+
|
|
57
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
58
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
59
|
+
| `azure-blob` → `container` | `String` | nome de container | — | Sim | Ausente → `StorageConfigurationException`; criado no init se não existir | Container alvo | — | Runtime (lazy) | `AzureBlobStorageFactory#create`; `AzureBlobStorage#initialize` |
|
|
60
|
+
| `azure-blob` → `connection-string` 🔒 | `String` | connection string Azure | — | Condicional: ela **ou** `account-name`+`account-key` | Tem prioridade sobre nome+chave | Autenticação | alternativa a `account-name`/`account-key` | Runtime (lazy) | idem |
|
|
61
|
+
| `azure-blob` → `account-name` | `String` | — | — | Condicional (sem `connection-string`) | Endpoint `https://<account-name>.blob.core.windows.net` + `StorageSharedKeyCredential` | Autenticação | par com `account-key` | Runtime (lazy) | idem |
|
|
62
|
+
| `azure-blob` → `account-key` 🔒 | `String` | — | — | Condicional (sem `connection-string`) | idem | Autenticação | par com `account-name` | Runtime (lazy) | idem |
|
|
63
|
+
|
|
64
|
+
### 2.5 `gcs` (Google Cloud Storage)
|
|
65
|
+
|
|
66
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
67
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
68
|
+
| `gcs` → `bucket` | `String` | — | — | Sim | Ausente → `StorageConfigurationException`; bucket inexistente → `StorageInitializationException` no init | Bucket alvo | — | Runtime (lazy) | `GoogleCloudStorageFactory#create`; `GoogleCloudStorage#initialize` |
|
|
69
|
+
| `gcs` → `project-id` | `String` | — | — | Sim | Ausente → `StorageConfigurationException` | `StorageOptions.setProjectId` | — | Runtime (lazy) | idem |
|
|
70
|
+
| `gcs` → `credentials-file` 🔒 | `String` (caminho de JSON de service account) | — | — | Condicional: ela **ou** `credentials-json` (o factory não valida, mas o init lança `StorageInitializationException` sem nenhuma) | Tem prioridade sobre `credentials-json` | `ServiceAccountCredentials.fromStream` | alternativa a `credentials-json` | Runtime (lazy) | `GoogleCloudStorage#initialize` |
|
|
71
|
+
| `gcs` → `credentials-json` 🔒 | `String` (conteúdo JSON) | — | — | Condicional (ver acima) | Usada se não houver `credentials-file` | idem | alternativa | Runtime (lazy) | idem |
|
|
72
|
+
|
|
73
|
+
### 2.6 `google-drive`
|
|
74
|
+
|
|
75
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
76
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
77
|
+
| `google-drive` → `root-folder-id` | `String` | ID de pasta do Drive | — | Sim | Ausente → `StorageConfigurationException`; vira o `bucket` da `StorageKey` | Pasta raiz dos uploads | — | Runtime (lazy) | `GoogleDriveStorageFactory#create` |
|
|
78
|
+
| `google-drive` → `credentials-file` 🔒 | `String` (caminho) | JSON de service account | — | Condicional: ela **ou** `credentials-json` (validado no factory) | Prioridade sobre `credentials-json`; escopo `drive.file` | Autenticação | alternativa | Runtime (lazy) | `GoogleDriveStorageFactory#create`; `GoogleDriveStorage` (construtor) |
|
|
79
|
+
| `google-drive` → `credentials-json` 🔒 | `String` (conteúdo JSON) | — | — | Condicional | idem | Autenticação | alternativa | Runtime (lazy) | idem |
|
|
80
|
+
|
|
81
|
+
### 2.7 `onedrive`
|
|
82
|
+
|
|
83
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
84
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
85
|
+
| `onedrive` → `client-id` | `String` | App registration Azure AD | — | Sim | Qualquer das três ausente → `StorageConfigurationException` | `ClientSecretCredential` | com `client-secret`, `tenant-id` | Runtime (lazy) | `OneDriveStorageFactory#create`; `OneDriveStorage` (construtor) |
|
|
86
|
+
| `onedrive` → `client-secret` 🔒 | `String` | — | — | Sim | idem | idem | idem | Runtime (lazy) | idem |
|
|
87
|
+
| `onedrive` → `tenant-id` | `String` | tenant Azure AD (não é tenant da aplicação) | — | Sim | idem | idem | idem | Runtime (lazy) | idem |
|
|
88
|
+
| `onedrive` → `root-folder-path` | `String` | caminho no drive | `/seedgrid/files` | Não | Pasta raiz; vira o `bucket` da `StorageKey` | Uploads | — | Runtime (lazy) | `OneDriveStorageFactory#create` (`getOrDefault`) |
|
|
89
|
+
|
|
90
|
+
## 3. Propriedades de frameworks
|
|
91
|
+
|
|
92
|
+
Nenhuma exigida. Não é necessário `quarkus.index-dependency.*`: o jar empacota `META-INF/jandex.idx` (`jandex-maven-plugin` no pom; confirmado também em comentário de `java/examples/seedgrid-filemanagement-example/src/main/resources/application.properties`).
|
|
93
|
+
|
|
94
|
+
## 4. Propriedades só de testes/exemplos
|
|
95
|
+
|
|
96
|
+
| Propriedade | Onde | Observação |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `quarkus.log.level`, `quarkus.log.category."br.com.seedgrid".level` | idem | logging de teste |
|
|
99
|
+
| `app.storage.type` (default `filesystem` no `@ConfigProperty`), `app.storage.filesystem.base-path` | `java/examples/seedgrid-filemanagement-example` → `DocumentStorageService` | propriedades **do exemplo**, que montam o mapa `Map.of("base-path", basePath)` |
|
|
100
|
+
|
|
101
|
+
## 5. Aliases, obsoletas, renomeações
|
|
102
|
+
|
|
103
|
+
Nenhuma propriedade da lib (ela não lê MicroProfile Config).
|
|
104
|
+
|
|
105
|
+
- Mapeamentos feitos por consumidores (não pertencem a esta lib): backup `seedgrid.backup.<tipo>.*` → chaves acima (`ExportService#buildStorageConfig`); security (avatar) em `UserAvatarService#buildStorageConfig`. Detalhes nas notas de cada extension: [[SeedGrid/Extensions/backup/Configuracao|Configuração do backup]], [[SeedGrid/Extensions/security/Configuracao|Configuração do security]].
|
|
106
|
+
|
|
107
|
+
## 6. Configuração mínima
|
|
108
|
+
|
|
109
|
+
Não há `application.properties` da lib. Mínimo no código do host:
|
|
110
|
+
|
|
111
|
+
```java
|
|
112
|
+
FileStorage storage = registry.get("filesystem", Map.of("base-path", "/var/data/files"));
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 7. Configuração completa comentada (mapas por backend)
|
|
116
|
+
|
|
117
|
+
```java
|
|
118
|
+
// filesystem
|
|
119
|
+
Map.of("base-path", "/var/data/files");
|
|
120
|
+
|
|
121
|
+
// s3 (credenciais opcionais: sem elas usa a cadeia padrão do AWS SDK)
|
|
122
|
+
Map<String, String> s3 = new HashMap<>();
|
|
123
|
+
s3.put("bucket", "<bucket>");
|
|
124
|
+
s3.put("region", "us-east-1"); // padrão us-east-1
|
|
125
|
+
s3.put("access-key", "<SEGREDO:aws-access-key>");
|
|
126
|
+
s3.put("secret-key", "<SEGREDO:aws-secret-key>");
|
|
127
|
+
s3.put("endpoint", "http://<host>:9000"); // opcional (S3-compatível)
|
|
128
|
+
|
|
129
|
+
// minio (todas obrigatórias, exceto region)
|
|
130
|
+
Map.of("endpoint", "http://<host>:9000", "access-key", "<SEGREDO:minio-access-key>",
|
|
131
|
+
"secret-key", "<SEGREDO:minio-secret-key>", "bucket", "<bucket>");
|
|
132
|
+
|
|
133
|
+
// azure-blob: container + (connection-string OU account-name + account-key)
|
|
134
|
+
Map.of("container", "<container>", "connection-string", "<SEGREDO:azure-connection-string>");
|
|
135
|
+
|
|
136
|
+
// gcs: bucket + project-id + (credentials-file OU credentials-json)
|
|
137
|
+
Map.of("bucket", "<bucket>", "project-id", "<project>", "credentials-file", "/etc/<sa>.json");
|
|
138
|
+
|
|
139
|
+
// google-drive: root-folder-id + (credentials-file OU credentials-json)
|
|
140
|
+
Map.of("root-folder-id", "<folder-id>", "credentials-json", "<SEGREDO:google-sa-json>");
|
|
141
|
+
|
|
142
|
+
// onedrive
|
|
143
|
+
Map.of("client-id", "<client-id>", "client-secret", "<SEGREDO:onedrive-client-secret>",
|
|
144
|
+
"tenant-id", "<azure-tenant-id>", "root-folder-path", "/seedgrid/files");
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 8. Receitas
|
|
148
|
+
|
|
149
|
+
- **Guardar a config em `application.properties` do host**: declare propriedades próprias (ex.: `app.storage.*`) com `@ConfigProperty` e monte o mapa — padrão do exemplo `DocumentStorageService`.
|
|
150
|
+
- **Vários buckets do mesmo tipo**: chame `registry.get("s3", configA)` e `registry.get("s3", configB)`; o cache separa por conteúdo do mapa.
|
|
151
|
+
- **Trocar de backend sem mudar código de negócio**: parametrize o `type` (ex.: `app.storage.type`) e monte o mapa por tipo, como faz `ExportService#buildStorageConfig` no backup.
|
|
152
|
+
- **Backend novo**: implemente `FileStorageFactory` (`@ApplicationScoped`) com `typeIdentifier` único e valide as chaves em `create`.
|
|
153
|
+
|
|
154
|
+
## 9. Dúvidas e lacunas
|
|
155
|
+
|
|
156
|
+
- Para usar um backend de nuvem o host precisa declarar o SDK (dependências `optional` no pom) — **Inferência**; sem ele, `create` deve falhar com `NoClassDefFoundError` (não testado).
|
|
157
|
+
- Equivalência com a config do crate Rust: [[SeedGrid/Extensions/filemanagement/Configuracao-Rust|Configuração Rust do filemanagement]].
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, library, filemanagement, exemplos]
|
|
3
|
+
fonte: java/seedgrid-quarkus-lib-filemanagement, java/examples/seedgrid-filemanagement-example
|
|
4
|
+
branch: main
|
|
5
|
+
commit: 35c89c7cf7
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# SeedGrid File Management — Exemplos
|
|
10
|
+
|
|
11
|
+
Voltar: [[SeedGrid/Extensions/filemanagement/Visao-geral|Visão geral do filemanagement]] · [[SeedGrid/Extensions/filemanagement/Configuracao|Configuração do filemanagement]]
|
|
12
|
+
|
|
13
|
+
## Dependência
|
|
14
|
+
|
|
15
|
+
```xml
|
|
16
|
+
<dependency>
|
|
17
|
+
<groupId>br.com.seedgrid</groupId>
|
|
18
|
+
<artifactId>seedgrid-filemanagement</artifactId>
|
|
19
|
+
<version>2026.07.08</version>
|
|
20
|
+
</dependency>
|
|
21
|
+
<!-- Para backends de nuvem, declare também o SDK (optional na lib), ex.: software.amazon.awssdk:s3 -->
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Fachada com backend configurável (exemplo real)
|
|
25
|
+
|
|
26
|
+
Fonte: `java/examples/seedgrid-filemanagement-example/src/main/java/br/com/seedgrid/filemanagementexample/service/DocumentStorageService.java`.
|
|
27
|
+
|
|
28
|
+
```java
|
|
29
|
+
@ApplicationScoped
|
|
30
|
+
public class DocumentStorageService {
|
|
31
|
+
|
|
32
|
+
@Inject
|
|
33
|
+
FileStorageRegistry registry;
|
|
34
|
+
|
|
35
|
+
@ConfigProperty(name = "app.storage.type", defaultValue = "filesystem")
|
|
36
|
+
String storageType;
|
|
37
|
+
|
|
38
|
+
@ConfigProperty(name = "app.storage.filesystem.base-path")
|
|
39
|
+
String basePath;
|
|
40
|
+
|
|
41
|
+
public FileStorage storage() {
|
|
42
|
+
Map<String, String> config = Map.of("base-path", basePath);
|
|
43
|
+
return registry.get(storageType, config);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public StorageKey store(String filename, byte[] content, String prefix, String contentType)
|
|
47
|
+
throws StorageException {
|
|
48
|
+
StorageOptions options = StorageOptions.builder()
|
|
49
|
+
.prefix(prefix)
|
|
50
|
+
.contentType(contentType)
|
|
51
|
+
.build();
|
|
52
|
+
return storage().store(filename, content, options);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public StorageKey keyOf(String relativePath) {
|
|
56
|
+
return StorageKey.of(storageType, relativePath);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public byte[] retrieve(StorageKey key) throws StorageException { return storage().retrieve(key); }
|
|
60
|
+
public FileMetadata metadata(StorageKey key) throws StorageException { return storage().getMetadata(key); }
|
|
61
|
+
public void delete(StorageKey key) throws StorageException { storage().delete(key); }
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```properties
|
|
66
|
+
# application.properties do exemplo (propriedades DO EXEMPLO, não da lib)
|
|
67
|
+
app.storage.type=filesystem
|
|
68
|
+
app.storage.filesystem.base-path=${STORAGE_BASE_PATH:${java.io.tmpdir}/seedgrid-filemanagement-example}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## S3 com credenciais opcionais
|
|
72
|
+
|
|
73
|
+
Fonte: `README.md` (chaves conferidas em `S3StorageFactory`).
|
|
74
|
+
|
|
75
|
+
```java
|
|
76
|
+
Map<String, String> s3Config = new HashMap<>();
|
|
77
|
+
s3Config.put("bucket", "<bucket>");
|
|
78
|
+
s3Config.put("region", "us-east-1");
|
|
79
|
+
s3Config.put("access-key", System.getenv("AWS_ACCESS_KEY_ID")); // opcional
|
|
80
|
+
s3Config.put("secret-key", System.getenv("AWS_SECRET_ACCESS_KEY")); // opcional
|
|
81
|
+
|
|
82
|
+
FileStorage storage = registry.get("s3", s3Config);
|
|
83
|
+
StorageKey key = storage.store("avatar.png", content, StorageOptions.builder()
|
|
84
|
+
.prefix("users/123/avatars")
|
|
85
|
+
.contentType("image/png")
|
|
86
|
+
.publicRead(true) // aplica ACL public-read no S3
|
|
87
|
+
.build());
|
|
88
|
+
String url = storage.generateSignedUrl(key, Duration.ofMinutes(15));
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> `HashMap.put` com valor `null` (env ausente) é aceito; o factory ignora credenciais vazias/nulas e usa a cadeia padrão do AWS SDK.
|
|
92
|
+
|
|
93
|
+
## Mapeando config própria da extension para o mapa (padrão do backup)
|
|
94
|
+
|
|
95
|
+
Fonte: `java/seedgrid-quarkus-ext-backup/runtime/src/main/java/br/com/seedgrid/backup/services/ExportService.java` → `buildStorageConfig` (trecho).
|
|
96
|
+
|
|
97
|
+
```java
|
|
98
|
+
private Map<String, String> buildStorageConfig(String storageType) {
|
|
99
|
+
Map<String, String> config = new HashMap<>();
|
|
100
|
+
|
|
101
|
+
switch (storageType.toLowerCase()) {
|
|
102
|
+
case "filesystem":
|
|
103
|
+
config.put("base-path", backupConfig.filesystem().basePath());
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
case "s3":
|
|
107
|
+
backupConfig.s3().bucket().ifPresent(v -> config.put("bucket", v));
|
|
108
|
+
backupConfig.s3().region().ifPresent(v -> config.put("region", v));
|
|
109
|
+
backupConfig.s3().accessKey().ifPresent(v -> config.put("access-key", v));
|
|
110
|
+
backupConfig.s3().secretKey().ifPresent(v -> config.put("secret-key", v));
|
|
111
|
+
backupConfig.s3().endpoint().ifPresent(v -> config.put("endpoint", v));
|
|
112
|
+
break;
|
|
113
|
+
|
|
114
|
+
// ... minio, azure-blob, google-drive, onedrive, gcs (mesmo padrão)
|
|
115
|
+
|
|
116
|
+
default:
|
|
117
|
+
throw new IllegalArgumentException("Unknown storage type: " + storageType);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return config;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// uso:
|
|
124
|
+
FileStorage storage = fileStorageRegistry.get(storageType, buildStorageConfig(storageType));
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Backend customizado
|
|
128
|
+
|
|
129
|
+
Fonte: `README.md` (contrato conferido em `FileStorageFactory`).
|
|
130
|
+
|
|
131
|
+
```java
|
|
132
|
+
@ApplicationScoped
|
|
133
|
+
public class DropboxStorageFactory implements FileStorageFactory {
|
|
134
|
+
@Override public String typeIdentifier() { return "dropbox"; }
|
|
135
|
+
|
|
136
|
+
@Override
|
|
137
|
+
public FileStorage create(Map<String, String> config) {
|
|
138
|
+
String token = config.get("token");
|
|
139
|
+
if (token == null || token.isBlank()) {
|
|
140
|
+
throw new StorageConfigurationException("Dropbox token missing");
|
|
141
|
+
}
|
|
142
|
+
return new DropboxStorage(token); // sua implementação de FileStorage
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`DropboxStorage` é hipotética (do README); um segundo factory com o mesmo `typeIdentifier` derruba o boot com `DuplicateStorageException`.
|
|
148
|
+
|
|
149
|
+
## StorageKey e URIs
|
|
150
|
+
|
|
151
|
+
```java
|
|
152
|
+
StorageKey k1 = StorageKey.filesystem("exports/2024/report.pdf");
|
|
153
|
+
String uri = k1.toUri(); // "filesystem://exports/2024/report.pdf"
|
|
154
|
+
StorageKey k2 = StorageKey.fromUri(uri); // bucket="exports", path="2024/report.pdf"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
O `FilesystemStorage` resolve `basePath/bucket/path`, então o round-trip acima funciona no filesystem; no S3 a chave volta sem bucket — ver limitações em [[SeedGrid/Extensions/filemanagement/Visao-geral|Visão geral do filemanagement]].
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, extension, filemanagement, rust]
|
|
3
|
+
fonte: rust/seedgrid-rust-crate-filemanagent
|
|
4
|
+
branch: main
|
|
5
|
+
commit: be738a2d1e
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# filemanagement — porte Rust (`seedgrid-rust-crate-filemanagent`)
|
|
10
|
+
|
|
11
|
+
Porte da lib Java `seedgrid-quarkus-lib-filemanagement`. O nome do pacote Rust tem a grafia `filemanagent` (sem "m"); os crates consumidores o renomeiam para `seedgrid_filemanagement` via `package = ...` (ex.: `rust/seedgrid-rust-crate-backup/Cargo.toml`). Lado Java: [[SeedGrid/Extensions/filemanagement/Visao-geral|Visão geral do filemanagement (Java)]] · [[SeedGrid/Extensions/filemanagement/Configuracao|Configuração do filemanagement (Java)]]. Configuração Rust: [[SeedGrid/Extensions/filemanagement/Configuracao-Rust|Configuração Rust do filemanagement]].
|
|
12
|
+
|
|
13
|
+
Abstração de armazenamento de arquivos com registro extensível de backends: `filesystem` (sempre presente) e, por feature Cargo, `s3`, `minio`, `azure-blob`, `gcs`, `google-drive`, `onedrive`. **Confirmado** (`src/lib.rs`, `src/factories.rs`).
|
|
14
|
+
|
|
15
|
+
## Identificação
|
|
16
|
+
| Item | Valor |
|
|
17
|
+
|---|---|
|
|
18
|
+
| Pacote Cargo | `seedgrid-rust-crate-filemanagent` (lib `seedgrid_rust_crate_filemanagent`, nome padrão; usado assim em `tests/minio_smoke.rs`) |
|
|
19
|
+
| Versão | workspace `2026.10.14` |
|
|
20
|
+
| Features | `s3`, `minio` (= `s3`), `azure`, `gcs`, `google-drive`, `onedrive`, `full`; padrão: nenhuma (só filesystem) |
|
|
21
|
+
| Dependências SeedGrid | nenhuma |
|
|
22
|
+
| Consumidores | backup (e o exemplo `seedgrid-filemanagement-example`) |
|
|
23
|
+
| I/O | síncrono (S3/MinIO via `rust-s3` blocking; REST via `reqwest::blocking`) |
|
|
24
|
+
|
|
25
|
+
## API pública
|
|
26
|
+
| Símbolo | Papel | Fonte |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| trait `FileStorage` | `store`, `store_stream`, `store_reader` (extra do Rust), `retrieve`, `stream`, `delete`, `exists`, `get_metadata`, `generate_signed_url`, `can_handle`; aliases camelCase (`getMetadata`, `generateSignedUrl`, `canHandle`) | `src/storage.rs` |
|
|
29
|
+
| trait `FileStorageFactory` | `type_identifier`, `create(&HashMap<String,String>)`, `is_available` | `src/storage.rs` |
|
|
30
|
+
| `FileStorageRegistry::new(Vec<Box<dyn FileStorageFactory>>)` | `get(tipo, &config)` com cache por `(tipo, config)`, `get_for_key`, `has`, `get_available_types` | `src/registry.rs` |
|
|
31
|
+
| `BuiltInStorageFactories::all()` | factories disponíveis conforme features | `src/factories.rs` |
|
|
32
|
+
| `FilesystemStorageFactory`, `FilesystemStorage` | backend local | `src/factories.rs`, `src/storages.rs` |
|
|
33
|
+
| `S3StorageFactory`, `MinioStorageFactory`, `S3CompatStorage` | feature `s3` | `src/providers/s3.rs` |
|
|
34
|
+
| `AzureBlobStorageFactory`/`AzureBlobStorage`, `GoogleCloudStorageFactory`/`GcsStorage`, `GoogleDriveStorageFactory`/`GoogleDriveStorage`, `OneDriveStorageFactory`/`OneDriveStorage` | features respectivas | `src/providers/*.rs` |
|
|
35
|
+
| `StorageKey` (`to_uri`, `from_uri`, construtores `filesystem`, `s3`…), `StorageOptions` (+ builder: `prefix`, `content_type`, `ttl`, `encrypt`, `public_read`, `metadata`), `FileMetadata` | domínio | `src/domains.rs` |
|
|
36
|
+
| `StorageError` (`not_found`, `is_not_found`), `StorageConfigurationError`, `StorageNotFoundError`, `DuplicateStorageError`, `StorageInitializationError`, `RegistryError` | erros | `src/error.rs`, `src/registry.rs` |
|
|
37
|
+
|
|
38
|
+
## Exemplo (de `rust/examples/seedgrid-filemanagement-example/src/main.rs`)
|
|
39
|
+
```rust
|
|
40
|
+
let mut config = HashMap::new();
|
|
41
|
+
config.insert("endpoint".into(), env_or("MINIO_ENDPOINT", "http://localhost:9000"));
|
|
42
|
+
config.insert("access-key".into(), env_or("MINIO_ACCESS_KEY", "<valor-dev>"));
|
|
43
|
+
config.insert("secret-key".into(), env_or("MINIO_SECRET_KEY", "<valor-dev>"));
|
|
44
|
+
config.insert("bucket".into(), env_or("MINIO_BUCKET", "sg-example"));
|
|
45
|
+
|
|
46
|
+
let registry = FileStorageRegistry::new(vec![
|
|
47
|
+
Box::new(MinioStorageFactory) as Box<dyn FileStorageFactory>,
|
|
48
|
+
])?;
|
|
49
|
+
let storage = registry.get("minio", &config)?;
|
|
50
|
+
let options = StorageOptions::builder().prefix("example").content_type("text/plain").build();
|
|
51
|
+
let key = storage.store("hello.txt", &payload, &options)?;
|
|
52
|
+
let fetched = storage.retrieve(&key)?;
|
|
53
|
+
let meta = storage.get_metadata(&key)?;
|
|
54
|
+
storage.delete(&key)?;
|
|
55
|
+
```
|
|
56
|
+
(Os valores default de credencial do exemplo foram substituídos por `<valor-dev>`.)
|
|
57
|
+
|
|
58
|
+
## Testes
|
|
59
|
+
- `tests/filesystem_storage_test.rs`, `registry_test.rs`, `storage_key_test.rs`, `storage_options_test.rs`.
|
|
60
|
+
- `tests/minio_smoke.rs` (feature `s3`, `#[ignore]`, MinIO real).
|
|
61
|
+
- E2E no exemplo: `rust/examples/seedgrid-filemanagement-example/tests/minio_e2e.rs`.
|
|
62
|
+
- **Não executados.** Só S3/MinIO foram validados E2E; Azure/GCS/Drive/OneDrive compilam mas não foram testados contra a nuvem.
|
|
63
|
+
|
|
64
|
+
## Limitações
|
|
65
|
+
|
|
66
|
+
- `generate_signed_url` só funciona em S3/MinIO; nos backends REST devolve "not supported".
|
|
67
|
+
- Não há parser manual de `from_uri`, aliases camelCase nem `store_reader`.
|
|
68
|
+
|
|
69
|
+
## Enums
|
|
70
|
+
Sem enums de domínio (o backend é escolhido pelo texto `type_identifier`: `filesystem`, `s3`, `minio`, `azure-blob`, `gcs`, `google-drive`, `onedrive`). Enum público de erro: `RegistryError` (`src/registry.rs`) com `NotFound(StorageNotFoundError)` (tipo não registrado; a mensagem lista os tipos disponíveis) e `Configuration(StorageConfigurationError)` (falha em `factory.create`). Ver [[SeedGrid/Extensions/filemanagement/Configuracao-Rust|Configuração Rust]] para os tipos e chaves.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, library, filemanagement]
|
|
3
|
+
fonte: java/seedgrid-quarkus-lib-filemanagement
|
|
4
|
+
branch: main
|
|
5
|
+
commit: 35c89c7cf7
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# SeedGrid File Management — Visão geral
|
|
10
|
+
|
|
11
|
+
> [!info] Library, não extension Quarkus
|
|
12
|
+
> `seedgrid-quarkus-lib-filemanagement` é uma **library Java** (jar único com índice Jandex), **não** uma extension Quarkus com `runtime`/`deployment`. Não há `@ConfigRoot`/`@ConfigMapping`: a lib **não lê MicroProfile Config** — recebe a configuração de cada storage num `Map<String, String>` passado pelo chamador. Documentada nesta estrutura por uniformidade.
|
|
13
|
+
|
|
14
|
+
Configuração: [[SeedGrid/Extensions/filemanagement/Configuracao|Configuração do filemanagement]] · Exemplos: [[SeedGrid/Extensions/filemanagement/Exemplos|Exemplos do filemanagement]] · [[SeedGrid/Extensions/filemanagement/Rust|Porte Rust]] (crate `seedgrid-rust-crate-filemanagent`)
|
|
15
|
+
|
|
16
|
+
## Objetivo
|
|
17
|
+
|
|
18
|
+
Uma API única de armazenamento de arquivos (`FileStorage`) com backends plugáveis — filesystem, AWS S3, MinIO, Azure Blob, Google Cloud Storage, Google Drive e OneDrive — criados **sob demanda** por factories e cacheados pelo `FileStorageRegistry`. A aplicação decide a organização de paths (via `prefix`). **Confirmado** (`pom.xml` description, `README.md`, código).
|
|
19
|
+
|
|
20
|
+
## Coordenadas e dependências
|
|
21
|
+
|
|
22
|
+
| Item | Valor |
|
|
23
|
+
|---|---|
|
|
24
|
+
| groupId:artifactId | `br.com.seedgrid:seedgrid-filemanagement` |
|
|
25
|
+
| Versão (pom) | `2026.07.08` |
|
|
26
|
+
| Parent | `br.com.seedgrid:seedgrid-parent:2026.07.02` |
|
|
27
|
+
| Obrigatórias | `quarkus-arc`, `quarkus-hibernate-validator` |
|
|
28
|
+
| **Optional** (o host precisa declarar para usar o backend) | AWS `s3` 2.21.42; `azure-storage-blob` 12.25.1; `google-api-client` 2.2.0, `google-api-services-drive` v3-rev197-1.25.0, `google-auth-library-oauth2-http` 1.20.0; `google-cloud-storage` 2.29.1; `minio` 8.5.9; `microsoft-graph` 5.80.0 + `azure-identity` 1.11.1; também `quarkus-hibernate-orm`, `quarkus-jdbc-postgresql`, `quarkus-flyway` |
|
|
29
|
+
| Dependências SeedGrid | nenhuma (desde 2026.07.08 não depende mais de `seedgrid-commons`, segundo comentário do exemplo) |
|
|
30
|
+
|
|
31
|
+
Fonte: `java/seedgrid-quarkus-lib-filemanagement/pom.xml`. **Confirmado.** Que o host precise declarar o SDK do backend escolhido é **Inferência** (escopo `optional` não é transitivo).
|
|
32
|
+
|
|
33
|
+
## Arquitetura
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
flowchart LR
|
|
37
|
+
APP["Host / extension<br/>(monta Map de config)"] -->|"registry.get(type, config)"| REG["FileStorageRegistry<br/>@ApplicationScoped"]
|
|
38
|
+
REG -->|"descobre no construtor<br/>Instance<FileStorageFactory>"| F["FileStorageFactory<br/>(1 por typeIdentifier)"]
|
|
39
|
+
F -->|"create(config) — valida chaves"| S["FileStorage<br/>(@Vetoed, não é bean)"]
|
|
40
|
+
REG -->|"cache por (type + config)"| S
|
|
41
|
+
S --> B[("filesystem · s3 · minio · azure-blob · gcs · google-drive · onedrive")]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- **Descoberta** (**Confirmado**, `FileStorageRegistry`): o construtor itera `Instance<FileStorageFactory>`; dois factories com o mesmo `typeIdentifier()` → `DuplicateStorageException` (falha no boot); nenhum factory → apenas WARN.
|
|
45
|
+
- **Lazy + cache** (**Confirmado**): `get(type, config)` cria via `factory.create(config)` na primeira chamada e cacheia por `record CacheKey(type, cópia imutável do config)` — igualdade por conteúdo do mapa; configs diferentes do mesmo tipo geram instâncias distintas. `clearCache()` força recriação. Tipo sem factory → `StorageNotFoundException` (checked, propagada via `@SneakyThrows`).
|
|
46
|
+
- **Validação** só no primeiro uso: factories lançam `StorageConfigurationException` (unchecked); construtores de storage podem lançar `StorageInitializationException` (ex.: GCS sem credenciais ou bucket inexistente).
|
|
47
|
+
- As classes de storage são `@Vetoed` (não são beans CDI); os factories são `@ApplicationScoped`. **Confirmado** (todas as classes em `storages/` têm `@Vetoed`; criação sempre via `new` nos factories).
|
|
48
|
+
|
|
49
|
+
### Backends embutidos
|
|
50
|
+
|
|
51
|
+
| `typeIdentifier` | Factory | Implementação | `generateSignedUrl` |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| `filesystem` | `FilesystemStorageFactory` | `FilesystemStorage` | não suportado (default lança `UnsupportedOperationException`) |
|
|
54
|
+
| `s3` | `S3StorageFactory` | classe interna `S3StorageImpl` (a classe pública `storages/S3Storage` é `@Vetoed` e **não é usada** pelo factory) | presigned GET |
|
|
55
|
+
| `minio` | `MinIOStorageFactory` | `MinIOStorage` | presigned (expiry em segundos) |
|
|
56
|
+
| `azure-blob` | `AzureBlobStorageFactory` | `AzureBlobStorage` (cria o container se não existir) | SAS |
|
|
57
|
+
| `gcs` | `GoogleCloudStorageFactory` | `GoogleCloudStorage` (verifica se o bucket existe no init) | signed URL (TTL em minutos) |
|
|
58
|
+
| `google-drive` | `GoogleDriveStorageFactory` | `GoogleDriveStorage` (escopo `drive.file`) | **cria permissão pública `anyone/reader`** e devolve link; o TTL é ignorado (link precisa ser revogado manualmente) |
|
|
59
|
+
| `onedrive` | `OneDriveStorageFactory` | `OneDriveStorage` (Graph `me().drive()`, client credentials) | devolve `webUrl` do item; TTL ignorado; loga WARN |
|
|
60
|
+
|
|
61
|
+
Fonte: `factories/*.java`, `storages/*.java`. **Confirmado.**
|
|
62
|
+
|
|
63
|
+
## APIs públicas e pontos de integração
|
|
64
|
+
|
|
65
|
+
| Tipo | Símbolo | Observação |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| SPI | `spi.FileStorage` | `typeIdentifier()`, `store(filename, byte[], StorageOptions)`, `store(filename, InputStream, StorageOptions)` (default lê tudo em memória), `retrieve`, `stream`, `delete`, `exists`, `getMetadata`, `generateSignedUrl(key, ttl)` (default unsupported), `canHandle(key)` |
|
|
68
|
+
| SPI | `spi.FileStorageFactory` | `typeIdentifier()`, `create(Map<String,String>)` |
|
|
69
|
+
| Bean | `services.FileStorageRegistry` | `get(type, config)`, `get(StorageKey, config)`, `has(type)`, `getAvailableTypes()`, `getCreatedStorages()`, `clearCache()` |
|
|
70
|
+
| Domínio | `domains.StorageKey` | `type`, `bucket`, `path`; `toUri()`/`fromUri()`, fábricas `filesystem`, `s3`, `azureBlob`, `minio`, `of(...)` |
|
|
71
|
+
| Domínio | `domains.StorageOptions` | `prefix`, `contentType`, `publicRead` (false; só tem efeito no S3), `metadata` (gravado por Azure, GCS, Google Drive e MinIO); `defaults()`, `withPrefix()`, `fullPath()` |
|
|
72
|
+
| Domínio | `domains.FileMetadata` | `storageKey`, `filename`, `sizeBytes`, `contentType`, `createdAt`, `lastModifiedAt`, `metadata` (preenchidos conforme o backend) |
|
|
73
|
+
| Exceções | `StorageException` (checked), `StorageNotFoundException` (checked, estende `StorageException`), `StorageConfigurationException`, `StorageInitializationException`, `DuplicateStorageException` | — |
|
|
74
|
+
|
|
75
|
+
Extensão: o host cria um `@ApplicationScoped FileStorageFactory` com `typeIdentifier` novo; o registry o descobre. Sem endpoints REST, eventos ou migrations (apesar das deps optional de ORM/Flyway, não há entidades nem SQL no `src/main`).
|
|
76
|
+
|
|
77
|
+
**Consumidores no monorepo** (**Confirmado** por busca): `seedgrid-quarkus-ext-backup` (`ExportService#buildStorageConfig`, mapeia `seedgrid.backup.*` → chaves do mapa) — ver [[SeedGrid/Extensions/backup/Visao-geral|Visão geral do backup]]; `seedgrid-quarkus-ext-security` (`UserAvatarService#buildStorageConfig`) — ver [[SeedGrid/Extensions/security/Visao-geral|Visão geral do security]]; dependência declarada em `seedgrid-quarkus-ext-login-tenancy`.
|
|
78
|
+
|
|
79
|
+
## Testes existentes (não executados)
|
|
80
|
+
|
|
81
|
+
`src/test/java/...`: `StorageKeyTest`, `StorageOptionsTest`, `FileMetadataTest`, `FileStorageRegistryTest` (Mockito), `FileStorageRegistryFilesystemTest` (cache por config), `FilesystemStorageTest`, `StorageExceptionTest`, `FileStorageIntegrationTest` (`@QuarkusTest`, só `filesystem`). ~60 `@Test` por grep. Nenhum teste de backend de nuvem. **Não executados.**
|
|
82
|
+
|
|
83
|
+
## Limitações
|
|
84
|
+
|
|
85
|
+
- `publicRead` só tem efeito no S3 (ACL `public-read`). **Confirmado.**
|
|
86
|
+
- S3 (`S3StorageImpl`) devolve `StorageKey.of("s3", key)` **sem bucket**; `toUri()` vira `s3://<prefixo>/<arquivo>` e um `fromUri()` posterior interpretaria o primeiro segmento como bucket, mudando o `path`. Risco de round-trip ao persistir a URI — **Inferência** (não testado).
|
|
87
|
+
- `FilesystemStorage` monta caminhos com `Paths.get(basePath, ...)` sem normalizar nem barrar `..` — risco de path traversal se `filename`/`prefix` vierem do usuário. **Inferência.**
|
|
88
|
+
- `GoogleDriveStorage#generateSignedUrl` torna o arquivo público permanentemente.
|