feat: add object storage production capability

This commit is contained in:
donghyeon-ka
2026-07-31 23:50:03 +09:00
parent b3add0162d
commit f0a6d1c8c8
427 changed files with 39930 additions and 699 deletions
+29 -26
View File
@@ -4,46 +4,49 @@
- Module ID: `adapter-outbound-objectstorage`
- Gradle path: `:adapter:outbound:objectstorage`
- Focused test (derived from Gradle path): `./gradlew :adapter:outbound:objectstorage:test --console=plain`
- Focused test: `./gradlew :adapter:outbound:objectstorage:test --console=plain`
- Runtime baseline: Java 21; repository framework baseline: Spring Boot 4.0.0.
- Registry SSOT: `src/config/architecture/modules.json`.
Package root: `dev.caskeleton.adapter.outbound.objectstorage`. Driven (outbound) adapter
implementing `dev.caskeleton.application.storage.ObjectStoragePort` (application-core). Design
rationale lives in [README.md](README.md).
Package root: `dev.caskeleton.adapter.outbound.objectstorage`. Design rationale and truthful
readiness live in [README.md](README.md) and
`docs/registries/object-storage-readiness.yaml`.
## Responsibility
- Persist/retrieve binary blobs behind `ObjectStoragePort`. Two backends select the same port by
`ca-skeleton.objectstorage.backend`: `filesystem` (default) and `s3` (S3/MinIO, AWS SDK v2).
- Opt-in: `ObjectStorageConfig` gates each backend with `@ConditionalOnProperty`; filesystem is the
`matchIfMissing` default. The adapters are plain classes; the config assembles them as beans.
- Implement application-core semantic object publication, read, retirement, and operation
resolution ports behind provider-neutral bounded streaming and strict durable control records.
- Compile disabled-by-default `app.object-storage` settings into exact immutable
provider/destination/route/policy bindings before constructing selected resources.
- Provide `filesystem-local-dev` as an R1-only development provider.
- Keep scanner maintenance, privileged purge, and direct-grant composition separate; unsupported
capabilities contribute no bean.
- Isolate the deprecated whole-`byte[]` `ObjectStoragePort` and old
`ca-skeleton.objectstorage.*` alias as explicit migration-only behavior.
## Allowed
- Project deps: `:application-core`, `:shared-contract` — SSOT is the
`adapter-outbound-objectstorage` entry in `src/config/architecture/modules.json`; `src/build.gradle`
enforces it. No
`:domain-core`, no sibling adapters (shared outbound code would go through `:adapter:outbound:support`
if ever needed).
- External: `software.amazon.awssdk:s3` (version via the module-scoped `software.amazon.awssdk:bom`
platform, pinned by root `ext.awsSdkVersion`), `spring-boot-starter`,
`spring-boot-configuration-processor` (annotation processor).
- Project dependencies are exactly those allowed by the `adapter-outbound-objectstorage` entry in
`src/config/architecture/modules.json`; currently application-core and shared-contract.
- Provider SDK/configuration types stay within this leaf.
- Provider contributions may describe support without side effects and may construct resources
only after exact selection.
## Forbidden
- Inbound adapters, sibling outbound adapters, persistence, `app-bootstrap`, `sample-portfolio`
(ArchUnit `OUTBOUND_ADAPTERS_*` family rules).
- Leaking a raw AWS SDK type across `ObjectStoragePort` (B7) — the port returns only `StoredObject`
/ `byte[]` / primitives.
- Fully-qualified inline type references; more than one public top-level type per file.
- Inbound adapters, sibling outbound adapters, persistence, app-bootstrap, or sample-portfolio
dependencies.
- Provider keys, paths, locators, SDK types, Spring types, or control-record types leaking into
application-core.
- A default provider/destination/namespace, local-dev in production, or startup mutation when the
capability is disabled.
- Normal routing types implementing scanner maintenance or privileged purge ports.
- Claims above the exact rows in `docs/registries/object-storage-readiness.yaml`.
- Adapting new semantic operations back to legacy caller-keyed overwrite semantics.
## Tests
`FilesystemObjectStorageAdapterTest` (temp-dir round-trip), `S3ObjectStorageAdapterTest` (mocked
`S3Client` mapping), `S3ObjectStorageAdapterIT` (Testcontainers MinIO, `disabledWithoutDocker`).
## Test
```bash
cd src
./gradlew :adapter:outbound:objectstorage:check
./gradlew :adapter:outbound:objectstorage:check --console=plain
```