Storage as a capability surface.
One IStorageProvider contract. 14 sub-interfaces declare capability granularly — Core, Stream, Urls, Copy, Metadata, Directory, MultiPart, Query, Version, Batch, Move, AccessControl, ProviderIdentity. Vadyl branches on declared caps, never assumes feature parity. Signed URLs for browser-direct uploads. Multi-part for large files. Quota enforcement and metering ride canonical events.
Switch by changing the binding. Your code does not change.
S3 · Azure Blob · GCS
Three cloud providers shipped. Vendor-neutral upload / download / copy / move / signed URL / multi-part. Capability declarations expose what each one does natively vs runtime-supplemented.
Local Disk · MinIO
Local for development and self-hosted. MinIO for S3-compatible storage on your own infrastructure. Same canonical surface — your code does not branch.
14 sub-interface declarations
Core / Stream / Urls / Copy / Metadata / Directory / MultiPart / Query / Version / Batch / Move / AccessControl / ProviderIdentity. Capability mismatches surface explicitly, never silent.
Signed URLs
Per-object pre-signed URLs for browser-direct uploads and downloads. Time-bounded, capability-gated, audited through canonical observability.
Multi-part uploads
Large-file resumable uploads via canonical IMultiPartOperations. Chunked, parallel, fail-resumable. Same client API across vendors.
Quota + metering
StorageEventEmitter routes through IUsageMeteringService for billing attribution and IQuotaEnforcementService for hard caps. Rides the canonical event substrate; no second metering pipeline.
Realtime + audit
Object create / update / delete fan out to realtime subscribers (field names only). Every storage mutation surfaces in the canonical observability relay.
Per-tenant path isolation
ProjectStorageNamespace.PhysicalPrefix derives from immutable project IDs (anti-pattern #32). No slug-based paths. Storage namespaces are forever stable.
Branchable bindings
Storage provider bindings are scope-chain inherited. A staging branch can point S3 at a different bucket without touching production. Branch and environment, not feature flags.
S3 · Azure Blob · GCS · Local Disk · MinIO
Granular capability
Anti-pattern #32 codified
Through canonical events
Object storage without lock-in.
Bind a vendor. Upload through signed URLs. Multi-part for large files. Switch the binding for staging. Vadyl handles the wiring, the audit, the quota.