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

document

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package document is wowapi's document / file framework: modules register document CLASSES (the policy envelope for a kind of file — allowed MIME types, a size ceiling, a default sensitivity, and an optional retention window); the service manages metadata rows, presigned upload sessions, immutable versioned file pointers, authorized presigned downloads, explicit access grants, and a retention sweep. Blob bytes never transit the API process — they flow client ↔ object store through short-lived presigned URLs (kernel/storage). Contract: blueprint 07 §4.

Index

Constants

View Source
const (
	PermRead = "kernel.document.read"
	// PermWrite is the authz permission for mutating a document (managing grants,
	// adding versions). "update" is the closed-set verb for write access; the
	// grant table's own access column still uses the literal "write".
	PermWrite = "kernel.document.update"
)

Permissions the download gate evaluates when an authz Evaluator is wired. The consumer registers them (kernel.document.read/write) at boot; the framework wiring does so by default.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessEvent

type AccessEvent struct {
	DocumentID  string
	VersionNo   int
	Sensitivity Sensitivity
	ActorID     string
}

AccessEvent is passed to OnDocumentAccess hooks after authorization succeeds and before the presigned GET is minted. A hook returning an error denies the download. The watermark slot lives here.

type AccessHook

type AccessHook func(context.Context, AccessEvent) error

UploadHook runs on confirm; AccessHook runs on download.

type Class

type Class struct {
	Key                string
	Module             string
	DefaultSensitivity Sensitivity   // applied when Create omits sensitivity
	MaxBytes           int64         // 0 = no ceiling
	AllowedMIME        []string      // empty = any sniffed type accepted
	Retention          time.Duration // 0 = keep forever; else retention_until = created_at + Retention
}

Class is a registered document class: the policy envelope a module declares for one kind of document.

type ConfirmInput

type ConfirmInput struct {
	DocumentID       uuid.UUID
	VersionNo        int
	StorageKey       string
	DeclaredSize     int64
	DeclaredChecksum string
	DeclaredMIME     string
}

ConfirmInput finalizes an uploaded version. Declared size/checksum/MIME are verified against the stored object before the immutable row is written.

type CreateInput

type CreateInput struct {
	Class       string
	Resource    resource.Ref
	Title       string
	Sensitivity Sensitivity // "" → the class default
}

CreateInput describes a new document's metadata. Resource is an optional anchor.

type Download

type Download struct {
	VersionNo int
	MIME      string
	URL       storage.PresignedURL
}

Download is an authorized, time-boxed download of one version.

type DownloadInput

type DownloadInput struct {
	DocumentID uuid.UUID
	VersionNo  int
}

DownloadInput selects a version to download; VersionNo 0 → latest active.

type GrantInput

type GrantInput struct {
	DocumentID  uuid.UUID
	GranteeKind string // capacity | role | relationship
	GranteeRef  string
	Access      string // read | write
	ValidTo     *time.Time
}

GrantInput adds an explicit access grant beyond policy.

type Hooks

type Hooks struct {
	// contains filtered or unexported fields
}

Hooks is the registry of upload/access hooks a module wires at boot.

func NewHooks

func NewHooks() *Hooks

NewHooks returns an empty hook set.

func (*Hooks) OnDocumentAccess

func (h *Hooks) OnDocumentAccess(fn AccessHook)

OnDocumentAccess registers a download-time hook.

func (*Hooks) OnFileUpload

func (h *Hooks) OnFileUpload(fn UploadHook)

OnFileUpload registers a confirm-time hook.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry collects document classes during module registration.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty class registry.

func (*Registry) Err

func (r *Registry) Err() error

Err returns accumulated registration errors joined, or nil.

func (*Registry) Get

func (r *Registry) Get(key string) (Class, bool)

Get returns the registered class.

func (*Registry) Keys

func (r *Registry) Keys() []string

Keys returns registered class keys, sorted.

func (*Registry) Register

func (r *Registry) Register(module string, c Class)

Register adds a document class. Malformed keys, a module-prefix mismatch, an invalid default sensitivity, or a duplicate are recorded and surfaced by Err().

type Sensitivity

type Sensitivity string

Sensitivity ranks how protected a document is. Ordered; the download scan-gate blocks pending scans at confidential and above.

const (
	SensitivityPublic       Sensitivity = "public"
	SensitivityInternal     Sensitivity = "internal"
	SensitivityConfidential Sensitivity = "confidential"
	SensitivityRestricted   Sensitivity = "restricted"
)

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the document framework. Metadata mutations run inside the caller's tenant transaction (so a document commits with its business write); scan-status and retention voiding run on a platform-privileged tenant-bound manager because document_versions is append-only to the module role.

func New

func New(reg *Registry, store storage.Adapter, ev authz.Evaluator, ob outbox.Writer, hooks *Hooks, idgen model.IDGen) *Service

New wires the service. registry/store/outbox/idgen are required; authz and hooks are optional.

func (*Service) ConfirmUpload

func (s *Service) ConfirmUpload(ctx context.Context, db database.TenantDB, in ConfirmInput) (uuid.UUID, error)

ConfirmUpload verifies the uploaded bytes (size, checksum, MIME sniff, class limits), runs OnFileUpload hooks, and writes the immutable version row.

func (*Service) Create

func (s *Service) Create(ctx context.Context, db database.TenantDB, in CreateInput) (uuid.UUID, error)

Create writes a document metadata row and returns its id.

func (*Service) Download

func (s *Service) Download(ctx context.Context, db database.TenantDB, actor authz.Actor, in DownloadInput) (Download, error)

Download authorizes and returns a short-lived presigned GET for a version.

func (*Service) Grant

func (s *Service) Grant(ctx context.Context, db database.TenantDB, in GrantInput) (uuid.UUID, error)

Grant records an explicit access grant. The caller must be able to write the document (owner, a write grant, or a policy write-allow).

func (*Service) InitiateUpload

func (s *Service) InitiateUpload(ctx context.Context, db database.TenantDB, docID uuid.UUID) (UploadSession, error)

InitiateUpload reserves the next version number and returns a presigned PUT for a tenant-prefixed key. The version row is written only on ConfirmUpload.

func (*Service) Revoke

func (s *Service) Revoke(ctx context.Context, db database.TenantDB, grantID uuid.UUID) error

Revoke closes a grant's validity window (soft revoke; grants are auditable). The caller must be able to write the grant's document — the same gate as Grant (SEC-43); the restrictive grant-ownership RLS policy is the DB-level backstop.

func (*Service) SweepRetention

func (s *Service) SweepRetention(ctx context.Context, plat database.TxManager, tenantID uuid.UUID, at time.Time) (int, error)

SweepRetention voids every active version of every document whose retention has lapsed (legal-hold documents are skipped) and tombstones the rows, then deletes the blobs. Runs as app_platform, tenant-bound. The row voiding commits FIRST; blob deletion happens only AFTER the commit succeeds (SEC-48) — so a mid-sweep failure never leaves an active row pointing at a deleted blob. A blob-delete failure after commit merely orphans the blob (swept by a future storage GC). Idempotent: a re-run over an already-swept tenant voids nothing. Returns the number of versions voided.

func (*Service) UpdateScanStatus

func (s *Service) UpdateScanStatus(ctx context.Context, plat database.TxManager, tenantID, versionID uuid.UUID, result string) error

UpdateScanStatus records the result of an async malware scan. Runs as app_platform (document_versions is append-only to the module role); a scan may only leave the pending state once.

type UploadEvent

type UploadEvent struct {
	DocumentID  string
	Class       string
	VersionNo   int
	StorageKey  string
	MIME        string
	SizeBytes   int64
	Sensitivity Sensitivity
}

UploadEvent is passed to OnFileUpload hooks after a version's bytes are verified but before the version row is committed. A hook returning an error aborts the confirm (the version is not written). The canonical hook enqueues an async malware scan; the version lands scan_status=pending and downloads of confidential+ documents block until the scan clears it.

type UploadHook

type UploadHook func(context.Context, UploadEvent) error

UploadHook runs on confirm; AccessHook runs on download.

type UploadSession

type UploadSession struct {
	DocumentID uuid.UUID
	VersionNo  int
	StorageKey string
	Upload     storage.PresignedURL
}

UploadSession is what a client needs to PUT a version's bytes.

Jump to

Keyboard shortcuts

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