Documentation
¶
Overview ¶
Package attachments owns typed model collections and recoverable storage workflows. Applications declare policy once and pass typed owner references.
Index ¶
- Constants
- Variables
- func Cleanup[M any, K comparable](ctx context.Context, tx *database.Tx, m *Manager, owner extensions.Owner[M, K], ...) error
- func CleanupIdentity(ctx context.Context, tx *database.Tx, m *Manager, owner extensions.OwnerName, ...) error
- func Matching[M any, K comparable](ctx context.Context, manager *Manager, collection Collection[M, K]) (orm.Predicate[M], error)
- func Migrations() []migrate.Definition
- func Module(name foundation.ProviderID, key foundation.Key[*Manager], ...) foundation.Module
- type Attachment
- type Batch
- type BeforeContext
- type Cardinality
- type ChangeResult
- type Collection
- func (c Collection[M, K]) Add(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Result[M, K], error)
- func (c Collection[M, K]) AddFromURL(ctx context.Context, m *Manager, owner model.Reference[M, K], ...) (Result[M, K], error)
- func (c Collection[M, K]) AddIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], ...) (Result[M, K], error)
- func (c Collection[M, K]) Clear(ctx context.Context, m *Manager, owner model.Reference[M, K]) (ChangeResult, error)
- func (c Collection[M, K]) ClearIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) (ChangeResult, error)
- func (c Collection[M, K]) Detach(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (ChangeResult, error)
- func (c Collection[M, K]) DetachIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], ...) (ChangeResult, error)
- func (c Collection[M, K]) DetachKeepFile(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (RetainResult, error)
- func (c Collection[M, K]) Discard(ctx context.Context, m *Manager, prepared Prepared[M, K]) error
- func (c Collection[M, K]) Find(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (Attachment[M, K], error)
- func (c Collection[M, K]) First(ctx context.Context, m *Manager, owner model.Reference[M, K]) (value.Optional[Attachment[M, K]], error)
- func (c Collection[M, K]) FirstIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) (value.Optional[Attachment[M, K]], error)
- func (c Collection[M, K]) ForLocale(locale i18n.LocaleID) Collection[M, K]
- func (Collection[M, K]) Format(s fmt.State, _ rune)
- func (c Collection[M, K]) Image(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], ...) (imaging.Result, error)
- func (c Collection[M, K]) List(ctx context.Context, m *Manager, owner model.Reference[M, K]) ([]Attachment[M, K], error)
- func (c Collection[M, K]) ListIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) ([]Attachment[M, K], error)
- func (c Collection[M, K]) Load(ctx context.Context, m *Manager, owners []model.Reference[M, K]) (Batch[M, K], error)
- func (c Collection[M, K]) LoadLocalized(ctx context.Context, m *Manager, owners []model.Reference[M, K]) (LocalizedBatch[M, K], error)
- func (c Collection[M, K]) Name() Name
- func (c Collection[M, K]) Open(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (io.ReadCloser, Attachment[M, K], error)
- func (c Collection[M, K]) Prepare(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Prepared[M, K], error)
- func (c Collection[M, K]) PublicURL(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (string, error)
- func (c Collection[M, K]) PublicURLOf(ctx context.Context, m *Manager, file Attachment[M, K]) (string, error)
- func (c Collection[M, K]) PublicURLsOf(ctx context.Context, m *Manager, files []Attachment[M, K]) ([]string, error)
- func (c Collection[M, K]) ReadBytes(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], ...) ([]byte, error)
- func (c Collection[M, K]) RegenerateVariants(ctx context.Context, m *Manager, options RegenerationOptions) (RegenerationPage, error)
- func (c Collection[M, K]) Registration() Registration
- func (c Collection[M, K]) Reorder(ctx context.Context, m *Manager, owner model.Reference[M, K], order []ID[M]) ([]Attachment[M, K], error)
- func (c Collection[M, K]) Replace(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Result[M, K], error)
- func (c Collection[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], ...) (Result[M, K], error)
- func (c Collection[M, K]) Resolve(ctx context.Context, m *Manager, owner model.Reference[M, K], ...) (value.Optional[Resolved[M, K]], error)
- func (c Collection[M, K]) SetProperties(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], ...) (Attachment[M, K], error)
- func (c Collection[M, K]) TemporaryURL(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], ...) (storage.TemporaryURL, error)
- func (c Collection[M, K]) TemporaryURLOf(ctx context.Context, m *Manager, file Attachment[M, K], ...) (storage.TemporaryURL, error)
- func (c Collection[M, K]) Validate() error
- func (c Collection[M, K]) VariantPublicURLOf(ctx context.Context, m *Manager, file Attachment[M, K], variant Variant) (string, error)
- func (c Collection[M, K]) VariantTemporaryURLOf(ctx context.Context, m *Manager, file Attachment[M, K], variant Variant, ...) (storage.TemporaryURL, error)
- func (c Collection[M, K]) WithReconciliation(queue Queue) Collection[M, K]
- func (c Collection[M, K]) WithVariantQueue(queue VariantQueue) Collection[M, K]
- type Config
- type Cursor
- type Dependencies
- type File
- func (f File[M]) Collection() Name
- func (f File[M]) CreatedAt() temporal.DateTime
- func (f File[M]) EmailAttachment() (email.Attachment, error)
- func (File[M]) Format(s fmt.State, _ rune)
- func (f File[M]) ID() ID[M]
- func (f File[M]) Info() UploadInfo
- func (f File[M]) IsZero() bool
- func (f File[M]) Locale() value.Optional[i18n.LocaleID]
- func (File[M]) MarshalJSON() ([]byte, error)
- func (f File[M]) Position() int32
- func (f File[M]) Properties() (json.RawMessage, error)
- func (f File[M]) Variant(variant Variant) (VariantInfo, bool)
- func (f File[M]) Variants() []VariantInfo
- type FileOf
- type FileSource
- type Hook
- type ID
- type LocalizedBatch
- type LocalizedFiles
- type Manager
- func (m *Manager) Close(ctx context.Context) error
- func (m *Manager) Done() <-chan struct{}
- func (m *Manager) GenerateVariants(ctx context.Context, id OperationID) error
- func (m *Manager) Inspect(ctx context.Context, id OperationID) (ReconcileResult, error)
- func (m *Manager) InspectOrphans(ctx context.Context, owner extensions.OwnerName, cursor Cursor, limit int) (OrphanPage, error)
- func (m *Manager) InspectStorage(ctx context.Context, options StorageInspection) (StorageOrphanPage, error)
- func (m *Manager) PruneOrphans(ctx context.Context, owner extensions.OwnerName, ids []OperationID, ...) (ChangeResult, error)
- func (m *Manager) Reconcile(ctx context.Context, id OperationID) (ReconcileResult, error)
- func (m *Manager) ReconcilePending(ctx context.Context, limit int) ([]ReconcileResult, error)
- func (m *Manager) RegenerateVariants(ctx context.Context, owner extensions.OwnerName, collection Name, ...) (RegenerationPage, error)
- func (m *Manager) RetainedObject(ctx context.Context, id OperationID) (RetainedFile, error)
- func (m *Manager) Settle(ctx context.Context, id OperationID, settlement Settlement, queue *Queue) (ReconcileResult, error)
- func (m *Manager) Validate() error
- type Many
- type ManyHandle
- func (s ManyHandle[M, K]) Accepts(ctx context.Context, file FileSource) (bool, error)
- func (s ManyHandle[M, K]) Add(ctx context.Context, owner M, upload Upload) (Result[M, K], error)
- func (s ManyHandle[M, K]) AddFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
- func (s ManyHandle[M, K]) AddIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
- func (s ManyHandle[M, K]) Clear(ctx context.Context, owner M) (ChangeResult, error)
- func (s ManyHandle[M, K]) ClearIn(ctx context.Context, tx *database.Tx, owner M) (ChangeResult, error)
- func (s ManyHandle[M, K]) Describe() extensions.SlotDescription
- func (s ManyHandle[M, K]) Detach(ctx context.Context, owner M, id ID[M]) (ChangeResult, error)
- func (s ManyHandle[M, K]) Discard(ctx context.Context, prepared Prepared[M, K]) error
- func (ManyHandle[M, K]) Format(s fmt.State, _ rune)
- func (s ManyHandle[M, K]) From(m *Manager) ManyHandle[M, K]
- func (s ManyHandle[M, K]) Name() Name
- func (s ManyHandle[M, K]) Prepare(ctx context.Context, owner M, upload Upload) (Prepared[M, K], error)
- func (s ManyHandle[M, K]) PrepareFile(ctx context.Context, owner M, file FileSource) (Prepared[M, K], error)
- func (s ManyHandle[M, K]) PublicURLs(ctx context.Context, owner M) ([]string, error)
- func (s ManyHandle[M, K]) Registration() Registration
- func (s ManyHandle[M, K]) Relation(slot orm.Slot[M, Many[M]]) orm.ExtensionRelation[M]
- func (s ManyHandle[M, K]) Reorder(ctx context.Context, owner M, order []ID[M]) ([]Attachment[M, K], error)
- func (s ManyHandle[M, K]) Replace(ctx context.Context, owner M, upload Upload) (Result[M, K], error)
- func (s ManyHandle[M, K]) ReplaceFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
- func (s ManyHandle[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
- func (s ManyHandle[M, K]) TemporaryURL(ctx context.Context, owner M, file File[M], options storage.LinkOptions) (storage.TemporaryURL, error)
- func (s ManyHandle[M, K]) URL(ctx context.Context, owner M, file File[M]) (string, error)
- func (s ManyHandle[M, K]) Validate() error
- func (s ManyHandle[M, K]) VariantURL(ctx context.Context, owner M, file File[M], variant Variant) (string, error)
- type Name
- type One
- type OneHandle
- func (s OneHandle[M, K]) Accepts(ctx context.Context, file FileSource) (bool, error)
- func (s OneHandle[M, K]) Clear(ctx context.Context, owner M) (ChangeResult, error)
- func (s OneHandle[M, K]) ClearIn(ctx context.Context, tx *database.Tx, owner M) (ChangeResult, error)
- func (s OneHandle[M, K]) Describe() extensions.SlotDescription
- func (s OneHandle[M, K]) Detach(ctx context.Context, owner M, id ID[M]) (ChangeResult, error)
- func (s OneHandle[M, K]) Discard(ctx context.Context, prepared Prepared[M, K]) error
- func (OneHandle[M, K]) Format(s fmt.State, _ rune)
- func (s OneHandle[M, K]) From(m *Manager) OneHandle[M, K]
- func (s OneHandle[M, K]) Name() Name
- func (s OneHandle[M, K]) Prepare(ctx context.Context, owner M, upload Upload) (Prepared[M, K], error)
- func (s OneHandle[M, K]) PrepareFile(ctx context.Context, owner M, file FileSource) (Prepared[M, K], error)
- func (s OneHandle[M, K]) PublicURL(ctx context.Context, owner M) (value.Optional[string], error)
- func (s OneHandle[M, K]) Registration() Registration
- func (s OneHandle[M, K]) Relation(slot orm.Slot[M, One[M]]) orm.ExtensionRelation[M]
- func (s OneHandle[M, K]) Replace(ctx context.Context, owner M, upload Upload) (Result[M, K], error)
- func (s OneHandle[M, K]) ReplaceFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
- func (s OneHandle[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
- func (s OneHandle[M, K]) TemporaryURL(ctx context.Context, owner M, file File[M], options storage.LinkOptions) (storage.TemporaryURL, error)
- func (s OneHandle[M, K]) URL(ctx context.Context, owner M, file File[M]) (string, error)
- func (s OneHandle[M, K]) Validate() error
- func (s OneHandle[M, K]) VariantURL(ctx context.Context, owner M, file File[M], variant Variant) (string, error)
- type Operation
- type OperationID
- type Orphan
- type OrphanPage
- type Policy
- type Prepared
- type Publication
- type Queue
- type ReconcileJob
- type ReconcileRequest
- type ReconcileResult
- type RegenerationCursor
- type RegenerationOptions
- type RegenerationPage
- type Registration
- type RemoteSource
- type Resolved
- type Result
- type RetainResult
- type RetainedFile
- type Settlement
- type State
- type StorageCursor
- type StorageInspection
- type StorageOrphanPage
- type Undeclared
- type Upload
- type UploadInfo
- type Variant
- type VariantInfo
- type VariantJob
- type VariantName
- type VariantQueue
- type VariantRequest
- type VariantState
Constants ¶
const ( MaxUploadBytes int64 = 64 << 20 MaxCollectionFiles = 256 MaxOwnerIntents = 4096 MaxPropertiesBytes = 64 << 10 )
const ( DefaultMaxReads = 64 DefaultSettleAfter = 15 * time.Minute // MaxOwnerCleanup bounds concurrent owner-delete observers per manager. MaxOwnerCleanup = 4096 )
const ( MigrationOrigin migrate.Origin = "foundry.attachments" CreateAttachments migrate.ID = "000001_create_attachments" CreateVariants migrate.ID = "000002_create_variants" Introduced migrate.Version = "v0.1.0" )
const ( MaxBatchFiles = 4096 MaxBatchPropertiesBytes = 4 << 20 )
const MaxRegenerationBatch = 100
const (
// MaxVariants bounds declared variants per collection.
MaxVariants = 8
)
Variables ¶
var ActiveContentRefused = safeerror.Sentinel(fault.Invalid, "script-capable attachment cannot be linked inline")
ActiveContentRefused reports an inline link to a script-capable attachment (SVG, HTML, XML, JavaScript) whose policy does not set InlineActiveContent. It matches fault.Invalid.
VariantUnavailable reports a declared variant that has not been generated (yet) for an attachment, for example while its job is queued. It matches fault.Missing.
Functions ¶
func Cleanup ¶
func Cleanup[M any, K comparable](ctx context.Context, tx *database.Tx, m *Manager, owner extensions.Owner[M, K], reference model.Reference[M, K], operation lifecycle.Operation, queue *Queue) error
Cleanup joins a generated owner's transactional Deleted/ForceDeleted observer. Soft deletion preserves files for restoration. Ready/stored ownership changes and optional job outbox rows roll back with the owner. Writing/uncertain intents remain visible for settlement; they cannot be deleted based on owner absence.
func CleanupIdentity ¶
func CleanupIdentity(ctx context.Context, tx *database.Tx, m *Manager, owner extensions.OwnerName, identity model.Identity, queue *Queue) error
CleanupIdentity is Cleanup for an owner known by its registered name and persisted identity, such as a durable cleanup job's request. It joins tx, rejects an owner that still exists and deletes stored objects after commit.
func Matching ¶
func Matching[M any, K comparable](ctx context.Context, manager *Manager, collection Collection[M, K]) (orm.Predicate[M], error)
Matching materializes a bounded ORM owner predicate for ready attachments in the collection and exact locale. It uses the manager's existing matching limits, validation and cancellation. The declaration must have an ORM owner. No match produces a false predicate; the subsequent owner query retains its own fresh visibility and authorization. This is a snapshot of matching keys, not a live subquery. Example: predicate, err := attachments.Matching(ctx, manager, Avatar.ForLocale("en")); then Owners.Query().Where(predicate).
func Migrations ¶
func Migrations() []migrate.Definition
Migrations returns fresh definitions for the attachment and variant journal schema.
func Module ¶
func Module(name foundation.ProviderID, key foundation.Key[*Manager], requires []foundation.ProviderID, construct func(foundation.Resolver) (*Manager, error)) foundation.Module
Module owns the manager and requires providers owning its borrowed store, disks, image engine and locale catalog. Workers invoking it must stop first.
Types ¶
type Attachment ¶
type Attachment[M any, K comparable] struct { File[M] // contains filtered or unexported fields }
Attachment is a ready File with its typed owner reference.
func (Attachment[M, K]) Format ¶
func (Attachment[M, K]) Format(s fmt.State, _ rune)
Format writes a label without exposing attachment data.
func (Attachment[M, K]) MarshalJSON ¶
func (Attachment[M, K]) MarshalJSON() ([]byte, error)
MarshalJSON rejects implicit attachment export; construct an explicit response DTO.
func (Attachment[M, K]) Owner ¶
func (a Attachment[M, K]) Owner() model.Reference[M, K]
Owner returns the typed owner reference captured when the attachment was loaded.
type Batch ¶
type Batch[M any, K comparable] struct { // contains filtered or unexported fields }
Batch is a bounded snapshot of ready attachments and owner visibility; lookups perform no I/O.
type BeforeContext ¶
type BeforeContext[M any, K comparable] struct { Owner model.Reference[M, K] Collection Name Locale value.Optional[i18n.LocaleID] Upload UploadInfo }
BeforeContext contains detected metadata, not the caller-owned reader or a mutable image buffer. The application can authorize through Owner.Key().
type Cardinality ¶
type Cardinality uint8
Cardinality selects a single-file or multiple-file collection.
const ( Single Cardinality = iota + 1 Multiple )
type ChangeResult ¶
type ChangeResult struct {
Publication Publication
Affected int
PendingCleanup []OperationID
}
ChangeResult separates membership publication, affected rows and pending storage cleanup.
type Collection ¶
type Collection[M any, K comparable] struct { // contains filtered or unexported fields }
Collection is an immutable typed declaration with optional locale and borrowed queue bindings.
func Define ¶
func Define[M any, K comparable](owner extensions.Owner[M, K], name Name, policy Policy, hooks ...Hook[M, K]) Collection[M, K]
Define snapshots policy slices and hooks into a typed collection declaration; validation is deferred.
func ManyCollection ¶
func ManyCollection[M any, K comparable](slot ManyHandle[M, K]) Collection[M, K]
ManyCollection returns the multiple-slot declaration for explicit batch reads and matching. It preserves registration identity and policy; a zero handle returns an invalid zero collection. Example: attachments.ManyCollection(bound.Gallery).List(ctx,manager,reference).
func OneCollection ¶
func OneCollection[M any, K comparable](slot OneHandle[M, K]) Collection[M, K]
OneCollection returns the single-slot declaration for explicit collection operations. It preserves registration identity and policy; a zero handle returns an invalid zero collection. Example: attachments.OneCollection(bound.Logo).List(ctx,manager,reference).
func (Collection[M, K]) Add ¶
func (c Collection[M, K]) Add(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Result[M, K], error)
Add appends to a multiple collection and replaces a single collection.
func (Collection[M, K]) AddFromURL ¶
func (c Collection[M, K]) AddFromURL(ctx context.Context, m *Manager, owner model.Reference[M, K], source RemoteSource) (Result[M, K], error)
AddFromURL downloads one remote file within the collection's MaxBytes and adds it exactly like Add. Acceptance is detected from the downloaded bytes; the response Content-Type is only a hint. Redirects and non-2xx responses fail without adding a file. Manager admission covers the complete download, validation, storage and publication, retaining one bounded input buffer. Image processing remains subject to the image engine's separate limits.
func (Collection[M, K]) AddIn ¶
func (c Collection[M, K]) AddIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], prepared Prepared[M, K]) (Result[M, K], error)
AddIn publishes a prepared upload into owner's collection inside tx, a transaction of the extension store's pool, using only that transaction: the owner may be one tx created, and the attachment becomes visible when tx commits. A failure, including a rollback, leaves the prepared upload for Discard or ReconcilePending. Old-object cleanup and unqueued variant generation run after tx commits; their failure is the transaction's after-commit error and leaves work for ReconcilePending.
func (Collection[M, K]) Clear ¶
func (c Collection[M, K]) Clear(ctx context.Context, m *Manager, owner model.Reference[M, K]) (ChangeResult, error)
Clear retires all ready membership for the selected owner collection and attempts bounded storage cleanup after commit.
func (Collection[M, K]) ClearIn ¶ added in v0.5.2
func (c Collection[M, K]) ClearIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) (ChangeResult, error)
ClearIn retires all ready membership for the selected owner collection inside tx; see DetachIn.
func (Collection[M, K]) Detach ¶
func (c Collection[M, K]) Detach(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (ChangeResult, error)
Detach retires ready membership for id and attempts storage cleanup after commit; an absent matching id affects no rows.
func (Collection[M, K]) DetachIn ¶ added in v0.5.2
func (c Collection[M, K]) DetachIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], id ID[M]) (ChangeResult, error)
DetachIn retires ready membership for id inside tx, a transaction of the extension store's pool. It locks the owner until tx ends and joins a savepoint; a rollback preserves membership and storage. Cleanup runs only after tx commits, and its failure is the transaction's after-commit error. Published and PendingCleanup describe the pending commit, as with ReplaceIn.
func (Collection[M, K]) DetachKeepFile ¶
func (c Collection[M, K]) DetachKeepFile(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (RetainResult, error)
DetachKeepFile removes collection membership without deleting storage. The durable retained state survives owner deletion and ordinary orphan pruning.
func (Collection[M, K]) Discard ¶
Discard reclaims a prepared upload that will not be published, instead of leaving it to ReconcilePending. A published upload is refused and kept.
func (Collection[M, K]) Find ¶
func (c Collection[M, K]) Find(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (Attachment[M, K], error)
Find loads one ready attachment belonging to owner and this collection, returning not found when absent.
func (Collection[M, K]) First ¶
func (c Collection[M, K]) First(ctx context.Context, m *Manager, owner model.Reference[M, K]) (value.Optional[Attachment[M, K]], error)
First returns the first ready attachment in collection order, or an unset value for an empty collection.
func (Collection[M, K]) FirstIn ¶ added in v0.5.2
func (c Collection[M, K]) FirstIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) (value.Optional[Attachment[M, K]], error)
FirstIn returns the first ready attachment in collection order through tx, or an unset value for an empty collection; see ListIn.
func (Collection[M, K]) ForLocale ¶
func (c Collection[M, K]) ForLocale(locale i18n.LocaleID) Collection[M, K]
ForLocale returns a collection selecting locale; validation rejects locale selection for nonlocalized policies.
func (Collection[M, K]) Format ¶
func (Collection[M, K]) Format(s fmt.State, _ rune)
Format writes a label without exposing collection internals.
func (Collection[M, K]) Image ¶
func (c Collection[M, K]) Image(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], plan imaging.Plan) (imaging.Result, error)
Image reads and verifies a ready attachment within image input bounds, then applies plan without changing storage.
func (Collection[M, K]) List ¶
func (c Collection[M, K]) List(ctx context.Context, m *Manager, owner model.Reference[M, K]) ([]Attachment[M, K], error)
List returns ready attachments for owner in collection order.
func (Collection[M, K]) ListIn ¶ added in v0.5.2
func (c Collection[M, K]) ListIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K]) ([]Attachment[M, K], error)
ListIn returns ready attachments for owner in collection order through tx, a transaction of the extension store's pool, including its uncommitted changes. Reads preserve tx's isolation level and do not lock the owner; lock it before checking an invariant that a subsequent mutation must preserve.
func (Collection[M, K]) Load ¶
func (c Collection[M, K]) Load(ctx context.Context, m *Manager, owners []model.Reference[M, K]) (Batch[M, K], error)
Load snapshots owner visibility and ready attachments within the shared row and property budgets.
func (Collection[M, K]) LoadLocalized ¶
func (c Collection[M, K]) LoadLocalized(ctx context.Context, m *Manager, owners []model.Reference[M, K]) (LocalizedBatch[M, K], error)
LoadLocalized captures a catalog snapshot and loads ready attachments for owners across registered locales.
func (Collection[M, K]) Name ¶
func (c Collection[M, K]) Name() Name
Name returns the declared name, or an empty name for a zero collection.
func (Collection[M, K]) Open ¶
func (c Collection[M, K]) Open(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (io.ReadCloser, Attachment[M, K], error)
Open streams an attachment pinned to its stored ETag/version. The full SHA-256 and length are verified at EOF (by the disk when the stored checksum matches the pin, otherwise here). Only the lookup uses manager read admission; the returned reader holds one disk stream slot until Close. Always close it, and close it before closing the disk.
func (Collection[M, K]) Prepare ¶
func (c Collection[M, K]) Prepare(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Prepared[M, K], error)
Prepare reads, checks and stores upload for owner's collection without publishing it, in the manager's own transactions. Call it before the transaction that publishes it begins, so that transaction needs only its own connection and sees the stored upload. An existing owner is locked while the upload is recorded, keeping its intent bound exact; owner may also be a model the publishing transaction creates, with its key chosen beforehand. On an error the returned value names any recorded intent.
func (Collection[M, K]) PublicURL ¶
func (c Collection[M, K]) PublicURL(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M]) (string, error)
PublicURL rechecks ready membership, then derives the public URL of the pinned object. Keys are immutable per upload, so no storage request is made.
func (Collection[M, K]) PublicURLOf ¶
func (c Collection[M, K]) PublicURLOf(ctx context.Context, m *Manager, file Attachment[M, K]) (string, error)
PublicURLOf derives the public URL of an attachment already loaded through this collection (for example from Load or List) without database or storage I/O. Authorize access to the attachment first; the URL does not.
func (Collection[M, K]) PublicURLsOf ¶
func (c Collection[M, K]) PublicURLsOf(ctx context.Context, m *Manager, files []Attachment[M, K]) ([]string, error)
PublicURLsOf maps loaded attachments to public URLs in order, for listing responses. It performs no database or storage I/O.
func (Collection[M, K]) ReadBytes ¶
func (c Collection[M, K]) ReadBytes(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], maximum int64) ([]byte, error)
ReadBytes reads a ready pinned object within maximum and verifies its length and full-object digest.
func (Collection[M, K]) RegenerateVariants ¶
func (c Collection[M, K]) RegenerateVariants(ctx context.Context, m *Manager, options RegenerationOptions) (RegenerationPage, error)
RegenerateVariants processes one batch of this collection's ready attachments in ID order under one write admission slot.
func (Collection[M, K]) Registration ¶
func (c Collection[M, K]) Registration() Registration
Registration returns a manager registration; zero and locale-selected collections return an invalid registration.
func (Collection[M, K]) Reorder ¶
func (c Collection[M, K]) Reorder(ctx context.Context, m *Manager, owner model.Reference[M, K], order []ID[M]) ([]Attachment[M, K], error)
Reorder accepts an exact permutation of current ready collection IDs. No omission, duplicate or foreign ID can partially change the stored ordering.
func (Collection[M, K]) Replace ¶
func (c Collection[M, K]) Replace(ctx context.Context, m *Manager, owner model.Reference[M, K], upload Upload) (Result[M, K], error)
Replace atomically replaces the complete collection membership. Old objects are eligible for cleanup only after this ownership transaction commits.
func (Collection[M, K]) ReplaceIn ¶
func (c Collection[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, m *Manager, owner model.Reference[M, K], prepared Prepared[M, K]) (Result[M, K], error)
ReplaceIn publishes a prepared upload as owner's complete collection inside tx; see AddIn.
func (Collection[M, K]) Resolve ¶
func (c Collection[M, K]) Resolve(ctx context.Context, m *Manager, owner model.Reference[M, K], requested i18n.LocaleID) (value.Optional[Resolved[M, K]], error)
Resolve loads localized files and selects the first nonempty collection in catalog fallback order.
func (Collection[M, K]) SetProperties ¶
func (c Collection[M, K]) SetProperties(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], properties value.JSON[json.RawMessage]) (Attachment[M, K], error)
SetProperties replaces explicit dynamic object metadata, never storage pins, owner identity or collection policy.
func (Collection[M, K]) TemporaryURL ¶
func (c Collection[M, K]) TemporaryURL(ctx context.Context, m *Manager, owner model.Reference[M, K], id ID[M], expires time.Duration) (storage.TemporaryURL, error)
TemporaryURL rechecks ready membership, then signs a read link pinned to the stored version. Signing performs no storage request.
func (Collection[M, K]) TemporaryURLOf ¶
func (c Collection[M, K]) TemporaryURLOf(ctx context.Context, m *Manager, file Attachment[M, K], options storage.LinkOptions) (storage.TemporaryURL, error)
TemporaryURLOf signs a read link for a loaded attachment, pinned to its stored version, without database or storage I/O. options.Version must be zero; response overrides (for example a download Content-Disposition using the original name) are signed into the link.
func (Collection[M, K]) Validate ¶
func (c Collection[M, K]) Validate() error
Validate checks declaration identity, owner, hooks, locale, queues and policy.
func (Collection[M, K]) VariantPublicURLOf ¶
func (c Collection[M, K]) VariantPublicURLOf(ctx context.Context, m *Manager, file Attachment[M, K], variant Variant) (string, error)
VariantPublicURLOf derives the public URL of a generated variant of a loaded attachment without database or storage I/O. It fails with VariantUnavailable until the variant has been generated.
func (Collection[M, K]) VariantTemporaryURLOf ¶
func (c Collection[M, K]) VariantTemporaryURLOf(ctx context.Context, m *Manager, file Attachment[M, K], variant Variant, options storage.LinkOptions) (storage.TemporaryURL, error)
VariantTemporaryURLOf signs a read link for a generated variant, pinned to its stored version, without database or storage I/O.
func (Collection[M, K]) WithReconciliation ¶
func (c Collection[M, K]) WithReconciliation(queue Queue) Collection[M, K]
WithReconciliation binds ordinary job/outbox publication after service assembly without changing this collection's registered policy or identity.
func (Collection[M, K]) WithVariantQueue ¶
func (c Collection[M, K]) WithVariantQueue(queue VariantQueue) Collection[M, K]
WithVariantQueue generates this collection's variants through the queued job instead of synchronously after each upload. It does not change the collection's registered policy or identity.
type Config ¶
type Config struct {
MaxActive int
MaxReads int
Timeout time.Duration
CleanupTimeout time.Duration
CleanupGrace time.Duration
StoredGrace time.Duration
SettleAfter time.Duration
}
Config bounds manager work. MaxActive admits uploads and other mutations, including the complete remote download, validation and persistence lifetime; MaxReads separately admits loads, lookups, reads and link signing, so a burst of reads cannot starve writes (or the reverse). Both queue briefly (at most min(Timeout, 5s)) before failing as retryable overload. Owner-delete cleanup joined from model observers uses its own MaxOwnerCleanup pool so it does not compete with application reads/writes. SettleAfter is added to a disk's operation Timeout before ReconcilePending may inspect an unresolved write. CleanupGrace is the minimum retirement age before object deletion (zero for immediate development cleanup). Zero MaxReads or SettleAfter selects its default.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns bounded read, mutation, cleanup and reconciliation timing defaults.
type Cursor ¶
type Cursor = extensionmaintenance.Cursor
Cursor is an opaque owner-orphan inspection continuation.
type Dependencies ¶
type Dependencies struct {
Store *extensions.Store
Disks *storage.Registry
Image *imaging.Engine
Locales i18n.LocaleCatalog
}
Dependencies are borrowed. Image and Locales are required only by collections that use them. Their owners must outlive this manager's actual operations.
type File ¶
type File[M any] struct { // contains filtered or unexported fields }
File is the owner-free view of one ready attachment: identity, collection, detected metadata, properties and ready variants. Model slots hold Files; Attachment adds the typed owner reference.
func (File[M]) Collection ¶
Collection returns the declared collection name.
func (File[M]) EmailAttachment ¶
func (f File[M]) EmailAttachment() (email.Attachment, error)
EmailAttachment snapshots this ready file into email's durable reference. No bytes are read. Authorize the file before use and retain its object for queued delivery. The mailer must have access to the same configured disk. Attachment promotes this method from its embedded File.
func (File[M]) Info ¶
func (f File[M]) Info() UploadInfo
Info returns detected upload metadata recorded with the attachment.
func (File[M]) MarshalJSON ¶
MarshalJSON rejects implicit file export; construct an explicit response DTO.
func (File[M]) Properties ¶
func (f File[M]) Properties() (json.RawMessage, error)
Properties decodes the stored dynamic JSON properties.
func (File[M]) Variant ¶
func (f File[M]) Variant(variant Variant) (VariantInfo, bool)
Variant reports whether the declared variant has been generated.
func (File[M]) Variants ¶
func (f File[M]) Variants() []VariantInfo
Variants returns the attachment's generated variants, ordered by name.
type FileOf ¶
type FileOf[M any] struct { // contains filtered or unexported fields }
FileOf distinguishes attachment identifiers belonging to model M.
type FileSource ¶
FileSource is an upload the framework can open and read, such as foundryhttp.UploadedFile, which satisfies it without attachments importing HTTP. An operation opens it, reads within the policy's MaxBytes and closes its reader before returning; the caller keeps owning the underlying file. Detected bytes decide acceptance: Name is display metadata and ClientContentType only the existing text-specialization hint.
type Hook ¶
type Hook[M any, K comparable] struct { Before func(context.Context, BeforeContext[M, K]) error AfterStored func(context.Context, *database.Tx, Attachment[M, K]) error }
Hooks execute in declaration order. AfterStored runs inside the ownership transaction after storage succeeds and can veto publication. External effects from that hook must use an ordinary transactional outbox or after-commit hook.
type LocalizedBatch ¶
type LocalizedBatch[M any, K comparable] struct { // contains filtered or unexported fields }
LocalizedBatch captures one catalog and owner/attachment snapshot. Resolving many owners or changing the requested locale performs no further I/O.
func (LocalizedBatch[M, K]) Get ¶
func (b LocalizedBatch[M, K]) Get(owner model.Reference[M, K]) (LocalizedFiles[M, K], error)
Get returns the loaded owner files and catalog without I/O; absent or unloaded owners return not found.
type LocalizedFiles ¶
type LocalizedFiles[M any, K comparable] struct { // contains filtered or unexported fields }
LocalizedFiles holds loaded attachments and the catalog snapshot used for locale selection.
func (LocalizedFiles[M, K]) List ¶
func (f LocalizedFiles[M, K]) List(locale i18n.LocaleID) ([]Attachment[M, K], error)
List returns files for a registered locale in collection order without I/O.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns attachment admission and recovery state while borrowing its store, disks, image engine and locale catalog.
func New ¶
func New(dependencies Dependencies, config Config, collections ...Registration) (*Manager, error)
New validates registrations and borrowed dependencies, then creates separate admission owners for reads, writes and owner cleanup.
func (*Manager) Close ¶
Close cancels reads, writes and owner cleanup together and waits for their actual exit. A timed-out wait keeps ownership visible through Done.
func (*Manager) Done ¶
func (m *Manager) Done() <-chan struct{}
Done closes when manager shutdown has drained reads, writes and owner cleanup. A nil or uninitialized manager returns a closed channel.
func (*Manager) GenerateVariants ¶
func (m *Manager) GenerateVariants(ctx context.Context, id OperationID) error
GenerateVariants derives every declared variant still missing for one ready attachment. It is idempotent and is the handler of the variant job; an original that is no longer ready has nothing to generate.
func (*Manager) Inspect ¶
func (m *Manager) Inspect(ctx context.Context, id OperationID) (ReconcileResult, error)
Inspect is an administrative, read-only lookup of a durable upload operation. Ready confirms publication; cleanup/cleaned confirms retirement. A writing or uncertain state cannot establish that a remote storage request has settled.
func (*Manager) InspectOrphans ¶
func (m *Manager) InspectOrphans(ctx context.Context, owner extensions.OwnerName, cursor Cursor, limit int) (OrphanPage, error)
InspectOrphans reads one bounded page of attachment journal entries whose owners no longer exist.
func (*Manager) InspectStorage ¶
func (m *Manager) InspectStorage(ctx context.Context, options StorageInspection) (StorageOrphanPage, error)
InspectStorage lists one bounded page under this owner's exact framework prefix on a registered collection disk, then checks both journals in two queries. Every journal state protects its object, including unsettled writes. Untracked candidates are inspection results only: their age never authorizes deletion.
func (*Manager) PruneOrphans ¶
func (m *Manager) PruneOrphans(ctx context.Context, owner extensions.OwnerName, ids []OperationID, queue *Queue) (ChangeResult, error)
PruneOrphans only retires ready/stored orphan rows selected explicitly. It preserves soft-deleted owners, and refuses unsettled writers instead of treating owner absence as permission to delete a possibly in-flight upload.
func (*Manager) Reconcile ¶
func (m *Manager) Reconcile(ctx context.Context, id OperationID) (ReconcileResult, error)
Reconcile cleans retired or abandoned stored uploads, preserving ready and retained files and refusing unsettled writers.
func (*Manager) ReconcilePending ¶
ReconcilePending is an explicit bounded sweep, suitable for an ordinary scheduled job. It retries Cleanup and abandons old Stored intents after the configured grace. Writing/Uncertain intents older than the settlement cutoff are inspected with Stat and settled only when storage is unambiguous: absent, or present with this intent's exact size and full checksum. Anything else stays Uncertain for operator Settle. Locally active writers are excluded. The same sweep retries variant cleanup, settles aged variant intents and scans one scoped object page for tombstoned keys after the age and cleanup grace limits.
func (*Manager) RegenerateVariants ¶
func (m *Manager) RegenerateVariants(ctx context.Context, owner extensions.OwnerName, collection Name, options RegenerationOptions) (RegenerationPage, error)
RegenerateVariants is the name-addressed form used by operational commands.
func (*Manager) RetainedObject ¶
func (m *Manager) RetainedObject(ctx context.Context, id OperationID) (RetainedFile, error)
RetainedObject is an administrative recovery lookup after an uncertain DetachKeepFile commit. It grants no access to ready or unsettled upload pins.
func (*Manager) Settle ¶
func (m *Manager) Settle(ctx context.Context, id OperationID, settlement Settlement, queue *Queue) (ReconcileResult, error)
Settle abandons an unresolved upload after an explicit operator assertion. It never publishes attachment ownership. A matching object is read through a pinned validator and checksum-verified before being scheduled for cleanup.
type Many ¶
type Many[M any] struct { // contains filtered or unexported fields }
Many is a model slot holding the ready files of a multiple-file collection in collection order. The zero value is not loaded.
func (Many[M]) MarshalJSON ¶
MarshalJSON rejects implicit collection slot export.
type ManyHandle ¶
type ManyHandle[M any, K comparable] struct { // contains filtered or unexported fields }
ManyHandle retains typed slot capabilities behind shared callback state. Example: slot.From(manager).Relation(Fields.Slot).
func ManyOf ¶
func ManyOf[M any, K comparable](owner extensions.Owner[M, K], name Name, policy Policy, binding extensions.SlotBinding[M, K, Many[M]]) ManyHandle[M, K]
ManyOf declares a thin multiple-file handle with the existing manager policy. Example: attachments.ManyOf(owner,"files",policy,binding).
func (ManyHandle[M, K]) Accepts ¶
func (s ManyHandle[M, K]) Accepts(ctx context.Context, file FileSource) (bool, error)
Accepts checks policy using the existing manager admission and media checks. Example: slot.Accepts(ctx,file).
func (ManyHandle[M, K]) Add ¶
Add appends an upload to the multiple-file collection. Example: slot.Add(ctx,article,upload).
func (ManyHandle[M, K]) AddFile ¶
func (s ManyHandle[M, K]) AddFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
AddFile appends a file to the multiple-file collection. Example: slot.AddFile(ctx,article,file).
func (ManyHandle[M, K]) AddIn ¶
func (s ManyHandle[M, K]) AddIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
AddIn publishes a prepared upload in the caller transaction. Example: slot.AddIn(ctx,tx,article,prepared).
func (ManyHandle[M, K]) Clear ¶
func (s ManyHandle[M, K]) Clear(ctx context.Context, owner M) (ChangeResult, error)
Clear retires every file and schedules storage cleanup. Example: slot.Clear(ctx,article).
func (ManyHandle[M, K]) ClearIn ¶ added in v0.5.2
func (s ManyHandle[M, K]) ClearIn(ctx context.Context, tx *database.Tx, owner M) (ChangeResult, error)
ClearIn retires every file in the caller transaction and cleans storage after commit. Example: slot.ClearIn(ctx,tx,article).
func (ManyHandle[M, K]) Describe ¶
func (s ManyHandle[M, K]) Describe() extensions.SlotDescription
Describe returns an owned inspection snapshot. Example: slot.Describe().
func (ManyHandle[M, K]) Detach ¶
func (s ManyHandle[M, K]) Detach(ctx context.Context, owner M, id ID[M]) (ChangeResult, error)
Detach retires one file and schedules storage cleanup. Example: slot.Detach(ctx,article,id).
func (ManyHandle[M, K]) Discard ¶
func (s ManyHandle[M, K]) Discard(ctx context.Context, prepared Prepared[M, K]) error
Discard reclaims an unpublished prepared upload. Example: slot.Discard(ctx,prepared).
func (ManyHandle[M, K]) Format ¶
func (ManyHandle[M, K]) Format(s fmt.State, _ rune)
Format omits retained runtime state. Example: fmt.Sprintf("%+v",slot).
func (ManyHandle[M, K]) From ¶
func (s ManyHandle[M, K]) From(m *Manager) ManyHandle[M, K]
From returns a copy borrowing this family's manager; nil leaves it unbound. Example: slot.From(manager).
func (ManyHandle[M, K]) Name ¶
func (s ManyHandle[M, K]) Name() Name
Name returns the stored name. Example: slot.Name().
func (ManyHandle[M, K]) Prepare ¶
func (s ManyHandle[M, K]) Prepare(ctx context.Context, owner M, upload Upload) (Prepared[M, K], error)
Prepare prepares storage before a transaction without publishing it. Example: slot.Prepare(ctx,article,upload).
func (ManyHandle[M, K]) PrepareFile ¶
func (s ManyHandle[M, K]) PrepareFile(ctx context.Context, owner M, file FileSource) (Prepared[M, K], error)
PrepareFile prepares file storage before a transaction without publishing it. Example: slot.PrepareFile(ctx,article,file).
func (ManyHandle[M, K]) PublicURLs ¶
func (s ManyHandle[M, K]) PublicURLs(ctx context.Context, owner M) ([]string, error)
PublicURLs derives loaded file URLs in collection order without I/O. Example: slot.PublicURLs(ctx,article).
func (ManyHandle[M, K]) Registration ¶
func (s ManyHandle[M, K]) Registration() Registration
Registration returns the existing manager registration. Example: slot.Registration().
func (ManyHandle[M, K]) Relation ¶
func (s ManyHandle[M, K]) Relation(slot orm.Slot[M, Many[M]]) orm.ExtensionRelation[M]
Relation binds the loader to its concrete ORM field; mismatched fields fail validation. Example: Articles.Query().With(slot.Relation(Articles.Gallery)).
func (ManyHandle[M, K]) Reorder ¶
func (s ManyHandle[M, K]) Reorder(ctx context.Context, owner M, order []ID[M]) ([]Attachment[M, K], error)
Reorder sets an exact permutation of the collection file IDs. Example: slot.Reorder(ctx,article,order).
func (ManyHandle[M, K]) Replace ¶
func (s ManyHandle[M, K]) Replace(ctx context.Context, owner M, upload Upload) (Result[M, K], error)
Replace replaces the collection; inspect the publication outcome when an error is returned. Example: slot.Replace(ctx,article,upload).
func (ManyHandle[M, K]) ReplaceFile ¶
func (s ManyHandle[M, K]) ReplaceFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
ReplaceFile replaces the collection from a file; inspect the publication outcome on error. Example: slot.ReplaceFile(ctx,article,file).
func (ManyHandle[M, K]) ReplaceIn ¶
func (s ManyHandle[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
ReplaceIn publishes a prepared upload in the caller transaction. Example: slot.ReplaceIn(ctx,tx,article,prepared).
func (ManyHandle[M, K]) TemporaryURL ¶
func (s ManyHandle[M, K]) TemporaryURL(ctx context.Context, owner M, file File[M], options storage.LinkOptions) (storage.TemporaryURL, error)
TemporaryURL signs a loaded file URL pinned to its stored version. Example: slot.TemporaryURL(ctx,article,file,options).
func (ManyHandle[M, K]) URL ¶
URL derives a loaded file URL without I/O; authorize access first. Example: slot.URL(ctx,article,file).
func (ManyHandle[M, K]) Validate ¶
func (s ManyHandle[M, K]) Validate() error
Validate checks the declaration and slot binding. Example: slot.Validate().
func (ManyHandle[M, K]) VariantURL ¶
func (s ManyHandle[M, K]) VariantURL(ctx context.Context, owner M, file File[M], variant Variant) (string, error)
VariantURL derives a generated variant URL without I/O. Example: slot.VariantURL(ctx,article,file,variant).
type Name ¶
type Name string
Name identifies an attachment collection within its declared owner scope.
type One ¶
type One[M any] struct { // contains filtered or unexported fields }
One is a model slot holding the ready file of a single-file collection. The zero value is not loaded. Reading a slot performs no I/O.
func (One[M]) EmailAttachment ¶
func (o One[M]) EmailAttachment() (email.Attachment, error)
EmailAttachment accepts a loaded, present single-file slot directly through Message.AttachStored. An unloaded or absent slot is an error.
func (One[M]) Get ¶
Get returns the optional file and whether the slot was loaded. A loaded but absent file differs from a slot that was not loaded.
func (One[M]) MarshalJSON ¶
MarshalJSON rejects implicit attachment slot export.
type OneHandle ¶
type OneHandle[M any, K comparable] struct { // contains filtered or unexported fields }
OneHandle retains typed slot capabilities behind shared callback state. Example: slot.From(manager).Relation(Fields.Slot).
func OneOf ¶
func OneOf[M any, K comparable](owner extensions.Owner[M, K], name Name, policy Policy, binding extensions.SlotBinding[M, K, One[M]]) OneHandle[M, K]
OneOf declares a thin single-file handle with the existing manager policy. Example: attachments.OneOf(owner,"files",policy,binding).
func (OneHandle[M, K]) Accepts ¶
Accepts checks policy using the existing manager admission and media checks. Example: slot.Accepts(ctx,file).
func (OneHandle[M, K]) Clear ¶
func (s OneHandle[M, K]) Clear(ctx context.Context, owner M) (ChangeResult, error)
Clear retires every file and schedules storage cleanup. Example: slot.Clear(ctx,article).
func (OneHandle[M, K]) ClearIn ¶ added in v0.5.2
func (s OneHandle[M, K]) ClearIn(ctx context.Context, tx *database.Tx, owner M) (ChangeResult, error)
ClearIn retires every file in the caller transaction and cleans storage after commit. Example: slot.ClearIn(ctx,tx,article).
func (OneHandle[M, K]) Describe ¶
func (s OneHandle[M, K]) Describe() extensions.SlotDescription
Describe returns an owned inspection snapshot. Example: slot.Describe().
func (OneHandle[M, K]) Detach ¶
Detach retires one file and schedules storage cleanup. Example: slot.Detach(ctx,article,id).
func (OneHandle[M, K]) Discard ¶
Discard reclaims an unpublished prepared upload. Example: slot.Discard(ctx,prepared).
func (OneHandle[M, K]) Format ¶
Format omits retained runtime state. Example: fmt.Sprintf("%+v",slot).
func (OneHandle[M, K]) From ¶
From returns a copy borrowing this family's manager; nil leaves it unbound. Example: slot.From(manager).
func (OneHandle[M, K]) Prepare ¶
func (s OneHandle[M, K]) Prepare(ctx context.Context, owner M, upload Upload) (Prepared[M, K], error)
Prepare prepares storage before a transaction without publishing it. Example: slot.Prepare(ctx,article,upload).
func (OneHandle[M, K]) PrepareFile ¶
func (s OneHandle[M, K]) PrepareFile(ctx context.Context, owner M, file FileSource) (Prepared[M, K], error)
PrepareFile prepares file storage before a transaction without publishing it. Example: slot.PrepareFile(ctx,article,file).
func (OneHandle[M, K]) PublicURL ¶
PublicURL derives the loaded single file URL without I/O. Example: slot.PublicURL(ctx,article).
func (OneHandle[M, K]) Registration ¶
func (s OneHandle[M, K]) Registration() Registration
Registration returns the existing manager registration. Example: slot.Registration().
func (OneHandle[M, K]) Relation ¶
Relation binds the loader to its concrete ORM field; mismatched fields fail validation. Example: Articles.Query().With(slot.Relation(Articles.Cover)).
func (OneHandle[M, K]) Replace ¶
Replace replaces the collection; inspect the publication outcome when an error is returned. Example: slot.Replace(ctx,article,upload).
func (OneHandle[M, K]) ReplaceFile ¶
func (s OneHandle[M, K]) ReplaceFile(ctx context.Context, owner M, file FileSource) (Result[M, K], error)
ReplaceFile replaces the collection from a file; inspect the publication outcome on error. Example: slot.ReplaceFile(ctx,article,file).
func (OneHandle[M, K]) ReplaceIn ¶
func (s OneHandle[M, K]) ReplaceIn(ctx context.Context, tx *database.Tx, owner M, prepared Prepared[M, K]) (Result[M, K], error)
ReplaceIn publishes a prepared upload in the caller transaction. Example: slot.ReplaceIn(ctx,tx,article,prepared).
func (OneHandle[M, K]) TemporaryURL ¶
func (s OneHandle[M, K]) TemporaryURL(ctx context.Context, owner M, file File[M], options storage.LinkOptions) (storage.TemporaryURL, error)
TemporaryURL signs a loaded file URL pinned to its stored version. Example: slot.TemporaryURL(ctx,article,file,options).
func (OneHandle[M, K]) URL ¶
URL derives a loaded file URL without I/O; authorize access first. Example: slot.URL(ctx,article,file).
type Operation ¶
type Operation struct{}
OperationID is the administrative/job reference for one durable upload intent. Application collection operations use model-owned ID[M] instead.
type OperationID ¶
OperationID identifies one durable upload intent for administrative and job operations.
type Orphan ¶
type Orphan struct {
Operation OperationID `json:"operation"`
Collection Name `json:"collection"`
Locale i18n.LocaleID `json:"locale"`
State State `json:"state"`
}
Orphan identifies an ownerless attachment journal entry without exposing its storage pins.
type OrphanPage ¶
OrphanPage reports ownerless journal entries, scan count and an optional continuation.
type Policy ¶
type Policy struct {
Disk storage.Declaration
Cardinality Cardinality
Localized bool
MaxFiles int
MaxBytes int64
MaxStoredBytes int64
Accepted []storage.MediaType
AnyMedia bool
Image value.Optional[imaging.Plan]
// Variants are named derived images (for example thumbnails) generated
// from each ready original and stored beside it. They require image input:
// an Image plan or an Accepted list of decodable image types.
Variants []Variant
// InlineActiveContent allows public URLs and inline signed links for
// script-capable files (SVG, HTML, XML, JavaScript). By default public URLs
// are refused and signed links force a download disposition, because such
// files served inline run scripts in the serving origin (stored XSS). Only
// set it when that origin is isolated and cookie-less.
InlineActiveContent bool
}
Policy declares storage, cardinality, accepted media, resource bounds and image processing for a collection.
type Prepared ¶
type Prepared[M any, K comparable] struct { // contains filtered or unexported fields }
Prepared is an upload read, checked and stored for one owner's collection but not yet published. Publish it with ReplaceIn or AddIn inside a transaction that begins after Prepare returned, within StoredGrace; otherwise ReconcilePending reclaims it. Discard reclaims it at once.
func (Prepared[M, K]) Format ¶
Format writes a label without exposing the prepared upload reference.
func (Prepared[M, K]) Operation ¶
func (p Prepared[M, K]) Operation() OperationID
Operation is the durable upload intent, for Manager.Inspect.
type Publication ¶
type Publication uint8
Publication distinguishes unpublished, published and uncertain ownership transaction outcomes.
const ( Unpublished Publication = iota Published PublicationUnknown )
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue is a borrowed job/outbox binding. Construct the manager, declare its reconcile job, assemble the ordinary dispatcher/outbox, then bind the queue to collections. This avoids constructor dependency cycles.
type ReconcileJob ¶
type ReconcileJob struct {
// contains filtered or unexported fields
}
ReconcileJob declares a typed job for one durable attachment operation.
func DefineReconcileJob ¶
func DefineReconcileJob(name jobs.Name, policy jobs.Policy) ReconcileJob
DefineReconcileJob declares a version-one reconciliation payload with the supplied job policy.
func (ReconcileJob) Declare ¶
func (j ReconcileJob) Declare(manager *Manager) (jobs.Declaration, error)
Declare binds manager reconciliation, marking invalid operations and unsettled writes as permanent job failures.
type ReconcileRequest ¶
type ReconcileRequest struct {
Operation OperationID `json:"operation"`
}
ReconcileRequest identifies the durable attachment operation to reconcile.
type ReconcileResult ¶
type ReconcileResult struct {
Operation OperationID
State State
Attempts uint32
Failure string
}
ReconcileResult reports durable operation state, cleanup attempt count and a safe failure classification.
type RegenerationCursor ¶
type RegenerationCursor struct {
// contains filtered or unexported fields
}
RegenerationCursor continues a regeneration run within one process.
func (RegenerationCursor) IsZero ¶
func (c RegenerationCursor) IsZero() bool
IsZero reports whether no regeneration continuation is set.
type RegenerationOptions ¶
type RegenerationOptions struct {
Missing bool
Cursor RegenerationCursor
Limit int
}
RegenerationOptions selects one bounded batch of ready attachments. Missing generates only variants without a ready file; otherwise every declared variant is regenerated and replaces the previous one.
type RegenerationPage ¶
type RegenerationPage struct {
Regenerated []OperationID
Failed []OperationID
Next RegenerationCursor
}
RegenerationPage reports one batch. Failed attachments keep their previous variants; rerun them after resolving the cause. Continue with Next until it is zero.
type Registration ¶
type Registration struct {
// contains filtered or unexported fields
}
Registration carries a collection declaration and its validation into manager construction.
type RemoteSource ¶
type RemoteSource struct {
Client *httpclient.Client
URL string
OriginalName string
}
RemoteSource names a remote file to import. URL is untrusted input, so Client must enforce a restricted destination policy (for example httpclient.PublicDestinations) that keeps imports away from internal services. OriginalName defaults to the URL's last path segment.
type Resolved ¶
type Resolved[M any, K comparable] struct { // contains filtered or unexported fields }
Resolved holds attachments from one selected locale without mixing fallback collections.
func (Resolved[M, K]) Files ¶
func (r Resolved[M, K]) Files() []Attachment[M, K]
Files returns an independent slice of the selected attachments.
type Result ¶
type Result[M any, K comparable] struct { Operation OperationID Publication Publication Attachment value.Optional[Attachment[M, K]] PendingCleanup []OperationID PendingVariants bool }
Result distinguishes ownership publication from storage cleanup. A published attachment remains published when old-object cleanup returns an error. An uncertain publication is never described as rolled back or automatically retried. Inspect the durable Operation before deciding the next action. PendingVariants reports that declared variants were queued, or that their synchronous generation failed; the original is published either way.
func AddFilesTo ¶
func AddFilesTo[F FileSource, M any, K comparable](ctx context.Context, slot ManyHandle[M, K], owner M, files []F) ([]Result[M, K], error)
AddFilesTo appends files through a bound ORM many-slot handle in input order. The slot and batch limit are checked before any file opens. Results include every attempted file, including the first failure; earlier publications remain published. Inspect each Result.Publication and never retry unknown outcomes. Example: results, err := attachments.AddFilesTo(ctx, bound.Galleries, article, files).
func (Result[M, K]) MarshalJSON ¶
MarshalJSON rejects implicit upload result export.
type RetainResult ¶
type RetainResult struct {
Operation OperationID
Publication Publication
File value.Optional[RetainedFile]
}
RetainResult reports detach publication and the optional storage reference handed to the application.
type RetainedFile ¶
type RetainedFile struct {
Operation OperationID
Disk storage.DiskID
Key storage.ObjectKey
ETag storage.ETag
Version storage.VersionID
}
RetainedFile transfers cleanup responsibility to the application. Its exact storage pins are explicit; automatic attachment maintenance never deletes it.
func (RetainedFile) Format ¶
func (RetainedFile) Format(s fmt.State, _ rune)
Format writes a label without exposing retained storage pins.
func (RetainedFile) MarshalJSON ¶
func (RetainedFile) MarshalJSON() ([]byte, error)
MarshalJSON rejects implicit retained storage reference export.
type Settlement ¶
type Settlement uint8
Settlement is an operator assertion, after inspecting the writer and storage provider, that no request can still publish this upload. It is never inferred from a lease, canceled context or one missing-object response; the automatic path relies instead on the configured writer/provider time bound.
const WriterStoppedAndStorageSettled Settlement = 1
type State ¶
type State string
State is persisted, public diagnostic state, not a caller-controlled upload option. Writing/Uncertain require settlement; a timeout alone is not proof that a remote storage request has stopped. ReconcilePending settles them only after the disk Timeout plus Config.SettleAfter and only when storage is unambiguous; everything else waits for an operator Settle.
type StorageCursor ¶
type StorageCursor struct {
// contains filtered or unexported fields
}
StorageCursor preserves the disk/owner/age policy and first-page cutoff. Listings are not transactional snapshots. Copy only a returned Next cursor.
func (StorageCursor) IsZero ¶
func (c StorageCursor) IsZero() bool
IsZero reports whether no storage inspection continuation is set.
type StorageInspection ¶
type StorageInspection struct {
Disk storage.Declaration
Owner extensions.OwnerName
MinimumAge time.Duration
Limit int
Cursor StorageCursor
}
StorageInspection selects a registered disk, owner scope, minimum age and bounded inspection page.
type StorageOrphanPage ¶
type StorageOrphanPage struct {
Candidates []storage.ObjectInfo
// Unknown is the number of age-qualified untracked objects in this page.
// Candidates contains their keys and metadata; sum Unknown across pages.
Unknown int
Scanned int
Next StorageCursor
}
StorageOrphanPage reports untracked storage candidates for inspection; candidates do not authorize deletion.
type Undeclared ¶
type Undeclared = extensionmaintenance.Undeclared
Undeclared lists stored names that no current registration declares.
func InspectUndeclared ¶
func InspectUndeclared(ctx context.Context, m *Manager, owner extensions.OwnerName) (Undeclared, error)
InspectUndeclared lists stored collection names in owner's current scope that no collection registered with m declares, in any journal state, for example after renaming a slot field without pinning its stored name. It reads names only and modifies no row or object.
type Upload ¶
type Upload struct {
Source io.Reader
OriginalName string
ContentType storage.MediaType
Properties value.JSON[json.RawMessage]
}
Upload borrows Source until the operation actually returns and never closes it. OriginalName and ContentType are untrusted metadata hints. Media acceptance is based on bytes; ContentType can only specialize generic plain text to a compatible textual type (CSV, TSV, Markdown, calendar, valid JSON) that the policy accepts, otherwise the file stays text/plain. Image policy performs actual bounded decode/re-encoding. Invisible bidirectional and zero-width characters are removed from OriginalName.
type UploadInfo ¶
type UploadInfo struct {
OriginalName string
MediaType storage.MediaType
Size int64
Width, Height int
}
UploadInfo holds the recorded filename, detected media type, byte size and image dimensions.
type Variant ¶
type Variant struct {
// contains filtered or unexported fields
}
Variant declares a named derived image, for example a thumbnail or preview. It is generated from each ready original with an imaging plan and stored beside it; the original is never changed. Declare it once and reuse the same value in collection policies and link helpers.
func DefineVariant ¶
func DefineVariant(name VariantName, plan imaging.Plan) Variant
DefineVariant creates a named image-plan declaration; validation is deferred.
func (Variant) Name ¶
func (v Variant) Name() VariantName
Name returns the declared variant identifier.
type VariantInfo ¶
type VariantInfo struct {
Name VariantName
MediaType storage.MediaType
Size int64
Width, Height int
}
VariantInfo describes one generated variant of a loaded attachment.
type VariantJob ¶
type VariantJob struct {
// contains filtered or unexported fields
}
VariantJob generates missing variants of one ready attachment. Retries are idempotent: completed variants are not generated again.
func DefineVariantJob ¶
func DefineVariantJob(name jobs.Name, policy jobs.Policy) VariantJob
DefineVariantJob declares a version-one variant payload with the supplied job policy.
func (VariantJob) Declare ¶
func (j VariantJob) Declare(manager *Manager) (jobs.Declaration, error)
Declare binds manager variant generation, marking invalid or missing intents as permanent job failures.
func (VariantJob) ToOutbox ¶
func (j VariantJob) ToOutbox(producer *jobs.Outbox) (VariantQueue, error)
ToOutbox returns a validated variant queue borrowing producer.
type VariantName ¶
type VariantName string
VariantName is a stable semantic identifier stored with each derived file.
func (VariantName) Validate ¶
func (n VariantName) Validate() error
Validate rejects invalid or excessive semantic variant identifiers.
type VariantQueue ¶
type VariantQueue struct {
// contains filtered or unexported fields
}
VariantQueue is a borrowed job/outbox binding for queued variant generation. Bind it with Collection.WithVariantQueue after the manager and its job are declared; the publication transaction then enqueues one job per upload.
func (VariantQueue) Validate ¶
func (q VariantQueue) Validate() error
Validate checks the variant job and borrowed outbox destination.
type VariantRequest ¶
type VariantRequest struct {
Operation OperationID `json:"operation"`
}
VariantRequest identifies one attachment whose declared variants are generated.
type VariantState ¶
type VariantState string
VariantState is the persisted journal state of one derived file.
const ( VariantWriting VariantState = "writing" VariantReady VariantState = "ready" VariantCleanup VariantState = "cleanup" VariantCleaned VariantState = "cleaned" VariantUncertain VariantState = "uncertain" )
func (VariantState) Validate ¶
func (s VariantState) Validate() error
Validate rejects an unrecognized persisted variant state.
Source Files
¶
- definition.go
- diagnostics.go
- email.go
- handle_collection.go
- handle_core.go
- handle_files.go
- handle_many.go
- handle_one.go
- inspection.go
- jobs.go
- lifecycle.go
- localized.go
- manager.go
- matching.go
- migrations.go
- module.go
- mutate.go
- object_cleanup.go
- orphans.go
- read.go
- reconcile.go
- remote.go
- result.go
- retain.go
- row.go
- scopes.go
- slot.go
- slot_write.go
- state.go
- storage_diagnostics.go
- storage_outcome.go
- upload.go
- variants.go
- write.go