Permanently deleting a photo whose album was deleted failed because authorization resolved through the album. Fall back to uploader ownership when the photo is albumless. Add a bulk DELETE /trash that removes every trashed photo the caller may delete (uncapped listing) and returns the deleted count, with an «Очистить корзину» action on the trash screen.
69 lines
3.5 KiB
Go
69 lines
3.5 KiB
Go
package photos
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"galo/internal/models"
|
|
)
|
|
|
|
// TrashIdentity is the minimal fact set needed to authorize a trashed photo
|
|
// during a bulk purge without loading the full photo.
|
|
type TrashIdentity struct {
|
|
ID string
|
|
AlbumID string
|
|
UploaderID string
|
|
}
|
|
|
|
// Repository is the persistence contract for the photos domain, including the
|
|
// object ledger, variant queue and garbage collection.
|
|
type Repository interface {
|
|
CreateWithOriginal(ctx context.Context, p *models.Photo, obj *Object) error
|
|
DeleteUpload(ctx context.Context, photoID, objectID string) error
|
|
GetByID(ctx context.Context, id, viewerID string) (*models.Photo, error)
|
|
List(ctx context.Context, in ListParams) ([]models.Photo, error)
|
|
SetDeleted(ctx context.Context, id string, deleted bool) error
|
|
UpdateAlbum(ctx context.Context, id, albumID string) error
|
|
Clone(ctx context.Context, src *models.Photo, albumID, uploaderID, id string) error
|
|
HardDelete(ctx context.Context, id string) error
|
|
ListTrash(ctx context.Context, userID string) ([]models.Photo, error)
|
|
// ListTrashIdentities returns every trashed photo accessible to the user
|
|
// (no display cap) so a bulk purge can authorize and remove each one.
|
|
ListTrashIdentities(ctx context.Context, userID string) ([]TrashIdentity, error)
|
|
TrashCount(ctx context.Context, userID string) (int, error)
|
|
RestoreToAlbum(ctx context.Context, id, albumID string) error
|
|
AlbumExists(ctx context.Context, albumID string) (bool, error)
|
|
ListTags(ctx context.Context, userID, q string) ([]models.Tag, error)
|
|
EnsureTag(ctx context.Context, userID, name string) (*models.Tag, error)
|
|
AttachTag(ctx context.Context, photoID, tagID string) error
|
|
DetachTag(ctx context.Context, photoID, tagID string) error
|
|
TagOwnedBy(ctx context.Context, tagID, userID string) (bool, error)
|
|
SetCoverIfEmpty(ctx context.Context, albumID, photoID string)
|
|
ClearCoverIfMatches(ctx context.Context, albumID, photoID string)
|
|
UpdateFilename(ctx context.Context, id, filename string) error
|
|
BackfillEXIF(ctx context.Context, fetch func(context.Context, string) ([]byte, error)) (int, error)
|
|
|
|
CreateObject(ctx context.Context, o *Object) error
|
|
SetObjectState(ctx context.Context, id, state string) error
|
|
ActivateObject(ctx context.Context, id string) error
|
|
MarkObjectDeleting(ctx context.Context, id string) error
|
|
DeleteObjectRow(ctx context.Context, id string) error
|
|
BindObject(ctx context.Context, photoID, objectID, role string) error
|
|
PhotoObjectIDs(ctx context.Context, photoID string) ([]string, error)
|
|
ObjectRefCount(ctx context.Context, objectID string) (int, error)
|
|
OriginalObject(ctx context.Context, photoID string) (*Object, error)
|
|
PhotosByOriginalObject(ctx context.Context, originalObjectID string) ([]string, error)
|
|
ClaimGarbage(ctx context.Context, limit int) ([]Object, error)
|
|
ClaimStalePending(ctx context.Context, olderThan time.Duration, limit int) ([]Object, error)
|
|
// ClaimVariantJobs leases due jobs of the given kind ("" claims all kinds).
|
|
ClaimVariantJobs(ctx context.Context, kind string, limit int, lease time.Duration) ([]string, error)
|
|
CompleteVariantJob(ctx context.Context, photoID string) error
|
|
FailVariantJob(ctx context.Context, photoID, errMsg string, maxAttempts int) error
|
|
// SetMediaMeta records probed video facts: duration on the photo and frame
|
|
// dimensions on the original object.
|
|
SetMediaMeta(ctx context.Context, photoID, objectID string, durationMS int64, width, height int) error
|
|
|
|
// AllStorageKeys returns every key registered in the object journal.
|
|
AllStorageKeys(ctx context.Context) ([]string, error)
|
|
}
|