Changeset 0.12.0 (#63)
This commit is contained in:
73
server/storage/storage.go
Normal file
73
server/storage/storage.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ── Errors ─────────────────────────────────
|
||||
|
||||
var (
|
||||
// ErrNotFound is returned when a requested object does not exist.
|
||||
ErrNotFound = errors.New("storage: object not found")
|
||||
|
||||
// ErrNotConfigured is returned when storage operations are attempted
|
||||
// but no backend has been configured or the backend is unhealthy.
|
||||
ErrNotConfigured = errors.New("storage: backend not configured")
|
||||
)
|
||||
|
||||
// ── ObjectStore Interface ──────────────────
|
||||
|
||||
// ObjectStore is the abstraction for blob storage.
|
||||
// Implementations: PVC (filesystem), S3 (minio-go v7).
|
||||
//
|
||||
// Keys are slash-delimited paths relative to the storage root:
|
||||
//
|
||||
// attachments/{channel_id}/{attachment_id}_{filename}
|
||||
//
|
||||
// Implementations must create intermediate directories as needed.
|
||||
type ObjectStore interface {
|
||||
// Put writes data to the given key.
|
||||
// Creates parent directories as needed. Overwrites if exists.
|
||||
Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error
|
||||
|
||||
// Get returns a reader for the given key.
|
||||
// Returns the reader, size in bytes, content type, and error.
|
||||
// Caller must close the returned reader.
|
||||
// Returns ErrNotFound if key does not exist.
|
||||
Get(ctx context.Context, key string) (io.ReadCloser, int64, string, error)
|
||||
|
||||
// Delete removes the object at key.
|
||||
// No error if the key does not exist (idempotent).
|
||||
Delete(ctx context.Context, key string) error
|
||||
|
||||
// DeletePrefix removes all objects under the given prefix.
|
||||
// Used for channel deletion (bulk cleanup).
|
||||
// Example: DeletePrefix(ctx, "attachments/{channel_id}/")
|
||||
DeletePrefix(ctx context.Context, prefix string) error
|
||||
|
||||
// Exists checks if an object exists at key without reading it.
|
||||
Exists(ctx context.Context, key string) (bool, error)
|
||||
|
||||
// Healthy returns nil if the backend is operational (writable).
|
||||
Healthy(ctx context.Context) error
|
||||
|
||||
// Stats returns aggregate storage statistics.
|
||||
Stats(ctx context.Context) (*StorageStats, error)
|
||||
|
||||
// Backend returns the backend type identifier ("pvc", "s3").
|
||||
Backend() string
|
||||
}
|
||||
|
||||
// StorageStats holds aggregate storage metrics.
|
||||
type StorageStats struct {
|
||||
Backend string `json:"backend"`
|
||||
Path string `json:"path,omitempty"` // PVC only
|
||||
Endpoint string `json:"endpoint,omitempty"` // S3 only
|
||||
Bucket string `json:"bucket,omitempty"` // S3 only
|
||||
Healthy bool `json:"healthy"`
|
||||
Configured bool `json:"configured"`
|
||||
TotalFiles int64 `json:"total_files"`
|
||||
TotalBytes int64 `json:"total_bytes"`
|
||||
}
|
||||
Reference in New Issue
Block a user