Register engine overview
Registers are Kandra's analytical/accounting layer — inventory balances, exchange rates, and similar running totals or event logs. See the practical guide's Creating a register for a task-oriented walkthrough; this page is the API-shape summary.
BalanceRegister<>(running totals) and the info-register family (InfoRegister/PeriodicInfoRegister/DocumentInfoRegister) are implemented and in active use.TurnoverRegister<>exists as infrastructure but has no live consumer in the reference configuration yet.- Concurrency uses a manually-incremented
Versionoptimistic-concurrency column with bounded retry (3 attempts) — a deliberate scope-down from a lock-free provider-specific atomic upsert, documented as such intechdebt/TECH_DEBT.md(TD-004). - Register writers are resolved only through
ISubmitScope.GetWriter<TWriter>()inside a document behavior'sOnSubmitAsync/OnDeleteAsync— never by ordinary constructor injection. BuildEqualityPredicate()(generated, see Source Generators) onIRegisterDimensions<TSelf>, combined withDimensionPredicateBuilder, is the accepted compile-time-typed way to filter to just the touched dimension rows instead of loading a whole balance table — use this pattern anywhere in the register engine rather than reflection-based filtering.
Full design: see the platform's docs/kandra-register-engine-design.md and
docs/1c-register-architecture.md.