Register Design
MCP routing
- Preferred path: use MCP
unicatoolsunica.view {},unica.viewon the object node,unica.apply,unica.search,unica.viewon the schema node,unica.check, andunica.run. - Runtime идёт через
unica.run: вызов безopотдаёт словарь операций и контракт каждой —argsSchema,execution,previewRequired,ifRevRequiredOnApply. Контракт вызова бери оттуда, а не из этого текста; выбирай только операцию сimplemented: trueи не выдумывай аргументов записи сargsSchema: null; превью исполнением не является. Не обходи контракт прямым runner-ом. - Use
unica.docswithsource: "development-standard"for the standards about registers: 447, 477, 657, 661, 663, 664, 708, 733, 792, and diagnostics АПК:123, АПК:229, BSLLS:DenyIncompleteValues, BSLLS:VirtualTableCallWithoutParameters. These are standards, not evidence of runtime behavior; confirm the wording before citing one. - Use
unica.viewon the role node when the register is subordinate to a recorder or carries access restrictions. - Do not call internal analyzer, runtime, standards, or package adapters directly. They are hidden behind MCP
unica.
References
- Read
../../references/platform/register-design.mdfor register class choice, the dimension/resource/attribute split, periodicity, totals, read paths, and bulk writes. - Read
../../references/platform/document-posting.mdwhen the register is written by document posting. - Read
../../references/platform/db-performance.mdwhen the register is already slow or contended.
Core model
Four decisions, in this order, and each one narrows the next:
- Which class: information register for state keyed by dimensions, accumulation register with
RegisterType = Balancesfor what comes in and goes out,RegisterType = Turnoverswhen balance is meaningless, accounting register for double entry, calculation register for accruals with an action period. - What is a key: a dimension is a key, a resource is an aggregatable value, an attribute is neither. For a
Balancesregister a dimension must be meaningful for both receipt and expense. - How it is read:
Остаткиgets the platform's cheapest plan only without totals separation, without a date parameter, and with every virtual table dimension used in the outer query (std733). - How it is written: one set per batch, not one write per row (std792).
Totals separation is the decision that pulls both ways: std664 wants it for write concurrency, std733 forbids it for the fastest balance read. Name the side and the reason.
Workflow
- State the accounting subject and the questions the register must answer. One subject, one register.
- Pick the class, then split every field into dimension, resource, or attribute before creating anything. Check the receipt/expense rule for every candidate dimension of a
Balancesregister. - Inspect neighbours with
unica.viewon the object node — an existing register with the same subject is a reason to extend rather than add — and locate the read paths withunica.search,unica.viewon the module node (itsMethodbranch lists the methods), andunica.viewon the schema node. - Decide periodicity and
WriteModefor an information register, and whether every std708 condition holds before enablingEnableTotalsSliceLastorEnableTotalsSliceFirst. - Decide
EnableTotalsSplittingagainst the read paths found in step 3, not in the abstract. - Set
DenyIncompleteValueson dimensions that must always carry a value, and decideMasterdeliberately: it makes record lifetime follow the master value. - Create with
unica.applyand refine withunica.apply, one verifiable step at a time. - Verify statically with
unica.checkon the module node (test runs are outside the v0.13 surface), report runtime behavior as unverified, and re-check the read paths that step 5 traded against.
Design rules
- A register must be logically independent of its recorders: no logic or report may reach a recorder field through a dot (std477, АПК:123). In a distributed infobase the movements can migrate to a node where the recorder does not exist.
- Parallelism follows the dimension set, because balances for one dimension combination live in one resource (std664).
- Filters go in the virtual table parameters, not in an outer
ГДЕ(std657). A virtual table called with no parameters isBSLLS:VirtualTableCallWithoutParameters. - Read information register data with a query when nothing will be modified. Use
РегистрСведенийМенеджерЗаписиonly when the filter covers every dimension at once; otherwise use a record set (std447). - Batch writes around 1000 records per set, and do not rewrite a large set when 30% or fewer of its records change — a rewrite reinserts unchanged rows and inflates the DBMS transaction log (std792).
- A role must not grant modification rights on a register subordinate to a recorder (АПК:229).
Review checklist
- Every dimension of a
Balancesregister is meaningful on both receipt and expense. - Resources hold only aggregatable values; accompanying data sits in attributes.
DenyIncompleteValuesis set on dimensions that cannot be empty.EnableTotalsSplittingmatches a named decision about write concurrency versus balance read speed.- Slice totals on a periodic information register satisfy every std708 condition.
- No query or report reaches a recorder field through a dot.
- Virtual tables are called with their filters as parameters.
- Register writes go through record sets in batches, not per-record in a loop.
- No role grants modification rights on a recorder-subordinate register.
Stop rules
- Do not add a dimension to a
Balancesregister that is meaningful on only one record direction. - Do not enable totals separation without naming the read path it costs, or disable it without naming the write contention it restores.
- Do not change dimensions, resources, periodicity, or
WriteModewithout a stated migration for the data already stored. - Do not claim a register read got faster without a before/after measurement on comparable volume.
Contract gaps
If public MCP unica cannot inspect the register, its recorders, its read paths, or the runtime evidence needed for the task, report a Unica MCP contract gap with the missing operation.