package objectstorage import ( "context" "errors" "fmt" "strings" "go.uber.org/zap" "github.com/geo-platform/tenant-api/internal/shared/config" ) var ErrNotConfigured = errors.New("object storage is not configured") type Client interface { Validate() error PutBytes(ctx context.Context, objectKey string, content []byte, contentType string) error GetBytes(ctx context.Context, objectKey string) ([]byte, error) Exists(ctx context.Context, objectKey string) (bool, error) Delete(ctx context.Context, objectKey string) error PublicURL(objectKey string) (string, error) } func New(cfg config.ObjectStorageConfig, logger *zap.Logger) Client { provider := strings.ToLower(strings.TrimSpace(cfg.Provider)) switch provider { case "", "disabled": return disabledClient{reason: "object storage is disabled"} case "minio", "mino": return NewMinIOClient(cfg, logger) case "aliyun", "aliyun_oss", "aliyun-oss", "oss": return NewAliyunClient(cfg, logger) default: return disabledClient{reason: fmt.Sprintf("unsupported object storage provider %q", cfg.Provider)} } } type disabledClient struct { reason string } func (c disabledClient) Validate() error { if c.reason == "" { c.reason = "missing object storage configuration" } return fmt.Errorf("%w: %s", ErrNotConfigured, c.reason) } func (c disabledClient) PutBytes(context.Context, string, []byte, string) error { return c.Validate() } func (c disabledClient) GetBytes(context.Context, string) ([]byte, error) { return nil, c.Validate() } func (c disabledClient) Exists(context.Context, string) (bool, error) { return false, c.Validate() } func (c disabledClient) Delete(context.Context, string) error { return c.Validate() } func (c disabledClient) PublicURL(string) (string, error) { return "", c.Validate() }