batch

package
v0.107.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package batch is the one op-list machinery behind Koha's batch record modification, MARC modification templates, and advanced-editor macros (tasks/047): a Selection names a set of Works, an editor.Op list names the edit, and the executor applies it per grain with per-record results -- dry-run first, exact quad deltas, everything audited. Saved queries and macros live in the datastore; a shared macro run over a selection is the modification-template shape.

Index

Constants

View Source
const (
	KindIDs         = "ids"
	KindSearch      = "search"
	KindSavedQuery  = "savedQuery"
	KindAll         = "all"
	KindImportBatch = "importBatch"
)

Selection kinds. importBatch is reserved for copy cataloging (tasks/050) and rejected until an import surface exists.

Variables

View Source
var ErrForbidden = errors.New("batch: not the owner")

ErrForbidden reports an edit to somebody else's macro.

View Source
var ErrNotFound = errors.New("batch: not found")

ErrNotFound reports a missing macro or saved query.

View Source
var ErrValidation = errors.New("batch: invalid request")

ErrValidation reports a request the executor refuses to run.

View Source
var ReservedShortcutKeys = map[string]string{
	"1": "the Native tab",
	"2": "the MARC tab",
	"3": "the History tab",
	"p": "preview staged changes",
	"m": "the live MARC preview pane",
	"?": "the help overlay",
	"g": "the go-to-screen prefix",
}

ReservedShortcutKeys are the single-character chords the editor already claims, mapped to the action that holds each (tasks/237). A macro keyed to one of them used to win by registering later, silently disabling the chord -- and the "?" overlay, which renders from the same registry, stopped listing it. Rejecting the macro at the source is the only place the cataloger can be told which action they would have broken.

This table is mirrored in backend/ui/src/lib/keyboard.ts (EDITOR_CHORDS), and TestReservedShortcutKeysMatchUI / keyboard.test.ts pin them together. "mod+s" is absent because a shortcut key is one character and can never collide with it.

Functions

func ApplyParams

func ApplyParams(m Macro, values map[string]string) ([]editor.Op, error)

ApplyParams substitutes ${name} references in the macro's op values from the caller's values (falling back to declared defaults) and returns the concrete op list. An unresolved reference fails closed -- a template never silently writes its placeholder text into a record.

A blank caller value means "use the default", exactly like an omitted one (tasks/231): the parameter field advertises the default as its placeholder and the client's own lookup skips blanks, so a cleared field must not override the default here either -- a macro means the same thing replayed in the editor or run over a selection.

Types

type IndexUpdater added in v0.48.0

type IndexUpdater interface {
	Apply(grainPath, etag string, grain []byte)
	AppendFeed(ctx context.Context, paths ...string) error
}

IndexUpdater is the workindex.Index surface batch writes keep exact: Apply folds one written grain in, AppendFeed publishes the changed paths so other containers read-their-writes without a corpus List.

type ItemResult

type ItemResult struct {
	WorkID string       `json:"workId"`
	ETag   string       `json:"etag,omitempty"`
	Error  string       `json:"error,omitempty"`
	Diff   *editor.Diff `json:"diff,omitempty"`
}

ItemResult is one Work's outcome in a run.

type ItemTemplate

type ItemTemplate struct {
	OwnedMeta
	CallNumber string `json:"callNumber,omitempty"`
	Location   string `json:"location,omitempty"`
	Note       string `json:"note,omitempty"`
	// BarcodePrefix seeds bulk add ("B-" -> B-0001, B-0002, ...).
	BarcodePrefix string `json:"barcodePrefix,omitempty"`
	// BarcodeWidth is the zero-padded counter width (default 4).
	BarcodeWidth int `json:"barcodeWidth,omitempty"`
}

ItemTemplate is a saved item field set (tasks/069): applied it pre-fills the item form; its barcode prefix seeds bulk add's auto-incrementing pattern. Personal or library-shared on the macros sharing model.

type Macro

type Macro struct {
	OwnedMeta
	Keys   string      `json:"keys,omitempty"`
	Ops    []editor.Op `json:"ops"`
	Params []Param     `json:"params,omitempty"`
}

Macro is a replayable op list (tasks/047): recorded in the editor, replayed against another record, or -- when shared -- run over a batch selection, which is the MARC-modification-template shape. Keys optionally names a single-character editor shortcut.

type OwnedMeta

type OwnedMeta struct {
	ID        string    `json:"id"`
	Label     string    `json:"label"`
	Shared    bool      `json:"shared"`
	Owner     string    `json:"owner"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

OwnedMeta is the shared identity/sharing surface of the owned-or-shared record shapes (macros, item templates): one record per item, living in the owner's partition or the library-shared one, owner-gated for writes.

type Param

type Param struct {
	Name    string `json:"name"`
	Label   string `json:"label,omitempty"`
	Default string `json:"default,omitempty"`
}

Param declares one macro parameter, referenced in op values as ${name}.

type RunResult

type RunResult struct {
	DryRun         bool         `json:"dryRun"`
	Matched        int          `json:"matched"`
	Applied        int          `json:"applied"`
	Failed         int          `json:"failed"`
	Added          int          `json:"added"`
	Removed        int          `json:"removed"`
	Results        []ItemResult `json:"results"`
	DiffsTruncated bool         `json:"diffsTruncated,omitempty"`
}

RunResult summarizes a batch run. Added/Removed aggregate the quad deltas across every work (dry-run and execute alike).

type SavedQuery

type SavedQuery struct {
	ID        string    `json:"id"`
	Label     string    `json:"label"`
	Query     string    `json:"query"`
	Owner     string    `json:"owner"`
	CreatedAt time.Time `json:"createdAt"`
}

SavedQuery is a named works search, the reusable half of a Selection.

type Selection

type Selection struct {
	Kind         string   `json:"kind"`
	IDs          []string `json:"ids,omitempty"`          // kind=ids
	Query        string   `json:"query,omitempty"`        // kind=search
	SavedQueryID string   `json:"savedQueryId,omitempty"` // kind=savedQuery
}

Selection names a set of Works to operate on.

type Service

type Service struct {
	Blob blob.Store
	DB   store.Store
	// Mapper is the static op mapper. MapperFn, when set, supersedes it so
	// runtime profile edits are picked up per run; leave Mapper for the
	// fixed-profile case (tests).
	Mapper   *editor.Mapper
	MapperFn func() *editor.Mapper
	// Queue, when set, receives one audit entry per execute run.
	Queue *suggest.Service
	// Trigger, when set, gets one grains-changed event per execute run.
	Trigger trigger.Notifier
	// Prefix is the grain tree root ("" = repo layout).
	Prefix string
	// MaxWorks bounds a run's selection (0 = defaultMaxWorks).
	MaxWorks int
	// Summaries, when set, is the shared maintained summary source
	// (workindex, tasks/109) search selections resolve against instead of a
	// per-run corpus walk; nil falls back to ScanSummaries.
	Summaries ingest.SummarySource
	// Labels, when set, writes vocabulary label companions next to term
	// IRIs a batch edit asserts (editor.ApplyOps, tasks/145).
	Labels editor.LabelResolver
	// Index, when set, is kept exact for this run's own writes -- the same
	// read-your-writes contract the single-record path holds (tasks/195).
	// Without it, batch edits wait out the workindex refresh TTL: invisible
	// to work search for up to 30s, and a chained batch selection resolves
	// against the stale index.
	Index IndexUpdater
}

Service resolves selections and executes op batches over the grain tree.

func (*Service) CreateItemTemplate

func (s *Service) CreateItemTemplate(ctx context.Context, t ItemTemplate, owner string) (ItemTemplate, error)

CreateItemTemplate validates and stores a template for owner (in the shared partition when t.Shared). The id is minted server-side.

func (*Service) CreateMacro

func (s *Service) CreateMacro(ctx context.Context, m Macro, owner string) (Macro, error)

CreateMacro validates and stores a macro for owner (in the shared partition when m.Shared). The id is minted server-side. A shortcut key already held by another macro visible to this owner refuses (tasks/237).

func (*Service) CreateQuery

func (s *Service) CreateQuery(ctx context.Context, label, query, owner string) (SavedQuery, error)

CreateQuery stores a named search for owner. Label and query validate after normalization: a whitespace-only query would persist a selection that forever resolves to the entire catalog (tasks/205).

func (*Service) DeleteItemTemplate

func (s *Service) DeleteItemTemplate(ctx context.Context, owner, id string) error

DeleteItemTemplate removes an owned template (shared or personal).

func (*Service) DeleteMacro

func (s *Service) DeleteMacro(ctx context.Context, owner, id string) error

DeleteMacro removes an owned macro (shared or personal).

func (*Service) DeleteQuery

func (s *Service) DeleteQuery(ctx context.Context, owner, id string) error

DeleteQuery removes one of the owner's saved queries.

func (*Service) GetItemTemplate

func (s *Service) GetItemTemplate(ctx context.Context, owner, id string) (ItemTemplate, error)

GetItemTemplate resolves a template the caller can use: their own, or a shared one.

func (*Service) GetMacro

func (s *Service) GetMacro(ctx context.Context, owner, id string) (Macro, error)

GetMacro resolves a macro the caller can run: their own, or a shared one.

func (*Service) GetQuery

func (s *Service) GetQuery(ctx context.Context, owner, id string) (SavedQuery, error)

GetQuery reads one of the owner's saved queries.

func (*Service) ListItemTemplates

func (s *Service) ListItemTemplates(ctx context.Context, owner string) ([]ItemTemplate, error)

ListItemTemplates returns the caller's templates plus every shared one, sorted by label.

func (*Service) ListMacros

func (s *Service) ListMacros(ctx context.Context, owner string) ([]Macro, error)

ListMacros returns the caller's macros plus every shared macro, sorted by label.

func (*Service) ListQueries

func (s *Service) ListQueries(ctx context.Context, owner string) ([]SavedQuery, error)

ListQueries returns the owner's saved queries in creation order.

func (*Service) Resolve

func (s *Service) Resolve(ctx context.Context, sel Selection, owner string) ([]Target, error)

Resolve expands a selection to its targets, owner-scoped for saved queries. Ids resolve without titles (no corpus scan); search kinds carry the summary title for preview listings.

func (*Service) Run

func (s *Service) Run(ctx context.Context, sel Selection, ops []editor.Op, dryRun bool, actor string) (RunResult, error)

Run applies ops to every work in the selection. Ops must target the work resource -- instance ids are per-record and meaningless across a selection. DryRun reads and diffs without writing; execute CAS-writes each grain and reports per-record success or failure, then audits and notifies once.

func (*Service) UpdateItemTemplate

func (s *Service) UpdateItemTemplate(ctx context.Context, id string, t ItemTemplate, owner string) (ItemTemplate, error)

UpdateItemTemplate replaces a template's definition. Only the owner may update; flipping Shared moves the record between partitions.

func (*Service) UpdateMacro

func (s *Service) UpdateMacro(ctx context.Context, id string, m Macro, owner string) (Macro, error)

UpdateMacro replaces a macro's definition. Only the owner may update, and flipping Shared moves the record between partitions.

type Target

type Target struct {
	WorkID string `json:"workId"`
	Title  string `json:"title,omitempty"`
	// contains filtered or unexported fields
}

Target is one resolved Work.

Jump to

Keyboard shortcuts

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