Documentation
¶
Overview ¶
Package simplecontent provides a reusable library for content and object management with pluggable repository and blob storage backends.
It exposes a single Service interface that orchestrates creation of content and objects, object upload/download, metadata management, and optional event/preview integrations. Implementations of repositories (e.g., memory, Postgres) and blob stores (e.g., memory, filesystem, S3) are provided under subpackages.
Metadata Strategy ¶
First-class fields represent authoritative, common attributes on domain models (e.g., Content.Name, Content.Description, Object.ObjectType). Extensible attributes are stored in JSON maps (ContentMetadata.Metadata, ObjectMetadata.Metadata). Avoid duplicating authoritative values in the JSON maps; if mirroring is needed for compatibility, treat the first-class fields as the source of truth.
Index ¶
- Constants
- Variables
- func DerivationTypeFromVariant(variant string) string
- func NormalizeDerivationType(s string) string
- type BasicImagePreviewer
- type BlobStore
- type Content
- type ContentError
- type ContentMetadata
- type ContentStatus
- type CreateContentRequest
- type CreateDerivedContentParams
- type CreateDerivedContentRequest
- type CreateObjectRequest
- type DerivationVariant
- type DerivedContent
- type EventSink
- type ListContentRequest
- type ListDerivedContentParams
- type Logger
- type LoggingEventSink
- func (l *LoggingEventSink) ContentCreated(ctx context.Context, content *Content) error
- func (l *LoggingEventSink) ContentDeleted(ctx context.Context, contentID uuid.UUID) error
- func (l *LoggingEventSink) ContentUpdated(ctx context.Context, content *Content) error
- func (l *LoggingEventSink) ObjectCreated(ctx context.Context, object *Object) error
- func (l *LoggingEventSink) ObjectDeleted(ctx context.Context, objectID uuid.UUID) error
- func (l *LoggingEventSink) ObjectUploaded(ctx context.Context, object *Object) error
- type NoopEventSink
- func (n *NoopEventSink) ContentCreated(ctx context.Context, content *Content) error
- func (n *NoopEventSink) ContentDeleted(ctx context.Context, contentID uuid.UUID) error
- func (n *NoopEventSink) ContentUpdated(ctx context.Context, content *Content) error
- func (n *NoopEventSink) ObjectCreated(ctx context.Context, object *Object) error
- func (n *NoopEventSink) ObjectDeleted(ctx context.Context, objectID uuid.UUID) error
- func (n *NoopEventSink) ObjectUploaded(ctx context.Context, object *Object) error
- type NoopPreviewer
- type Object
- type ObjectError
- type ObjectMeta
- type ObjectMetadata
- type ObjectPreview
- type ObjectStatus
- type Option
- type Previewer
- type Repository
- type Service
- type SetContentMetadataRequest
- type StorageBackend
- type StorageError
- type UpdateContentRequest
- type UploadObjectWithMetadataRequest
- type UploadParams
Constants ¶
const ( ContentDerivationTypeOriginal = "original" ContentDerivationTypeDerived = "derived" )
Content derivation type constants
Variables ¶
var ( // ErrContentNotFound indicates a content was not found ErrContentNotFound = errors.New("content not found") // ErrObjectNotFound indicates an object was not found ErrObjectNotFound = errors.New("object not found") // ErrStorageBackendNotFound indicates a storage backend was not found ErrStorageBackendNotFound = errors.New("storage backend not found") // ErrInvalidContentStatus indicates an invalid content status ErrInvalidContentStatus = errors.New("invalid content status") // ErrInvalidObjectStatus indicates an invalid object status ErrInvalidObjectStatus = errors.New("invalid object status") // ErrUploadFailed indicates an upload operation failed ErrUploadFailed = errors.New("upload failed") // ErrDownloadFailed indicates a download operation failed ErrDownloadFailed = errors.New("download failed") )
Error types
Functions ¶
func DerivationTypeFromVariant ¶ added in v0.1.1
DerivationTypeFromVariant infers a derivation type from a variant by taking the prefix before the first underscore. If no underscore exists, the entire variant string is returned.
func NormalizeDerivationType ¶ added in v0.1.1
NormalizeDerivationType lowercases a user-facing derivation type.
Types ¶
type BasicImagePreviewer ¶
type BasicImagePreviewer struct {
// contains filtered or unexported fields
}
BasicImagePreviewer is a simple previewer that generates preview URLs for common image types
func (*BasicImagePreviewer) GeneratePreview ¶
func (b *BasicImagePreviewer) GeneratePreview(ctx context.Context, object *Object, blobStore BlobStore) (*ObjectPreview, error)
GeneratePreview generates a preview for supported image types
func (*BasicImagePreviewer) SupportsContent ¶
func (b *BasicImagePreviewer) SupportsContent(mimeType string) bool
SupportsContent returns true if the MIME type is a supported image type
type BlobStore ¶
type BlobStore interface {
// GetUploadURL returns a URL for uploading content
GetUploadURL(ctx context.Context, objectKey string) (string, error)
// Upload uploads content directly
Upload(ctx context.Context, objectKey string, reader io.Reader) error
// UploadWithParams uploads content with additional parameters
UploadWithParams(ctx context.Context, reader io.Reader, params UploadParams) error
// GetDownloadURL returns a URL for downloading content
GetDownloadURL(ctx context.Context, objectKey string, downloadFilename string) (string, error)
// GetPreviewURL returns a URL for previewing content
GetPreviewURL(ctx context.Context, objectKey string) (string, error)
// Download downloads content directly
Download(ctx context.Context, objectKey string) (io.ReadCloser, error)
// Delete deletes content
Delete(ctx context.Context, objectKey string) error
// GetObjectMeta retrieves metadata for an object
GetObjectMeta(ctx context.Context, objectKey string) (*ObjectMeta, error)
}
BlobStore defines the interface for storage backends
type Content ¶
type Content struct {
ID uuid.UUID `json:"id"`
TenantID uuid.UUID `json:"tenant_id"`
OwnerID uuid.UUID `json:"owner_id"`
OwnerType string `json:"owner_type,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
DocumentType string `json:"document_type,omitempty"`
Status string `json:"status"`
DerivationType string `json:"derivation_type,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`
}
Content represents a logical content entity.
For derived content, the DerivationType field holds the user-facing derivation type (e.g., "thumbnail", "preview"). Specific variant (e.g., "thumbnail_256") is tracked in the derived-content relationship.
type ContentError ¶
ContentError represents an error related to content operations
func (*ContentError) Error ¶
func (e *ContentError) Error() string
func (*ContentError) Unwrap ¶
func (e *ContentError) Unwrap() error
type ContentMetadata ¶
type ContentMetadata struct {
ContentID uuid.UUID `json:"content_id"`
Tags []string `json:"tags,omitempty"`
FileSize int64 `json:"file_size,omitempty"`
FileName string `json:"file_name,omitempty"`
MimeType string `json:"mime_type"`
Checksum string `json:"checksum,omitempty"`
ChecksumAlgorithm string `json:"checksum_algorithm,omitempty"`
Metadata map[string]interface{} `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
ContentMetadata represents metadata for a content
type ContentStatus ¶ added in v0.1.1
type ContentStatus string
ContentStatus is the domain type for content lifecycle states.
const ( ContentStatusCreated ContentStatus = "created" ContentStatusUploaded ContentStatus = "uploaded" ContentStatusDeleted ContentStatus = "deleted" )
Content status constants (typed).
type CreateContentRequest ¶
type CreateContentRequest struct {
OwnerID uuid.UUID
TenantID uuid.UUID
Name string
Description string
DocumentType string
DerivationType string
}
CreateContentRequest contains parameters for creating new content
type CreateDerivedContentParams ¶
type CreateDerivedContentParams struct {
ParentID uuid.UUID
DerivedContentID uuid.UUID
DerivationType string
DerivationParams map[string]interface{}
ProcessingMetadata map[string]interface{}
}
CreateDerivedContentParams contains parameters for creating derived content relationships
type CreateDerivedContentRequest ¶
type CreateDerivedContentRequest struct {
ParentID uuid.UUID
OwnerID uuid.UUID
TenantID uuid.UUID
DerivationType string
Variant string
Metadata map[string]interface{}
}
CreateDerivedContentRequest contains parameters for creating derived content.
DerivationType is the user-facing derivation type stored on the derived Content (e.g., "thumbnail", "preview", "transcode"). Variant is the specific derivation (e.g., "thumbnail_256"). If Variant is provided and DerivationType is empty, the service infers DerivationType from the prefix before the first underscore in Variant.
type CreateObjectRequest ¶
type CreateObjectRequest struct {
ContentID uuid.UUID
StorageBackendName string
Version int
ObjectKey string
}
CreateObjectRequest contains parameters for creating an object
type DerivationVariant ¶ added in v0.1.1
type DerivationVariant string
DerivationVariant is the specific variant within a category (e.g., "thumbnail_256").
const ( VariantThumbnail720 DerivationVariant = "thumbnail_720" VariantThumbnail480 DerivationVariant = "thumbnail_480" VariantThumbnail256 DerivationVariant = "thumbnail_256" VariantThumbnail128 DerivationVariant = "thumbnail_128" VariantConversion DerivationVariant = "conversion" )
Derivation variant constants (typed).
func NormalizeVariant ¶ added in v0.1.1
func NormalizeVariant(s string) DerivationVariant
NormalizeVariant lowercases a specific derivation variant.
type DerivedContent ¶
type DerivedContent struct {
ParentID uuid.UUID `json:"parent_id"`
ContentID uuid.UUID `json:"content_id"`
DerivationType string `json:"derivation_type"`
DerivationParams map[string]interface{} `json:"derivation_params"`
ProcessingMetadata map[string]interface{} `json:"processing_metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DocumentType string `json:"document_type"`
Status string `json:"status"`
}
DerivedContent represents content derived from a parent content. DerivationType here represents the specific variant (e.g., "thumbnail_256").
type EventSink ¶
type EventSink interface {
// ContentCreated is fired when content is created
ContentCreated(ctx context.Context, content *Content) error
// ContentUpdated is fired when content is updated
ContentUpdated(ctx context.Context, content *Content) error
// ContentDeleted is fired when content is deleted
ContentDeleted(ctx context.Context, contentID uuid.UUID) error
// ObjectCreated is fired when an object is created
ObjectCreated(ctx context.Context, object *Object) error
// ObjectUploaded is fired when an object is uploaded
ObjectUploaded(ctx context.Context, object *Object) error
// ObjectDeleted is fired when an object is deleted
ObjectDeleted(ctx context.Context, objectID uuid.UUID) error
}
EventSink defines the interface for event handling
func NewLoggingEventSink ¶
NewLoggingEventSink creates a new logging event sink
func NewNoopEventSink ¶
func NewNoopEventSink() EventSink
NewNoopEventSink creates a new no-operation event sink
type ListContentRequest ¶
ListContentRequest contains parameters for listing content
type ListDerivedContentParams ¶
type ListDerivedContentParams struct {
ParentID *uuid.UUID
DerivationType *string
Limit *int
Offset *int
}
ListDerivedContentParams contains parameters for listing derived content
type Logger ¶
type Logger interface {
Infof(format string, args ...interface{})
Errorf(format string, args ...interface{})
}
Logger interface for logging events
type LoggingEventSink ¶
type LoggingEventSink struct {
// contains filtered or unexported fields
}
LoggingEventSink is an event sink that logs events but takes no other action Useful for development and debugging
func (*LoggingEventSink) ContentCreated ¶
func (l *LoggingEventSink) ContentCreated(ctx context.Context, content *Content) error
ContentCreated logs the content creation event
func (*LoggingEventSink) ContentDeleted ¶
ContentDeleted logs the content deletion event
func (*LoggingEventSink) ContentUpdated ¶
func (l *LoggingEventSink) ContentUpdated(ctx context.Context, content *Content) error
ContentUpdated logs the content update event
func (*LoggingEventSink) ObjectCreated ¶
func (l *LoggingEventSink) ObjectCreated(ctx context.Context, object *Object) error
ObjectCreated logs the object creation event
func (*LoggingEventSink) ObjectDeleted ¶
ObjectDeleted logs the object deletion event
func (*LoggingEventSink) ObjectUploaded ¶
func (l *LoggingEventSink) ObjectUploaded(ctx context.Context, object *Object) error
ObjectUploaded logs the object upload event
type NoopEventSink ¶
type NoopEventSink struct{}
NoopEventSink is a no-operation implementation of EventSink Useful for production when you don't need event handling or for testing
func (*NoopEventSink) ContentCreated ¶
func (n *NoopEventSink) ContentCreated(ctx context.Context, content *Content) error
ContentCreated does nothing and returns nil
func (*NoopEventSink) ContentDeleted ¶
ContentDeleted does nothing and returns nil
func (*NoopEventSink) ContentUpdated ¶
func (n *NoopEventSink) ContentUpdated(ctx context.Context, content *Content) error
ContentUpdated does nothing and returns nil
func (*NoopEventSink) ObjectCreated ¶
func (n *NoopEventSink) ObjectCreated(ctx context.Context, object *Object) error
ObjectCreated does nothing and returns nil
func (*NoopEventSink) ObjectDeleted ¶
ObjectDeleted does nothing and returns nil
func (*NoopEventSink) ObjectUploaded ¶
func (n *NoopEventSink) ObjectUploaded(ctx context.Context, object *Object) error
ObjectUploaded does nothing and returns nil
type NoopPreviewer ¶
type NoopPreviewer struct{}
NoopPreviewer is a no-operation implementation of Previewer Always returns nil (no preview generated) and supports no content types
func (*NoopPreviewer) GeneratePreview ¶
func (n *NoopPreviewer) GeneratePreview(ctx context.Context, object *Object, blobStore BlobStore) (*ObjectPreview, error)
GeneratePreview always returns nil (no preview generated)
func (*NoopPreviewer) SupportsContent ¶
func (n *NoopPreviewer) SupportsContent(mimeType string) bool
SupportsContent always returns false (supports no content types)
type Object ¶
type Object struct {
ID uuid.UUID `json:"id"`
ContentID uuid.UUID `json:"content_id"`
StorageBackendName string `json:"storage_backend_name"`
StorageClass string `json:"storage_class,omitempty"`
ObjectKey string `json:"object_key"`
FileName string `json:"file_name,omitempty"`
Version int `json:"version"`
ObjectType string `json:"object_type,omitempty"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`
}
Object represents a physical object stored in a storage backend
type ObjectError ¶
ObjectError represents an error related to object operations
func (*ObjectError) Error ¶
func (e *ObjectError) Error() string
func (*ObjectError) Unwrap ¶
func (e *ObjectError) Unwrap() error
type ObjectMeta ¶
type ObjectMeta struct {
Key string
Size int64
ContentType string
UpdatedAt time.Time
ETag string
Metadata map[string]string
}
ObjectMeta contains metadata about an object in storage
type ObjectMetadata ¶
type ObjectMetadata struct {
ObjectID uuid.UUID `json:"object_id"`
SizeBytes int64 `json:"size_bytes"`
MimeType string `json:"mime_type"`
ETag string `json:"etag,omitempty"`
Metadata map[string]interface{} `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
ObjectMetadata represents metadata about an object
type ObjectPreview ¶
type ObjectPreview struct {
ID uuid.UUID `json:"id"`
ObjectID uuid.UUID `json:"object_id"`
PreviewType string `json:"preview_type"`
Status string `json:"status"`
PreviewURL string `json:"preview_url"`
CreatedAt time.Time `json:"created_at"`
}
ObjectPreview represents a preview generated from an object
type ObjectStatus ¶ added in v0.1.1
type ObjectStatus string
ObjectStatus is the domain type for object lifecycle states.
const ( ObjectStatusCreated ObjectStatus = "created" ObjectStatusUploading ObjectStatus = "uploading" ObjectStatusUploaded ObjectStatus = "uploaded" ObjectStatusProcessing ObjectStatus = "processing" ObjectStatusProcessed ObjectStatus = "processed" ObjectStatusFailed ObjectStatus = "failed" ObjectStatusDeleted ObjectStatus = "deleted" )
Object status constants (typed).
type Option ¶
type Option func(*service)
Option represents a functional option for configuring the service
func WithBlobStore ¶
WithBlobStore adds a blob storage backend
func WithEventSink ¶
WithEventSink sets the event sink for the service
func WithPreviewer ¶
WithPreviewer sets the previewer for the service
func WithRepository ¶
func WithRepository(repo Repository) Option
WithRepository sets the repository for the service
type Previewer ¶
type Previewer interface {
// GeneratePreview generates a preview for the given object
GeneratePreview(ctx context.Context, object *Object, blobStore BlobStore) (*ObjectPreview, error)
// SupportsContent returns true if the previewer supports the given content type
SupportsContent(mimeType string) bool
}
Previewer defines the interface for content preview generation
func NewBasicImagePreviewer ¶
func NewBasicImagePreviewer() Previewer
NewBasicImagePreviewer creates a new basic image previewer
func NewNoopPreviewer ¶
func NewNoopPreviewer() Previewer
NewNoopPreviewer creates a new no-operation previewer
type Repository ¶
type Repository interface {
// Content operations
CreateContent(ctx context.Context, content *Content) error
GetContent(ctx context.Context, id uuid.UUID) (*Content, error)
UpdateContent(ctx context.Context, content *Content) error
DeleteContent(ctx context.Context, id uuid.UUID) error
ListContent(ctx context.Context, ownerID, tenantID uuid.UUID) ([]*Content, error)
// Content metadata operations
SetContentMetadata(ctx context.Context, metadata *ContentMetadata) error
GetContentMetadata(ctx context.Context, contentID uuid.UUID) (*ContentMetadata, error)
// Derived content operations
CreateDerivedContentRelationship(ctx context.Context, params CreateDerivedContentParams) (*DerivedContent, error)
ListDerivedContent(ctx context.Context, params ListDerivedContentParams) ([]*DerivedContent, error)
// GetDerivedRelationshipByContentID returns the derived-content relationship for a given derived content ID
GetDerivedRelationshipByContentID(ctx context.Context, contentID uuid.UUID) (*DerivedContent, error)
// Object operations
CreateObject(ctx context.Context, object *Object) error
GetObject(ctx context.Context, id uuid.UUID) (*Object, error)
GetObjectsByContentID(ctx context.Context, contentID uuid.UUID) ([]*Object, error)
GetObjectByObjectKeyAndStorageBackendName(ctx context.Context, objectKey, storageBackendName string) (*Object, error)
UpdateObject(ctx context.Context, object *Object) error
DeleteObject(ctx context.Context, id uuid.UUID) error
// Object metadata operations
SetObjectMetadata(ctx context.Context, metadata *ObjectMetadata) error
GetObjectMetadata(ctx context.Context, objectID uuid.UUID) (*ObjectMetadata, error)
}
Repository defines the interface for content and object persistence
type Service ¶
type Service interface {
// Content operations
CreateContent(ctx context.Context, req CreateContentRequest) (*Content, error)
CreateDerivedContent(ctx context.Context, req CreateDerivedContentRequest) (*Content, error)
GetContent(ctx context.Context, id uuid.UUID) (*Content, error)
UpdateContent(ctx context.Context, req UpdateContentRequest) error
DeleteContent(ctx context.Context, id uuid.UUID) error
ListContent(ctx context.Context, req ListContentRequest) ([]*Content, error)
// Content metadata operations
SetContentMetadata(ctx context.Context, req SetContentMetadataRequest) error
GetContentMetadata(ctx context.Context, contentID uuid.UUID) (*ContentMetadata, error)
// Object operations
CreateObject(ctx context.Context, req CreateObjectRequest) (*Object, error)
GetObject(ctx context.Context, id uuid.UUID) (*Object, error)
GetObjectsByContentID(ctx context.Context, contentID uuid.UUID) ([]*Object, error)
UpdateObject(ctx context.Context, object *Object) error
DeleteObject(ctx context.Context, id uuid.UUID) error
// Object upload/download operations
UploadObject(ctx context.Context, id uuid.UUID, reader io.Reader) error
UploadObjectWithMetadata(ctx context.Context, reader io.Reader, req UploadObjectWithMetadataRequest) error
DownloadObject(ctx context.Context, id uuid.UUID) (io.ReadCloser, error)
GetUploadURL(ctx context.Context, id uuid.UUID) (string, error)
GetDownloadURL(ctx context.Context, id uuid.UUID) (string, error)
GetPreviewURL(ctx context.Context, id uuid.UUID) (string, error)
// Object metadata operations
SetObjectMetadata(ctx context.Context, objectID uuid.UUID, metadata map[string]interface{}) error
GetObjectMetadata(ctx context.Context, objectID uuid.UUID) (map[string]interface{}, error)
UpdateObjectMetaFromStorage(ctx context.Context, objectID uuid.UUID) (*ObjectMetadata, error)
// Storage backend operations
RegisterBackend(name string, backend BlobStore)
GetBackend(name string) (BlobStore, error)
// Derived content relationship helpers
GetDerivedRelationshipByContentID(ctx context.Context, contentID uuid.UUID) (*DerivedContent, error)
ListDerivedByParent(ctx context.Context, parentID uuid.UUID) ([]*DerivedContent, error)
}
Service defines the main interface for the simple-content library
type SetContentMetadataRequest ¶
type SetContentMetadataRequest struct {
ContentID uuid.UUID
ContentType string
Title string
Description string
Tags []string
FileName string
FileSize int64
CreatedBy string
CustomMetadata map[string]interface{}
}
SetContentMetadataRequest contains parameters for setting content metadata
type StorageBackend ¶
type StorageBackend struct {
Name string `json:"name"`
Type string `json:"type"`
Config map[string]interface{} `json:"config"`
IsActive bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
StorageBackend represents a configurable storage backend
type StorageError ¶
StorageError represents an error related to storage operations
func (*StorageError) Error ¶
func (e *StorageError) Error() string
func (*StorageError) Unwrap ¶
func (e *StorageError) Unwrap() error
type UpdateContentRequest ¶
type UpdateContentRequest struct {
Content *Content
}
UpdateContentRequest contains parameters for updating content
type UploadObjectWithMetadataRequest ¶
UploadObjectWithMetadataRequest contains parameters for uploading object with metadata
type UploadParams ¶
UploadParams contains parameters for uploading an object