namespace GB5Shared.Storage { /// /// Abstraction over physical file storage. /// All implementations must be stateless and thread-safe. /// The storagePath parameter is an opaque internal key — never expose it to the frontend. /// public interface IStorageProvider { StorageProviderType ProviderType { get; } /// /// Saves the stream to storage at the specified relative path. /// Creates intermediate directories as needed. /// Returns the same on success. /// Task SaveAsync(Stream content, string storagePath, string mimeType, CancellationToken ct = default); /// /// Opens a readable stream for the given storage path. /// Throws if not found. /// Caller is responsible for disposing the returned stream. /// Task GetStreamAsync(string storagePath, CancellationToken ct = default); /// /// Permanently deletes a file. Returns false if not found (idempotent). /// Task DeleteAsync(string storagePath, CancellationToken ct = default); /// /// Checks existence without downloading. Useful for health/integrity checks. /// Task ExistsAsync(string storagePath, CancellationToken ct = default); /// /// Moves a file from to . /// For S3 this is CopyObject + DeleteObject. For filesystem this is File.Move. /// Returns false if the source does not exist (idempotent). /// Task MoveAsync(string oldStoragePath, string newStoragePath, CancellationToken ct = default); } }