Versions in this module Expand all Collapse all v0 v0.3.0 Aug 24, 2026 Changes in this version + func BuildStorageKey(householdID identity.HouseholdID, class domain.PhotoClass, sum, ext string) (string, error) + func ExtensionForContentType(contentType string) (ext string, ok bool) + type ExifReader struct + func NewExifReader() ExifReader + func (ExifReader) Scrub(data []byte, orientation int) ([]byte, error) + func (ExifReader) TakenAt(r domain.RandomAccessReader) (taken *time.Time) + func (ExifReader) TakenAtAndOrientation(data []byte) (taken *time.Time, orientation int) + type LocalPhotoStore struct + func NewLocalPhotoStore(root string, maxUploadBytes int64) (*LocalPhotoStore, error) + func (s *LocalPhotoStore) Delete(_ context.Context, ref domain.StorageRef) error + func (s *LocalPhotoStore) Open(_ context.Context, ref domain.StorageRef) (domain.PhotoReader, error) + func (s *LocalPhotoStore) Put(_ context.Context, householdID identity.HouseholdID, class domain.PhotoClass, ...) (domain.PutResult, error) + func (s *LocalPhotoStore) SupportsDirectURL() bool + func (s *LocalPhotoStore) URL(_ context.Context, ref domain.StorageRef, _ time.Duration) (string, error) + type PhotoRepository struct + func NewPhotoRepository(dbtx db.TX, backend domain.StorageBackend) *PhotoRepository + func (r *PhotoRepository) Create(ctx context.Context, photo *domain.Photo) error + func (r *PhotoRepository) Delete(ctx context.Context, id domain.PhotoID) error + func (r *PhotoRepository) ExistsByStorageRef(ctx context.Context, ref domain.StorageRef, backend domain.StorageBackend) (bool, error) + func (r *PhotoRepository) FindByContentHash(ctx context.Context, householdID identity.HouseholdID, hash string) (*domain.Photo, error) + func (r *PhotoRepository) Get(ctx context.Context, id domain.PhotoID) (*domain.Photo, error) + func (r *PhotoRepository) ListAllStorageRefs(ctx context.Context, backend domain.StorageBackend) ([]domain.StorageRef, error) + func (r *PhotoRepository) ListByBackend(ctx context.Context, backend domain.StorageBackend, afterID domain.PhotoID, ...) ([]*domain.Photo, error) + func (r *PhotoRepository) ListByHousehold(ctx context.Context, householdID identity.HouseholdID) ([]*domain.Photo, error) + func (r *PhotoRepository) MigrateStorageBackend(ctx context.Context, id domain.PhotoID, newRef domain.StorageRef, ...) (bool, error) + type S3Params struct + AccessKeyID string + Bucket string + Endpoint string + MaxUploadBytes int64 + PresignTTL time.Duration + Region string + SecretAccessKey string + UsePathStyle bool + type S3PhotoStore struct + func NewS3PhotoStore(ctx context.Context, params S3Params) (*S3PhotoStore, error) + func (s *S3PhotoStore) Delete(ctx context.Context, ref domain.StorageRef) error + func (s *S3PhotoStore) ListObjects(ctx context.Context, class domain.PhotoClass) ([]domain.ObjectInfo, error) + func (s *S3PhotoStore) ObjectExists(ctx context.Context, ref domain.StorageRef) (bool, error) + func (s *S3PhotoStore) Open(ctx context.Context, ref domain.StorageRef) (domain.PhotoReader, error) + func (s *S3PhotoStore) Put(ctx context.Context, householdID identity.HouseholdID, class domain.PhotoClass, ...) (domain.PutResult, error) + func (s *S3PhotoStore) PutAt(ctx context.Context, ref domain.StorageRef, contentType string, r io.Reader) error + func (s *S3PhotoStore) SupportsDirectURL() bool + func (s *S3PhotoStore) URL(ctx context.Context, ref domain.StorageRef, ttl time.Duration) (string, error) + type StoreResolver struct + func NewStoreResolver(stores map[domain.StorageBackend]domain.PhotoStore) *StoreResolver + func (r *StoreResolver) Resolve(backend domain.StorageBackend) (domain.PhotoStore, error)