Help us shape the future of Go! Take the 2026 Go Developer Survey

attachments

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 50 Imported by: 0

Documentation

Overview

Package attachments owns typed model collections and recoverable storage workflows. Applications declare policy once and pass typed owner references.

Index

Constants

View Source
const (
	MaxUploadBytes     int64 = 64 << 20
	MaxCollectionFiles       = 256
	MaxOwnerIntents          = 4096
	MaxPropertiesBytes       = 64 << 10
)
View Source
const (
	DefaultMaxReads    = 64
	DefaultSettleAfter = 15 * time.Minute
	// MaxOwnerCleanup bounds concurrent owner-delete observers per manager.
	MaxOwnerCleanup = 4096
)
View Source
const (
	MigrationOrigin   migrate.Origin  = "foundry.attachments"
	CreateAttachments migrate.ID      = "000001_create_attachments"
	CreateVariants    migrate.ID      = "000002_create_variants"
	Introduced        migrate.Version = "v0.1.0"
)
View Source
const (
	MaxBatchFiles           = 4096
	MaxBatchPropertiesBytes = 4 << 20
)
View Source
const MaxRegenerationBatch = 100
View Source
const (
	// MaxVariants bounds declared variants per collection.
	MaxVariants = 8
)

Variables

View Source
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.

View Source
var VariantUnavailable = safeerror.Sentinel(fault.Missing, "attachment variant is not available")

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.

func (Batch[M, K]) Get

func (b Batch[M, K]) Get(owner model.Reference[M, K]) ([]Attachment[M, K], error)

Get returns an independent slice of loaded ready attachments; inactive or unloaded owners return not found.

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

func (c Collection[M, K]) Discard(ctx context.Context, m *Manager, prepared Prepared[M, K]) error

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.

func (Config) Validate

func (c Config) Validate() error

Validate checks manager capacity and timing bounds, allowing zero read capacity and settlement delay to select defaults.

type 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

func (f File[M]) Collection() Name

Collection returns the declared collection name.

func (File[M]) CreatedAt

func (f File[M]) CreatedAt() temporal.DateTime

CreatedAt returns the recorded attachment creation time.

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]) Format

func (File[M]) Format(s fmt.State, _ rune)

Format writes a label without exposing file data or storage pins.

func (File[M]) ID

func (f File[M]) ID() ID[M]

ID returns the model-owned attachment identifier.

func (File[M]) Info

func (f File[M]) Info() UploadInfo

Info returns detected upload metadata recorded with the attachment.

func (File[M]) IsZero

func (f File[M]) IsZero() bool

IsZero reports whether the file has no attachment identifier.

func (File[M]) Locale

func (f File[M]) Locale() value.Optional[i18n.LocaleID]

Locale returns the optional exact collection locale.

func (File[M]) MarshalJSON

func (File[M]) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit file export; construct an explicit response DTO.

func (File[M]) Position

func (f File[M]) Position() int32

Position returns the recorded collection sort position.

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

type FileSource = upload.Source

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 ID

type ID[M any] = model.ID[FileOf[M]]

ID is an attachment identifier tied to its owner model type.

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.

func (LocalizedFiles[M, K]) Resolve

func (f LocalizedFiles[M, K]) Resolve(requested i18n.LocaleID) (value.Optional[Resolved[M, K]], error)

Resolve chooses the first nonempty collection in requested/default/remaining lexical locale order. It never mixes files from different locale collections.

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

func (m *Manager) Close(ctx context.Context) error

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

func (m *Manager) ReconcilePending(ctx context.Context, limit int) ([]ReconcileResult, error)

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.

func (*Manager) Validate

func (m *Manager) Validate() error

Validate rejects an uninitialized manager or invalid backing store.

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]) All

func (m Many[M]) All() iter.Seq2[int, File[M]]

All yields each loaded file in collection order without copying the slice.

func (Many[M]) Format

func (Many[M]) Format(s fmt.State, _ rune)

Format writes a label without exposing loaded files.

func (Many[M]) Get

func (m Many[M]) Get() ([]File[M], bool)

Get returns a caller-owned copy of the files and whether the slot was loaded.

func (Many[M]) IsLoaded

func (m Many[M]) IsLoaded() bool

IsLoaded reports whether the slot was filled by a loader.

func (Many[M]) Len

func (m Many[M]) Len() int

Len reports the number of loaded files; it is zero when not loaded.

func (Many[M]) MarshalJSON

func (Many[M]) MarshalJSON() ([]byte, error)

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

func (s ManyHandle[M, K]) Add(ctx context.Context, owner M, upload Upload) (Result[M, K], error)

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

func (s ManyHandle[M, K]) URL(ctx context.Context, owner M, file File[M]) (string, error)

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]) Format

func (One[M]) Format(s fmt.State, _ rune)

Format writes a label without exposing the loaded file.

func (One[M]) Get

func (o One[M]) Get() (value.Optional[File[M]], bool)

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]) IsLoaded

func (o One[M]) IsLoaded() bool

IsLoaded reports whether the slot was filled by a loader.

func (One[M]) MarshalJSON

func (One[M]) MarshalJSON() ([]byte, error)

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

func (s OneHandle[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 (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

func (s OneHandle[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 (OneHandle[M, K]) Discard

func (s OneHandle[M, K]) Discard(ctx context.Context, prepared Prepared[M, K]) error

Discard reclaims an unpublished prepared upload. Example: slot.Discard(ctx,prepared).

func (OneHandle[M, K]) Format

func (OneHandle[M, K]) Format(s fmt.State, _ rune)

Format omits retained runtime state. Example: fmt.Sprintf("%+v",slot).

func (OneHandle[M, K]) From

func (s OneHandle[M, K]) From(m *Manager) OneHandle[M, K]

From returns a copy borrowing this family's manager; nil leaves it unbound. Example: slot.From(manager).

func (OneHandle[M, K]) Name

func (s OneHandle[M, K]) Name() Name

Name returns the stored name. Example: slot.Name().

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

func (s OneHandle[M, K]) PublicURL(ctx context.Context, owner M) (value.Optional[string], error)

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

func (s OneHandle[M, K]) Relation(slot orm.Slot[M, One[M]]) orm.ExtensionRelation[M]

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

func (s OneHandle[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 (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

func (s OneHandle[M, K]) URL(ctx context.Context, owner M, file File[M]) (string, error)

URL derives a loaded file URL without I/O; authorize access first. Example: slot.URL(ctx,article,file).

func (OneHandle[M, K]) Validate

func (s OneHandle[M, K]) Validate() error

Validate checks the declaration and slot binding. Example: slot.Validate().

func (OneHandle[M, K]) VariantURL

func (s OneHandle[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 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

type OperationID = model.ID[Operation]

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

type OrphanPage struct {
	Orphans []Orphan
	Scanned int
	Next    Cursor
}

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.

func (Policy) Validate

func (p Policy) Validate() error

Validate checks explicit policy bounds, cardinality, media declarations and image plans without resolving services.

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

func (Prepared[M, K]) Format(s fmt.State, _ rune)

Format writes a label without exposing the prepared upload reference.

func (Prepared[M, K]) IsZero

func (p Prepared[M, K]) IsZero() bool

IsZero reports whether no prepared upload operation is set.

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.

func (Queue) Enqueue

func (q Queue) Enqueue(ctx context.Context, tx *database.Tx, id OperationID) error

Enqueue is available for explicit operator retries. The cleanup operation itself is idempotent; each requested enqueue receives a normal new execution ID.

func (Queue) Validate

func (q Queue) Validate() error

Validate checks the reconcile job and borrowed outbox destination.

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.

func (ReconcileJob) ToOutbox

func (j ReconcileJob) ToOutbox(producer *jobs.Outbox) (Queue, error)

ToOutbox returns a validated queue borrowing producer.

type ReconcileRequest

type ReconcileRequest struct {
	Operation OperationID `json:"operation"`
}

ReconcileRequest identifies the durable attachment operation to reconcile.

func (ReconcileRequest) Format

func (ReconcileRequest) Format(s fmt.State, _ rune)

Format writes a label without exposing the operation identifier.

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.

func (Resolved[M, K]) Locale

func (r Resolved[M, K]) Locale() i18n.LocaleID

Locale returns the selected fallback locale.

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]) Format

func (Result[M, K]) Format(s fmt.State, _ rune)

Format writes a label without exposing upload results or storage pins.

func (Result[M, K]) MarshalJSON

func (Result[M, K]) MarshalJSON() ([]byte, error)

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.

const (
	Writing        State = "writing"
	Stored         State = "stored"
	Ready          State = "ready"
	CleanupPending State = "cleanup"
	Cleaned        State = "cleaned"
	Retained       State = "retained"
	Uncertain      State = "uncertain"
)

func (State) Validate

func (s State) Validate() error

Validate rejects an unrecognized persisted attachment state.

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) Format

func (Variant) Format(s fmt.State, _ rune)

Format writes a label without exposing the prepared image plan.

func (Variant) Name

func (v Variant) Name() VariantName

Name returns the declared variant identifier.

func (Variant) Validate

func (v Variant) Validate() error

Validate checks the variant name and image plan without checking engine capabilities.

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.

func (VariantRequest) Format

func (VariantRequest) Format(s fmt.State, _ rune)

Format writes a label without exposing the operation identifier.

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.

Directories

Path Synopsis
Package command provides read-only attachment owner-orphan inspection and bounded regeneration of declared image variants.
Package command provides read-only attachment owner-orphan inspection and bounded regeneration of declared image variants.

Jump to

Keyboard shortcuts

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