feat(12.2-01): add deferred bindings, guarded upload store and purge

- deferred_bindings migration set under summercms.deferred with backend_user_id
- lagoon.DeferredBind/Unbind/Bindings/Forget/Slaves scoped by DeferredKey
- lagoon.PurgeDeferred with SKIP LOCKED batches and after-commit blob deletes
- attach.Store with the ported image guard, extension and MIME limits
- attach.Relation, attach.HasRelations, attach.BlobKeys, File.ThumbKey
- lagoon README and attachments docs
This commit is contained in:
Jakub Zych
2026-10-02 17:36:43 +02:00
parent 79e2a43095
commit 19f4cf8232
14 changed files with 1280 additions and 15 deletions

View File

@@ -107,7 +107,10 @@ func init() {
Register(&File{})
}
func blobKeysFor(f File) []string {
// BlobKeys returns the blob keys of f: the original's partitioned key and
// the thumb_<id>_ prefix of its thumbnails. DeleteKeys treats the second as
// a prefix, so passing both removes the original and every thumbnail.
func BlobKeys(f File) []string {
part := PartitionDirectory(f.DiskName)
return []string{
part + f.DiskName,
@@ -141,7 +144,7 @@ func DeleteForOwner(tx *gorm.DB, owner Owner, ownerID string, afterCommit func(b
}
var keys []string
for _, f := range files {
keys = append(keys, blobKeysFor(f)...)
keys = append(keys, BlobKeys(f)...)
}
if err := tx.Where("attachment_type = ? AND attachment_id = ?", morph, ownerID).Delete(&File{}).Error; err != nil {
return err