Behaviour for object-storage backends.
Implemented by Gamend.Storage.Local (disk, the dev default) and
Gamend.Storage.S3 (any S3-compatible service — AWS S3, Cloudflare R2,
Backblaze B2, MinIO, DigitalOcean Spaces). Callers go through the
Gamend.Storage facade, never an adapter directly.
Summary
Types
A stored object's metadata, as listed by the admin tools.
An upload ticket handed to a client so it can upload bytes directly to the backend (S3/R2) or to the local upload endpoint — the client flow is identical either way.
What the backend reports about a stored object without fetching it.
Callbacks
Deletes every object under prefix. Returns how many were removed.
One page of objects. Opts: :prefix, :offset, :limit.
Size and stored content type of one object, without downloading it.
Total object count and byte size. Opts: :prefix.
Types
@type key() :: String.t()
@type object() :: %{ key: key(), size: non_neg_integer(), last_modified: DateTime.t() | nil }
A stored object's metadata, as listed by the admin tools.
@type presigned() :: %{ method: String.t(), url: String.t(), headers: %{optional(String.t()) => String.t()}, key: key(), expires_in: pos_integer() }
An upload ticket handed to a client so it can upload bytes directly to the backend (S3/R2) or to the local upload endpoint — the client flow is identical either way.
@type stat() :: %{size: non_neg_integer(), content_type: String.t() | nil}
What the backend reports about a stored object without fetching it.
Callbacks
@callback delete_prefix(String.t()) :: {:ok, non_neg_integer()} | {:error, term()}
Deletes every object under prefix. Returns how many were removed.
One page of objects. Opts: :prefix, :offset, :limit.
Size and stored content type of one object, without downloading it.
content_type is whatever the backend recorded; the local adapter keeps no
per-object metadata and always reports nil.
@callback usage(keyword()) :: %{count: non_neg_integer(), bytes: non_neg_integer()}
Total object count and byte size. Opts: :prefix.