Kandra.Forms
Kandra.Forms.Accounting.AccountSubcontoSlotDto
One subconto slot declaration on a leaf account (Kandra.Domain.Accounting.SubcontoSlotDeclaration) - a declared TYPE, not a resolved value (there's no posted transaction here). A composite ("OneOf") slot has more than one MemberTypes entry, e.g. account 68's slot 2 (Waybill/GoodsReceipt) - never flattened away, or the OR structure of the declaration is lost.
Kandra.Forms.Accounting.AccountSubcontoTypeDto
One acceptable CLR type for a subconto slot. TypeId matches the same Guid ISubcontoResolutionService/ AccountTransactionsService use to key resolved subconto VALUES elsewhere, so a consumer can correlate a slot declaration here with a resolved SubcontoValueDto. TypeCaptionKey/TypeCaptionIsLiteral is the same resolved-client-side pair as SubcontoValueDto (unlike ChartOfAccountsNodeDto.Name above, which is baked server-side) - this is the Account Transactions viewer's own caption technology, reused as-is.
Properties
| Property | Description |
|---|---|
Kind | Dictionary/Document/Enum/Other - see SubcontoKind's own doc comment. |
Kandra.Forms.Accounting.AccountTransactionRowDto
One posted ledger row (both sides of an elementary posting - see Kandra.Domain.Accounting.PostingTransactionRecord). Unlike a register-transactions row (Kandra.Forms.Registers.RegisterTransactionRowDto), there is no shared per-reader field "shape" to hoist metadata into - the subconto set on each side depends on which account this specific row posted to, so every SubcontoValueDto is fully self-describing instead.
Properties
| Property | Description |
|---|---|
DestinationSubconto | undocumented |
SourceSubconto | undocumented |
Kandra.Forms.Accounting.ChartOfAccountsNodeDto
One node in the chart-of-accounts tree (folder or leaf). The whole chart is returned as a single eagerly-nested payload in one call (see Kandra.Application.Abstractions.Services. IChartOfAccountsTreeService) rather than the flat/lazy-per-level shape hierarchical dictionaries use (Kandra.Forms.Dictionaries.HierarchicalLookupItemDto) - the whole in-memory chart is a few dozen nodes rebuilt once per process (Kandra.Domain.Accounting.ChartOfAccounts), so per-level round-trips would be pure ceremony. There is no Guid Id: an AccountNode's identity is its AccountCode (see Code below), so account selector components bind by that string, not by Guid like every other selector.
Properties
| Property | Description |
|---|---|
Children | Empty for a leaf. |
Code | Dot-joined account code, e.g. "68" or "28.1" (Kandra.Domain.Accounting.AccountCode.ToString()/ .Parse()) - the whole identity of this node. |
Name | Pre-localized display name, baked server-side (IsLiteral ? Name : localizer[Name]) - mirrors AccountTransactionsService's own convention for AccountNode display names. |
Subconto | Empty for a folder. 0-5 entries (AccountLeafBase.MaxSubconto), one per declared subconto slot in AccountLeafBase.SubcontoSlots order. |
Kandra.Forms.Accounting.SubcontoEnumValues<T0>
Guid <-> enum-member resolution for a subconto-backing enum (one decorated with [SubcontoId] per member, e.g. CostingMethod), for anything that needs to bind a Guid to one of these members without pulling in Kandra.Domain.Accounting.EnumSubconto<TEnum> (server-only). Static generic class - per-closed-TEnum cache, same trick EnumSubconto<TEnum> itself already documents. Deliberately a separate, independent implementation of the same small reflection snippet EnumSubconto<TEnum>.ResolveValueIds() uses, rather than a shared refactor - avoids adding a Kandra.Domain -> Kandra.Forms reference for a UI-only concern.
Kandra.Forms.Accounting.SubcontoValueDto
One resolved subconto (analytical dimension) value - self-describing (carries its own type caption) since, unlike a register field, there is no shared per-reader metadata list this could be correlated against by PropertyName. Reference/FormattedValue are mutually exclusive, mirroring Kandra.Forms.Registers.RegisterFieldValueDto's own convention: Reference is set for a dictionary-kind subconto (Item/Counterparty/Warehouse/...), FormattedValue for a document-kind one (Waybill/ GoodsReceipt/...) - documents have no Name property, so Kandra.DtoCommon.Printing.CodeNameRef doesn't fit them; FormattedValue is server-pre-formatted instead (e.g. "GR.26000123 (02.09.2026)").
Kandra.Forms.Blobs.BlobReferenceAdminViewDto
Kandra.Forms.Blobs.BlobReferenceMetadataDto
Kandra.Forms.Blobs.BlobReferenceSearchQueryDto
Kandra.Forms.Blobs.BlobUploadResultDto
Kandra.Forms.ChangeTracking.ChangeEventEntryDto
Kandra.Forms.ChangeTracking.ChangeEventQueryDto
Kandra.Forms.ChangeTracking.ChangeHistoryEntryDto
Kandra.Forms.ChangeTracking.ChangeStateDto
Kandra.Forms.Constants.ConstantHistoryEntryDto
One row for a single constant, as returned by ConstantsController.GetHistoryAsync.
Properties
| Property | Description |
|---|---|
Date | The row's effective instant - see ConstantSummaryDto.SetAt's doc comment. |
Id | The row's own id - pass this to the admin API's delete endpoint (not Date, which is a real instant now and needlessly fragile to round-trip through a URL). |
ValueJson | The bare value's JSON, unwrapped the same way as ValueJson. |
ValueKind | Same per-constant classification as ValueKind - repeated on every row so the client can open an edit-in-place dialog straight from a history row, without a second round trip to look up the constant's declared value type. |
Kandra.Forms.Constants.ConstantSummaryDto
One declared constant's current effective value, as returned by the admin Constants list (ConstantsController.GetAllAsync). Every [KandraConstant] class known to IConstantRegistry appears here, even ones never overridden in the database.
Properties
| Property | Description |
|---|---|
HasFutureOverride | True when at least one row exists dated after now - a value already scheduled to take effect later, which would otherwise be entirely invisible from this row (its own ValueJson/SetAt only ever reflect what's effective right now). Check the History dialog for the scheduled row(s). |
Id | The backing row's id when IsOverridden is true (null otherwise) - edit this exact row via the id-keyed update endpoint rather than re-deriving SetAt. |
IsOverridden | False when nothing has ever been written for this constant - ValueJson is then the compiled default from the constant's own descriptor class. |
SetAt | The exact instant ValueJson's row took effect from. Null when IsOverridden is false. A genuine UTC instant (not day-truncated) - the client's shared UtcToLocalDateTimeJsonConverter is exactly right for this, converting it to the viewer's own local time for display. |
ValueJson | The bare value's JSON (e.g. "UAH", 4.5, true) - never the {"Value": ...} storage envelope, which the controller unwraps before mapping. |
Kandra.Forms.Constants.ConstantValueKind
Coarse classification of a constant's declared value type (Constant<T>'s T) - lets a UI pick an appropriate input control (text box, numeric field, switch, date picker) without needing Type to cross the wire. Resolved server-side (ConstantsController) from IConstantRegistry's ValueType metadata.
Fields
| Field | Description |
|---|---|
Other | Any other declared value type - not a real shape in this codebase today, kept as a forward-compatible fallback so a new constant value type never breaks classification. Rendered as a plain JSON text box. |
Kandra.Forms.Constants.SetConstantValueDto
Request body for ConstantsController's PUT endpoint.
Properties
| Property | Description |
|---|---|
Date | Effective instant for this value; defaults to now when omitted. A genuine UTC instant (not day-truncated) - the client must set Kind = DateTimeKind.Utc on an already-correctly-computed value before sending, or the shared UtcToLocalDateTimeJsonConverter will (mis)treat it as local time needing conversion. See ConstantEditDialog.razor's effective-date computation. |
ValueJson | The bare value's JSON (e.g. "UAH", 4.5, true) - the controller wraps it into the {"Value": ...} storage envelope via IConstantsManageService.SetRawAsync. |
Kandra.Forms.Constants.UpdateConstantValueDto
Request body for ConstantsController's id-keyed value-update endpoint - deliberately carries no date/instant field, since this path never touches a row's effective instant (see IConstantsManageService.UpdateValueAsync's doc comment for why).
Properties
| Property | Description |
|---|---|
ValueJson | The bare value's JSON (e.g. "UAH", 4.5, true) - the controller wraps it into the {"Value": ...} storage envelope via IConstantsManageService.UpdateValueAsync. |
Kandra.Forms.DataProcessors.IDataProcessorInputDto
Kandra.Forms.DataProcessors.IDataProcessorResultDto
Kandra.Forms.Dictionaries.HierarchicalLookupItemDto
Kandra.Forms.Dictionaries.HierarchicalLookupMode
Fields
| Field | Description |
|---|---|
AllFolders | undocumented |
AllLeaves | undocumented |
Breadcrumbs | undocumented |
Children | undocumented |
FoldersUnderId | undocumented |
LeavesUnderId | undocumented |
Self | undocumented |
Subtree | undocumented |
SubtreeExcludingSelf | undocumented |
Kandra.Forms.Dictionaries.IHierarchicalLookupItemDto
Kandra.Forms.Dictionaries.ILookupItemDto
Kandra.Forms.Dictionaries.LookupItemDto
Kandra.Forms.Documents.DocumentLookupItemDto
Kandra.Forms.Handlers.EmptyHandlerDto
Reusable "no meaningful payload" DTO — usable as either TIn or TOut for a handler that doesn't need one.
Kandra.Forms.Handlers.IHandler<T0, T1>
Marker contract a document/dictionary/report's own handler-marker type implements, e.g. sealed class PriceLookupHandler : IHandler<PriceLookupRequestDto, PriceLookupResponseDto> — the closed TIn/TOut are what the discovering generator reads off this interface. The handler's name (the DI key its backend IHandlerBehavior<TIn,TOut> is registered under, and the literal route segment api/v1/handlers/{Name} the generated controller exposes) lives solely on the [KandraHandler(Name = "...")] attribute — not duplicated here as an interface member, since the generator can only read it from attribute metadata anyway (see HandlerDiscovery). The marker type also carries whatever static FillRequestFrom/ApplyResponseTo overloads make sense for the documents that call it — not part of this interface either, since their signatures are document-specific.
Kandra.Forms.Handlers.ILocalHandler
Marker contract for a UI-only handler — a named class that recomputes a value on an already-in-memory Dto (and optionally a line), with no backend leg at all: no request/response DTO, no IHandlerBehavior, no generated controller, no Refit client. Unlike IHandler there's no TIn/ TOut to deduce — a local handler isn't a wire contract, so the interface stays a pure, member-less marker. The concrete class's HandleAsync (and any helper methods it needs) are plain static methods with whatever call-site-specific signature/overloads make sense — same rule IHandler already applies to FillRequestFrom/ApplyResponseTo, taken one step further since there isn't even a fixed HandleAsync(TIn,...) shape to conform to. The class is decorated with [KandraLocalHandler(Name = "...")] — Name is enforced unique by the same generator pass that enforces uniqueness for [KandraHandler], for consistency with that requirement (a Dto property's [HandlerTrigger] attribute references the handler by Type, not by this name).
Kandra.Forms.IEntityDto
Kandra.Forms.Linking.DocumentLinkRowDto
One resolved link row - the other entity's side only (the viewer already knows which document it's looking at). Same self-describing-type-caption shape as Kandra.Forms.Accounting.SubcontoValueDto, deliberately reused rather than inventing a second convention for "a typed entity reference plus a display caption".
Properties
| Property | Description |
|---|---|
LineId | undocumented |
Reference | undocumented |
Kandra.Forms.Linking.DocumentLinksDto
Both directions of a document's Document Links, for the generated View page's Links tab (see docs on IDocumentLinkService.GetLinksAsync).
Properties
| Property | Description |
|---|---|
LinksFrom | undocumented |
LinksTo | undocumented |
Kandra.Forms.Other.InterfaceDto
The full tree returned by GET api/v1/interfaces/{name}.
Kandra.Forms.Other.InterfaceNodeDto
Properties
| Property | Description |
|---|---|
Children | Set for Folder, empty for Link. |
Href | Set for Link, null for Folder. |
Kandra.Forms.Other.InterfaceNodeDtoKind
On the wire, an Entity/Special/Link node (server-side Kandra.Application.Abstractions. Navigation.InterfaceNodeKind) is already fully resolved down to a plain link - the client never needs to know which of those three it originally was, only that it's a leaf with an Href. Only Folder-vs-leaf actually changes how the client renders a node (MudNavGroup vs MudNavLink).
Kandra.Forms.Other.InterfaceSummaryDto
One entry of GET api/v1/interfaces - just enough to list/switch between the Interfaces the current user can see. TitleKey is a resource key (or a literal when TitleIsLiteral is set), resolved client-side with the live IStringLocalizer, same as every other nav caption in the app.
Kandra.Forms.Printable.PrintFormBase
Base for print-form DTOs — a plain, inert data shape, no rendering behavior.
Kandra.Forms.Printable.PrintFormLineBase
Base for a print-form's tabular part line — a plain, inert data shape, no rendering behavior.
Kandra.Forms.Printing.DocumentExportRequest
Properties
| Property | Description |
|---|---|
Format | undocumented |
LayoutTag | undocumented |
Kandra.Forms.Printing.ReportExportRequest<T0>
Properties
| Property | Description |
|---|---|
LayoutTag | undocumented |
Kandra.Forms.Querying.DateRangeDto
A reusable From/To date range, for any query/filter Dto property that needs one.
Kandra.Forms.Querying.DictionaryQueryDto
Properties
| Property | Description |
|---|---|
Id | undocumented |
Ids | undocumented |
Kandra.Forms.Querying.DocumentQueryDto
Properties
| Property | Description |
|---|---|
Id | undocumented |
Kandra.Forms.Querying.HierarchicalDictionaryQueryDto
Properties
| Property | Description |
|---|---|
Mode | undocumented |
Kandra.Forms.Registers.DocumentRegisterTransactionsDto
Every register a Document type is declared to touch (via [RegisterTransactions] on its Behavior), each carrying its own resolved movement/document-info-record rows for one document instance. Empty for a Document with no [RegisterTransactions] attributes — not an error, just "nothing to show".
Kandra.Forms.Registers.RegisterFieldKind
How a register transactions viewer field should be rendered — resolved server-side (dimension classification walks the register's Dimensions/Resources/Details CLR shape), consumed purely as data client-side (no client-side type inspection needed to pick a rendering).
Fields
| Field | Description |
|---|---|
Dictionary | Guid FK resolved to a Dictionary entity — the row's matching Reference is populated. |
Document | Guid FK resolved to a Document entity — reference-value resolution not implemented yet, renders as an unresolved Guid. |
DynamicReference | [ReferenceOf(TypeIdProperty = ..., PossibleTypes = ...)] — the target type varies per row, identified at read time by a sibling TypeId property elsewhere on the same register row. Resolves to Reference (Dictionary candidate) or DocumentReference (Document candidate), never both. |
User | Guid FK resolved to the Identity user entity — reference-value resolution not implemented yet, renders as an unresolved Guid. |
Kandra.Forms.Registers.RegisterFieldMetaDto
One Dimensions/Resources/Details column's display metadata — shared by every row of the owning RegisterTransactionsDto.
Properties
| Property | Description |
|---|---|
ReferencedTypeId | Set only when Kind is Dictionary or Document — the referenced CLR type's IEntityWithTypeId.TypeId. |
Kandra.Forms.Registers.RegisterFieldValueDto
One field's value on one RegisterTransactionRowDto, correlated to its RegisterFieldMetaDto by PropertyName.
Properties
| Property | Description |
|---|---|
DocumentReference | Set for a DynamicReference field resolved to a Document candidate — see Kind. |
FormattedValue | Pre-formatted server-side (Kandra.Printing.PrintValueFormatter.Format) — null when Reference is set instead. |
Reference | Set for a Dictionary-kind field, or a DynamicReference field resolved to a Dictionary candidate — see Kind. |
TypeCaptionKey | Set only for a DynamicReference field (the resx key naming which of its declared PossibleTypes this row actually resolved to, e.g. "GoodsReceipt" — same convention Kandra.Persistence.Abstractions. Accounting.ResolvedSubconto.TypeCaptionKey already uses: the CLR type's own simple name, always a resx key, never a literal). Null for every other Kind, including a static Dictionary/Document field — those already say what they reference via their own column caption. |
Kandra.Forms.Registers.RegisterTransactionRowDto
One register movement/document-info-record row, resolved for display.
Properties
| Property | Description |
|---|---|
IsExpense | Null for DocumentInfoRecord-family rows — the concept only exists on Movement rows. |
Kandra.Forms.Registers.RegisterTransactionsDto
One register's resolved movement/document-info-record rows for one document instance, plus the field metadata (captions/kinds) needed to render them without the client knowing this register's CLR shape.
Properties
| Property | Description |
|---|---|
RegisterName | Stable/internal register row type name, e.g. "InventoryMovement" — not localized, not shown as-is. |
Resources | Empty for a DocumentInfoRecord-family register (Resources only exist on Movement rows). |
Kandra.Forms.Reports.ICustomAggregate
Contract for a report-line-specific custom group-footer aggregate - the counterpart to ILocalHandler for aggregates (same "attribute references by Type, implementation is a plain static-method class, no DI" shape). Implementations live alongside the report line Dto they aggregate (referenced by [Aggregate(CustomAggregateType = typeof(...))] on one of its properties) and are invoked via a direct static generic call at the generated column's emission site, not through the interface - the interface only enforces the contract shape at the implementing class's declaration. format is the column's own [Format] string (e.g. "N3"), passed through so the aggregate's own computed value renders with the same format as the column's individual cells instead of a hardcoded one - null when the column carries no [Format].
Kandra.Forms.Reports.IReportFiltersDto
Kandra.Forms.Reports.IReportResultDto
Properties
| Property | Description |
|---|---|
CacheTag | undocumented |
Kandra.Forms.Reports.IReportResult<T0, T1>
Splits the technical envelope (Filters/CacheTag, via the base IReportResult) from the report's actual business/print data - TData is what carries [PrintForm]/[PrintTable]/ [PrintSectionRef], not the wrapper itself.
Kandra.Forms.Reports.ReportGroupingState
Ordered set of a report result grid's currently-grouped column property names, outermost-first (MudDataGrid nests later-grouped columns inside earlier-grouped ones). Backed by a List, not a Queue - a real queue doesn't support arbitrary-position removal, which ungrouping a non-last column needs. "FIFO" only in the sense that grouping always appends to the end; ungrouping can remove from anywhere.
Properties
| Property | Description |
|---|---|
FrontGroup | Outermost/first-grouped column, or null if nothing is grouped - what a conditional aggregate (ICustomAggregate) checks against. |
Methods
| Method | Description |
|---|---|
Set(String, Boolean) | Call from a column's GroupingChanged handler: grouped=true appends propertyName if not already present; grouped=false removes it from wherever it sits. |
Kandra.Forms.Reports.ReportResult<T0, T1>
Base implementation of a report result's technical envelope - Filters/Data/CacheTag - so a concrete report result is just a closed generic with no members of its own, e.g. sealed class RestsReportResult : ReportResult<ReportRestsDto, RestsReportDataDto>;
Kandra.Forms.Scheduling.JobStateDto
Kandra.Forms.Scheduling.ScheduledJobDto
Properties
| Property | Description |
|---|---|
ProcessorName | undocumented |
State | undocumented |
Kandra.Forms.Scheduling.TriggerConfigDto
Properties
| Property | Description |
|---|---|
CronExpression | undocumented |
IntervalSeconds | undocumented |
RepeatCount | undocumented |
TimeZoneId | undocumented |