simplecontent

package
v0.1.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2025 License: MIT Imports: 7 Imported by: 3

README

Simple Content Library

A reusable Go library for content management with pluggable storage backends and repository implementations.

Overview

The simplecontent package provides a clean, pluggable architecture for content management systems. It separates concerns between:

  • Domain types: Content, Object, metadata types
  • Interfaces: Service, Repository, BlobStore, EventSink, Previewer
  • Implementations: Memory, PostgreSQL, S3, filesystem storage backends

Quick Start

package main

import (
    "context"
    "log"
    
    "github.com/tendant/simple-content/pkg/simplecontent"
    "github.com/tendant/simple-content/pkg/simplecontent/repo/memory"
    "github.com/tendant/simple-content/pkg/simplecontent/storage/memory"
)

func main() {
    // Create repository and storage backends
    repo := memory.New()
    store := memorystorage.New()
    
    // Create service with functional options
    svc, err := simplecontent.New(
        simplecontent.WithRepository(repo),
        simplecontent.WithBlobStore("memory", store),
    )
    if err != nil {
        log.Fatal(err)
    }
    
    ctx := context.Background()
    
    // Create content
    content, err := svc.CreateContent(ctx, simplecontent.CreateContentRequest{
        OwnerID:     uuid.New(),
        TenantID:    uuid.New(), 
        Name:        "My Document",
        Description: "A sample document",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Create object for storage
    object, err := svc.CreateObject(ctx, simplecontent.CreateObjectRequest{
        ContentID:          content.ID,
        StorageBackendName: "memory",
        Version:            1,
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Upload data
    data := strings.NewReader("Hello, World!")
    err = svc.UploadObject(ctx, object.ID, data)
    if err != nil {
        log.Fatal(err)
    }
    
    // Download data  
    reader, err := svc.DownloadObject(ctx, object.ID)
    if err != nil {
        log.Fatal(err)
    }
    defer reader.Close()
    
    // Read downloaded content
    content, err := io.ReadAll(reader)
    fmt.Printf("Downloaded: %s\\n", content)
}

Architecture

Core Interfaces
  • Service: Main interface providing all content management operations
  • Repository: Data persistence abstraction for contents, objects, and metadata
  • BlobStore: Storage backend abstraction for binary data
  • EventSink: Event handling for lifecycle events
  • Previewer: Content preview generation
Available Implementations
Repositories
  • repo/memory: In-memory repository (testing)
  • repo/postgres: PostgreSQL repository (production)
Storage Backends
  • storage/memory: In-memory storage (testing)
  • storage/fs: Filesystem storage
  • storage/s3: S3-compatible storage
Configuration Options

The service supports functional options for configuration:

svc, err := simplecontent.New(
    simplecontent.WithRepository(postgresRepo),
    simplecontent.WithBlobStore("s3-primary", s3Store),
    simplecontent.WithBlobStore("s3-backup", s3BackupStore),
    simplecontent.WithBlobStore("local", fsStore),
    simplecontent.WithEventSink(eventSink),
    simplecontent.WithPreviewer(previewer),
)

Features

  • Pluggable architecture: Swap repositories and storage backends easily
  • Multi-tenant: Built-in tenant isolation
  • Versioning: Support for content versions
  • Metadata management: Rich metadata support for content and objects
  • Event system: Lifecycle event notifications
  • Preview generation: Extensible preview system
  • Error handling: Typed errors for better error handling

Metadata Strategy

The library uses a hybrid metadata approach:

  • First-class fields capture common, structured attributes directly on domain types (e.g., Content.Name, Content.Description, Object.ObjectType, ContentMetadata.FileName, ContentMetadata.MimeType). These fields are authoritative for their respective values.
  • Flexible JSON maps (ContentMetadata.Metadata, ObjectMetadata.Metadata) accommodate extensible, application-specific attributes. Prefer namespaced keys as needed to avoid collisions.
  • Avoid duplicating authoritative values in the JSON map. If mirroring is desired for compatibility, treat first-class fields as the source of truth and ensure the JSON copy is consistent.
  • Standard keys when present in metadata JSON: mime_type, file_name, file_size, etag, plus additional backend-provided attributes. Applications can add custom keys (e.g., category, priority).

Derived Content Typing

  • Derivation type (user-facing): stored on derived Content.DerivationType (e.g., thumbnail, preview, transcode). Omitted for originals.
  • Variant (specific): stored on the content_derived relationship (DB column variant), e.g., thumbnail_256, thumbnail_720, conversion.
  • All keyword values use lowercase to minimize typos and normalization overhead. If only variant is provided when creating derived content, the service infers derivation_type from the variant prefix.
Typed constants

For clarity and IDE hints, typed string constants are provided:

  • Content statuses: simplecontent.ContentStatus with constants like ContentStatusCreated.
  • Object statuses: simplecontent.ObjectStatus with constants like ObjectStatusUploaded.
  • Derivation:
    • Variant: simplecontent.DerivationVariant (e.g., VariantThumbnail256).

Struct fields remain string for compatibility. You can extend by declaring your own typed constants:

const VariantThumbnail1024 simplecontent.DerivationVariant = "thumbnail_1024"

Use Cases

  • Document management systems
  • Media asset management
  • File storage services
  • Content delivery platforms
  • Multi-tenant SaaS applications

Testing

The library includes in-memory implementations perfect for testing:

func TestMyFeature(t *testing.T) {
    repo := memory.New()
    store := memorystorage.New()
    
    svc, _ := simplecontent.New(
        simplecontent.WithRepository(repo),
        simplecontent.WithBlobStore("test", store),
    )
    
    // Test your code...
}

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

View Source
const (
	ContentDerivationTypeOriginal = "original"
	ContentDerivationTypeDerived  = "derived"
)

Content derivation type constants

Variables

View Source
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 CountDerivedContent added in v0.1.9

func CountDerivedContent(ctx context.Context, svc Service, params ListDerivedContentParams) (int64, error)

CountDerivedContent counts derived content matching the given parameters. This is a convenience function that uses the service's ListDerivedContent method. Deprecated: Use svc.ListDerivedContent with appropriate options instead.

func DerivationTypeFromVariant added in v0.1.1

func DerivationTypeFromVariant(variant string) string

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

func NormalizeDerivationType(s string) string

NormalizeDerivationType lowercases a user-facing derivation type.

func UploadObjectSimple added in v0.1.9

func UploadObjectSimple(ctx context.Context, svc Service, objectID uuid.UUID, reader io.Reader) error

UploadObjectSimple uploads an object without metadata (backward compatibility). This is a convenience function that uses the service's UploadObject method.

func UploadObjectWithMimeType added in v0.1.9

func UploadObjectWithMimeType(ctx context.Context, svc Service, objectID uuid.UUID, reader io.Reader, mimeType string) error

UploadObjectWithMimeType uploads an object with a specific MIME type. This is a convenience function that uses the service's UploadObject method.

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

type ContentError struct {
	ContentID uuid.UUID
	Op        string
	Err       error
}

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
	Variant            string // NEW: Specific variant (e.g., "thumbnail_256")
	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 {
	// Persisted fields
	ParentID           uuid.UUID              `json:"parent_id" db:"parent_id"`
	ContentID          uuid.UUID              `json:"content_id" db:"content_id"`
	DerivationType     string                 `json:"derivation_type" db:"derivation_type"`
	Variant            string                 `json:"variant" db:"variant"` // NEW: Specific variant (persisted)
	DerivationParams   map[string]interface{} `json:"derivation_params" db:"derivation_params"`
	ProcessingMetadata map[string]interface{} `json:"processing_metadata" db:"processing_metadata"`
	CreatedAt          time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time              `json:"updated_at" db:"updated_at"`
	DocumentType       string                 `json:"document_type" db:"document_type"`
	Status             string                 `json:"status" db:"status"`

	// Computed fields (not persisted - populated by service layer)
	DownloadURL  string `json:"download_url,omitempty" db:"-"`
	PreviewURL   string `json:"preview_url,omitempty" db:"-"`
	ThumbnailURL string `json:"thumbnail_url,omitempty" db:"-"`

	// Optional enhanced data (not persisted - populated on demand)
	Objects       []*Object        `json:"objects,omitempty" db:"-"`
	Metadata      *ContentMetadata `json:"metadata,omitempty" db:"-"`
	ParentContent *Content         `json:"parent_content,omitempty" db:"-"`
}

DerivedContent represents content derived from a parent content. DerivationType here represents the category (e.g., "thumbnail", "preview"). Variant represents the specific variant (e.g., "thumbnail_256").

func GetDerivedContentWithURLs added in v0.1.9

func GetDerivedContentWithURLs(ctx context.Context, svc Service, contentID uuid.UUID) (*DerivedContent, error)

GetDerivedContentWithURLs retrieves a single derived content with URLs populated. This is a convenience function that uses the service's GetDerivedRelationship method.

func GetRecentDerived added in v0.1.9

func GetRecentDerived(ctx context.Context, svc Service, parentID uuid.UUID, since time.Time) ([]*DerivedContent, error)

GetRecentDerived retrieves derived content created after a specific time. This is a convenience function that uses the service's ListDerivedContent method.

func GetThumbnailsBySize added in v0.1.9

func GetThumbnailsBySize(ctx context.Context, svc Service, parentID uuid.UUID, sizes []string) ([]*DerivedContent, error)

GetThumbnailsBySize retrieves thumbnails of specific sizes for a parent content. This is a convenience function that uses the service's ListDerivedContent method.

func ListDerivedByTypeAndVariant added in v0.1.9

func ListDerivedByTypeAndVariant(ctx context.Context, svc Service, parentID uuid.UUID, derivationType, variant string) ([]*DerivedContent, error)

ListDerivedByTypeAndVariant retrieves derived content by specific type and variant. This is a convenience function that uses the service's ListDerivedContent method.

func ListDerivedByVariants added in v0.1.9

func ListDerivedByVariants(ctx context.Context, svc Service, parentID uuid.UUID, variants []string) ([]*DerivedContent, error)

ListDerivedByVariants retrieves derived content by specific variants. This is a convenience function that uses the service's ListDerivedContent method.

func ListDerivedContentWithURLs added in v0.1.9

func ListDerivedContentWithURLs(ctx context.Context, svc Service, params ListDerivedContentParams) ([]*DerivedContent, error)

ListDerivedContentWithURLs retrieves derived content with URLs populated. This is a convenience function that uses the service's ListDerivedContent method. Deprecated: Use svc.ListDerivedContent with WithURLs() option instead.

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

func NewLoggingEventSink(logger Logger) EventSink

NewLoggingEventSink creates a new logging event sink

func NewNoopEventSink

func NewNoopEventSink() EventSink

NewNoopEventSink creates a new no-operation event sink

type ListContentRequest

type ListContentRequest struct {
	OwnerID  uuid.UUID
	TenantID uuid.UUID
}

ListContentRequest contains parameters for listing content

type ListDerivedContentOption added in v0.1.9

type ListDerivedContentOption func(*ListDerivedContentParams)

ListDerivedContentOption represents a functional option for listing derived content

func WithContentStatus added in v0.1.9

func WithContentStatus(status string) ListDerivedContentOption

WithContentStatus sets the content status to filter by

func WithCreatedAfter added in v0.1.9

func WithCreatedAfter(t time.Time) ListDerivedContentOption

WithCreatedAfter sets the created after time filter

func WithCreatedBefore added in v0.1.9

func WithCreatedBefore(t time.Time) ListDerivedContentOption

WithCreatedBefore sets the created before time filter

func WithDerivationType added in v0.1.9

func WithDerivationType(derivationType string) ListDerivedContentOption

WithDerivationType sets the derivation type to filter by

func WithDerivationTypes added in v0.1.9

func WithDerivationTypes(derivationTypes ...string) ListDerivedContentOption

WithDerivationTypes sets multiple derivation types to filter by

func WithLimit added in v0.1.9

func WithLimit(limit int) ListDerivedContentOption

WithLimit sets the maximum number of results

func WithMetadata added in v0.1.9

func WithMetadata() ListDerivedContentOption

WithMetadata includes metadata in the response

func WithObjects added in v0.1.9

func WithObjects() ListDerivedContentOption

WithObjects includes object details in the response

func WithOffset added in v0.1.9

func WithOffset(offset int) ListDerivedContentOption

WithOffset sets the offset for pagination

func WithPagination added in v0.1.9

func WithPagination(limit, offset int) ListDerivedContentOption

WithPagination sets both limit and offset for pagination

func WithParentID added in v0.1.9

func WithParentID(parentID uuid.UUID) ListDerivedContentOption

WithParentID sets the parent ID to filter by

func WithParentIDs added in v0.1.9

func WithParentIDs(parentIDs ...uuid.UUID) ListDerivedContentOption

WithParentIDs sets multiple parent IDs to filter by

func WithSortBy added in v0.1.9

func WithSortBy(sortBy string) ListDerivedContentOption

WithSortBy sets the sort field and order

func WithTypeVariantPairs added in v0.1.9

func WithTypeVariantPairs(pairs ...TypeVariantPair) ListDerivedContentOption

WithTypeVariantPairs sets type-variant pairs to filter by

func WithURLs added in v0.1.9

func WithURLs() ListDerivedContentOption

WithURLs includes URLs in the response (DownloadURL, PreviewURL, ThumbnailURL)

func WithVariant added in v0.1.9

func WithVariant(variant string) ListDerivedContentOption

WithVariant sets the variant to filter by

func WithVariants added in v0.1.9

func WithVariants(variants ...string) ListDerivedContentOption

WithVariants sets multiple variants to filter by

type ListDerivedContentParams

type ListDerivedContentParams struct {
	// Existing fields (no breaking changes)
	ParentID       *uuid.UUID `json:"parent_id,omitempty"`
	DerivationType *string    `json:"derivation_type,omitempty"`
	Limit          *int       `json:"limit,omitempty"`
	Offset         *int       `json:"offset,omitempty"`

	// NEW: Advanced filtering fields
	ParentIDs        []uuid.UUID       `json:"parent_ids,omitempty"`
	DerivationTypes  []string          `json:"derivation_types,omitempty"`
	Variant          *string           `json:"variant,omitempty"`
	Variants         []string          `json:"variants,omitempty"`
	TypeVariantPairs []TypeVariantPair `json:"type_variant_pairs,omitempty"`
	ContentStatus    *string           `json:"content_status,omitempty"`
	CreatedAfter     *time.Time        `json:"created_after,omitempty"`
	CreatedBefore    *time.Time        `json:"created_before,omitempty"`
	SortBy           *string           `json:"sort_by,omitempty"`

	// NEW: URL and metadata inclusion options
	IncludeURLs     bool `json:"include_urls"`
	IncludeObjects  bool `json:"include_objects"`
	IncludeMetadata bool `json:"include_metadata"`
}

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

func (l *LoggingEventSink) ContentDeleted(ctx context.Context, contentID uuid.UUID) error

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

func (l *LoggingEventSink) ObjectDeleted(ctx context.Context, objectID uuid.UUID) error

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

func (n *NoopEventSink) ContentDeleted(ctx context.Context, contentID uuid.UUID) error

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

func (n *NoopEventSink) ObjectDeleted(ctx context.Context, objectID uuid.UUID) error

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

type ObjectError struct {
	ObjectID uuid.UUID
	Op       string
	Err      error
}

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

func WithBlobStore(name string, store BlobStore) Option

WithBlobStore adds a blob storage backend

func WithEventSink

func WithEventSink(sink EventSink) Option

WithEventSink sets the event sink for the service

func WithPreviewer

func WithPreviewer(previewer Previewer) Option

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)
	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, req UploadObjectRequest) 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 operations
	CreateDerivedContent(ctx context.Context, req CreateDerivedContentRequest) (*Content, error)
	GetDerivedRelationship(ctx context.Context, contentID uuid.UUID) (*DerivedContent, error)
	ListDerivedContent(ctx context.Context, options ...ListDerivedContentOption) ([]*DerivedContent, error)
}

Service defines the main interface for the simple-content library

func New

func New(options ...Option) (Service, error)

New creates a new service instance with the given options

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

type StorageError struct {
	Backend string
	Key     string
	Op      string
	Err     error
}

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 TypeVariantPair added in v0.1.8

type TypeVariantPair struct {
	DerivationType string `json:"derivation_type"`
	Variant        string `json:"variant"`
}

TypeVariantPair represents a specific derivation type and variant combination

type UpdateContentRequest

type UpdateContentRequest struct {
	Content *Content
}

UpdateContentRequest contains parameters for updating content

type UploadObjectRequest added in v0.1.9

type UploadObjectRequest struct {
	ObjectID uuid.UUID
	Reader   io.Reader
	MimeType string // Optional - for metadata
}

UploadObjectRequest contains parameters for uploading an object

type UploadObjectWithMetadataRequest

type UploadObjectWithMetadataRequest struct {
	ObjectID uuid.UUID
	MimeType string
}

UploadObjectWithMetadataRequest is deprecated - use UploadObjectRequest instead

type UploadParams

type UploadParams struct {
	ObjectKey string
	MimeType  string
}

UploadParams contains parameters for uploading an object

Directories

Path Synopsis
repo
storage
fs
s3

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL