Skip to main content

Kandra.DataImport

Kandra.DataImport.AdminCaller​

Runs a non-interactive flow (startup, setup) as the admin user when nobody is signed in.

Kandra.DataImport.CanonicalJson​

Canonical form of a package item, used to detect "the package changed" without caring about formatting: properties sorted by ordinal name at every level, no insignificant whitespace, numbers exactly as written, strings re-encoded the same way whichever escapes the source used. $ref/$code objects and date tokens are left unresolved on purpose - resolved values change every day ($today-23d) and would make every document look edited.

Methods​

MethodDescription
Hash(JsonNode)SHA-256 of the canonical JSON, lowercase hex (64 chars).

Kandra.DataImport.DataImportService​

The import engine. See IDataImportService and docs/kandra-data-import-design.md. Every write goes through IEntityOperationExecutor (the real CRUD services: behaviors, validators, posting and authorization run exactly as for a user), inside IImportStampScope so the row is stamped. Each item runs in its own DI scope (fresh DbContext - the same lifetime as one HTTP request) with the caller's identity copied across; there is no global transaction, the work is idempotent instead.

Constructors​

ConstructorDescription
DataImportService(IServiceScopeFactory, DbContext, IEntityOperationExecutor, ImportPackageValidator, ICallerContext, ILicenseService)The import engine. See IDataImportService and docs/kandra-data-import-design.md. Every write goes through IEntityOperationExecutor (the real CRUD services: behaviors, validators, posting and authorization run exactly as for a user), inside IImportStampScope so the row is stamped. Each item runs in its own DI scope (fresh DbContext - the same lifetime as one HTTP request) with the caller's identity copied across; there is no global transaction, the work is idempotent instead.

Methods​

MethodDescription
CheckLicenseAsync(ImportPackage, Pass, List<ImportDiagnostic>, CancellationToken)Fails before anything is written when the package would exceed the licence: documents count against the calendar month they are created in (all of them land in the current month), so the check is "documents this month + documents the package would create" against the monthly limit, plus the per-document line limit.
NormalizeForWire(JsonObject, EntityCatalogEntry)A hierarchical dictionary DTO is polymorphic on the wire: the folder/leaf discriminator is the string "1"/"0" and must be the first property. A package writes it as "isFolder": true.
Overlay(JsonObject, JsonObject, IReadOnlyList<EntityFieldInfo>, JsonObject, String)Lays the resolved package item over a base DTO (a New draft for inserts, the current DTO for updates).
SaveStateAsync(ImportPackage, Pass, CancellationToken)Written straight to the constants table (not through IConstantsManageService): it is bookkeeping, not a user-facing setting - no constants permission is needed, no change event is produced, and the row is not import-stamped.
Wire(String)undocumented
WithLineIds(JsonArray, JsonArray)Document lines need an id; keep the existing row's id at the same position on update so the line is rewritten, not replaced.
WithScopeAsync(Pass, Func<IServiceScope, Task>)Runs action in a fresh DI scope carrying this caller's identity and the import change origin.

Fields​

FieldDescription
PackageStateConstantPrefixReserved prefix of the constants rows that hold each package's state; deliberately not a registered [KandraConstant], so the Constants admin page never lists them.

Kandra.DataImport.DataImportService.Pass​

Properties​

PropertyDescription
Ids$id -> row id for everything processed so far (in a dry pass, planned inserts get a placeholder id).
PlannedCodes(entity, code) -> id, for dry passes where an earlier planned insert is referenced by $code.

Kandra.DataImport.DataImportServiceCollectionExtensions​

Methods​

MethodDescription
AddKandraDataImport(IServiceCollection, String)Registers the import package validator and schema provider. Requires AddKandraEntityOperations<TCatalog>() (the entity catalog and field metadata the validator and schema are built from).

Kandra.DataImport.DemoContentUpdater​

After an update that ships a newer demo package, applies it once at startup (see ApplyPendingUpdateAsync). Never blocks or fails the host.

Constructors​

ConstructorDescription
DemoContentUpdater(IServiceScopeFactory, ILogger<DemoContentUpdater>)After an update that ships a newer demo package, applies it once at startup (see ApplyPendingUpdateAsync). Never blocks or fails the host.

Kandra.DataImport.DemoInstallation​

What a demo installation was seeded from; read by the demo banner and by factory reset.

Constructors​

ConstructorDescription
DemoInstallation(String, DateTime)What a demo installation was seeded from; read by the demo banner and by factory reset.

Kandra.DataImport.DemoSeedResult​

Constructors​

ConstructorDescription
DemoSeedResult(Boolean, ImportReport, IReadOnlyList<String>)undocumented

Properties​

PropertyDescription
AlreadySeededThe installation already carries the demo marker: nothing was created (a newer package version, if any, is applied by ApplyPendingUpdateAsync).

Kandra.DataImport.DemoSeedingConstants​

Fields​

FieldDescription
MarkerConstantNameReserved name, deliberately not a registered [KandraConstant], so the Constants admin page never lists it.

Kandra.DataImport.DemoSeedingServiceCollectionExtensions​

Methods​

MethodDescription
AddKandraDemoSeeding<T0, T1>(IServiceCollection)Registers IDemoSeeding and the startup update of demo content. Needs AddKandraDataImport and an IDemoUserProvider if the configuration wants demo users.

Kandra.DataImport.DemoSeeding<T0, T1>​

Methods​

MethodDescription
CheckUserLimitAsync(IReadOnlyList<DemoUser>, CancellationToken)Free-tier fit: the demo users plus the existing real users must stay within the licensed user count.
EnsureCallerAsyncThe import runs as the calling user; at startup or from a setup flow nobody is signed in, so it runs as admin.
WriteMarkerAsync(DemoInstallation, CancellationToken)Written straight to the constants table, like the package state: bookkeeping, not a user-facing setting.

Kandra.DataImport.IDataImportService​

Applies an import package (docs/kandra-data-import-design.md) through the entity-operations layer. Idempotent: every row it writes carries an ImportStamp, so a re-run inserts what is missing, updates what the package changed, and leaves everything else (including rows users edited or deleted) alone unless the step's policies say otherwise. Demo seeding and real import use the same code; only the package's origin differs. Runs as the calling user (ICallerContext).

Kandra.DataImport.IDemoSeeding​

Turns an installation into a demo one: applies the configuration's demo import package through the import engine, creates the demo users and writes the installation marker (MarkerConstantName). Re-running is a no-op. A regular installation never calls it and so never has sample users.

Methods​

MethodDescription
ApplyPendingUpdateAsync(CancellationToken)When the installation is a demo one and its embedded package is newer than the applied one, runs the import so new demo objects appear (the default policies keep the user's own edits). Returns the report, or null when nothing was due.
DryRunAsync(String, CancellationToken)Runs everything SeedAsync would check or import, writing nothing: the licensed user limit and a dry run of the package. Lets a setup flow show errors instead of half-seeding. Throws like SeedAsync when there is no demo package or the demo users do not fit the licence.
GetInstallationAsync(CancellationToken)The marker, or null when this is not a demo installation.
SeedAsync(String, CancellationToken)undocumented

Kandra.DataImport.IImportPackageRegistry​

The packages a configuration ships as embedded resources (ImportPackages/*.json in its Application project, registered with AddImportPackages).

Methods​

MethodDescription
Open(String)Opens a fresh read stream over the package JSON; null when no such package.

Kandra.DataImport.IImportRowAccessor​

Per-entity-type EF access for the importer, behind a non-generic seam so the service needs no per-type code.

Methods​

MethodDescription
AdoptAsync(DbContext, Guid, ImportStamp, CancellationToken)Stamps an existing row without otherwise changing it (Adopted).
FindUnstampedByMatchAsync(DbContext, IReadOnlyList<ValueTuple<String, Object>>, CancellationToken)Not-deleted rows without a stamp whose properties equal the given values (EF-translatable, string/Guid/int/bool/decimal properties).
RestoreAsync(DbContext, Guid, Guid, CancellationToken)Clears the soft-delete flag (Restored); the importer then updates the row through the normal service.

Kandra.DataImport.IImportRunService​

Runs imports in the background and answers "what happened" afterwards. A large import takes longer than an HTTP request should, so Start returns a run id immediately; the run executes as the user who started it (identity and time zone are copied into the run's own DI scope). Live status and the report of recent runs (dry runs included) are held in memory; completed real runs also appear in the package state and keep their report as a blob.

Methods​

MethodDescription
ListRunsAsync(String, CancellationToken)Recent runs, newest first; of one package, or of every package when null.
Start(Byte[], String, ImportOptions)Starts a run over the package JSON and returns its id. Throws InvalidStateException when another import is running.

Kandra.DataImport.IImportSchemaProvider​

Builds the JSON Schema (draft 2020-12) of the import package format for this configuration, so editors (VS Code) can validate and autocomplete packages through $schema.

Kandra.DataImport.ImportDiagnostic​

One finding from reading/validating/applying a package. Path is a JSON-path-like locator, e.g. steps[2].items[0].lines[1].itemId.

Constructors​

ConstructorDescription
ImportDiagnostic(String, ImportDiagnosticSeverity, String)One finding from reading/validating/applying a package. Path is a JSON-path-like locator, e.g. steps[2].items[0].lines[1].itemId.

Kandra.DataImport.ImportEntityTypes​

Maps a catalog entry to the EF entity type behind it, and hands out the matching accessor.

Methods​

MethodDescription
EntityTypeOf(EntityCatalogEntry)The EF entity of a Dictionary/Document catalog entry: the type argument of the behavior's IDictionaryBehavior<TEntity> / IDocumentBehavior<TEntity> (for a hierarchical dictionary that is the root node type, which is the one EF maps and the repository is registered for).

Kandra.DataImport.ImportHostInfo​

The configuration an import host belongs to; a package declares the one it targets.

Constructors​

ConstructorDescription
ImportHostInfo(String)The configuration an import host belongs to; a package declares the one it targets.

Kandra.DataImport.ImportItem​

One object of a step: its $id (becomes ImportStamp.Key) and the item JSON as written (including $id).

Constructors​

ConstructorDescription
ImportItem(String, JsonObject, String)One object of a step: its $id (becomes ImportStamp.Key) and the item JSON as written (including $id).

Kandra.DataImport.ImportItemResult​

What happened to one package object. EntityId is null for a data processor or a failure before an id was known.

Constructors​

ConstructorDescription
ImportItemResult(Int32, String, String, Nullable<Guid>, ImportItemOutcome, String)What happened to one package object. EntityId is null for a data processor or a failure before an id was known.

Kandra.DataImport.ImportOptions​

Constructors​

ConstructorDescription
ImportOptions(Boolean, Boolean, Nullable<Guid>)undocumented

Properties​

PropertyDescription
ContinueOnErrorWhen false the run stops at the first failed item; re-running continues where it stopped.
DryRunParse, validate, resolve, look up and plan outcomes - including the licence pre-check - but write nothing.
RunIdPre-allocated run id (a background runner hands it to its caller before the run starts); generated when null.

Kandra.DataImport.ImportPackageInfo​

Header of an embedded package: what the admin page and GET Import/packages list.

Constructors​

ConstructorDescription
ImportPackageInfo(String, Int32, ImportOrigin, String, String)Header of an embedded package: what the admin page and GET Import/packages list.

Kandra.DataImport.ImportPackageReader​

Parses a kandra-import/1 package into the ImportPackage model (header + steps, items kept as JsonNode) and reports structural problems as ImportDiagnostics. Knows nothing about the configuration entities - see ImportPackageValidator for that.

Methods​

MethodDescription
PackageIdRegexundocumented

Kandra.DataImport.ImportPackageServiceCollectionExtensions​

Methods​

MethodDescription
AddImportPackages(IServiceCollection, Assembly)Registers the packages embedded in assembly (resources under an ImportPackages folder). Call once per assembly that ships packages; typically typeof(SomeTypeInYourApplicationProject).Assembly.

Kandra.DataImport.ImportPackageState​

The applied version of a package (null = never applied) and its most recent runs.

Constructors​

ConstructorDescription
ImportPackageState(String, Nullable<Int32>, IReadOnlyList<ImportRunSummary>)The applied version of a package (null = never applied) and its most recent runs.

Kandra.DataImport.ImportPackageValidator​

Checks a parsed package against this configuration: entity/constant/processor names, item properties (against the field metadata of the Dto, i.e. the real wire shape), required fields, $id uniqueness, $ref (must point at an earlier object) / $code (field must reference an entity), date tokens and match properties. Findings come back as ImportDiagnostics; nothing is thrown or written.

Constructors​

ConstructorDescription
ImportPackageValidator(IEntityCatalog, EntityFieldMetadataBuilder, ImportHostInfo)Checks a parsed package against this configuration: entity/constant/processor names, item properties (against the field metadata of the Dto, i.e. the real wire shape), required fields, $id uniqueness, $ref (must point at an earlier object) / $code (field must reference an entity), date tokens and match properties. Findings come back as ImportDiagnostics; nothing is thrown or written.

Methods​

MethodDescription
FieldsFor(EntityCatalogEntry)The properties an item of this entity may carry. A hierarchical dictionary's catalog Dto is the abstract root, so folder and leaf properties are unioned; the polymorphic discriminator (isFolder) is added explicitly.
RequiredFieldsFor(EntityCatalogEntry, JsonObject, IReadOnlyList<EntityFieldInfo>)undocumented

Kandra.DataImport.ImportRowInfo​

What the importer needs to know about an existing row to decide an outcome. Soft-deleted rows are included.

Constructors​

ConstructorDescription
ImportRowInfo(Guid, Boolean, DateTime, Nullable<DateTime>, String, Nullable<DateTime>)What the importer needs to know about an existing row to decide an outcome. Soft-deleted rows are included.

Properties​

PropertyDescription
ModifiedAfterImportA user (or anything else) changed the row after the import wrote it.

Kandra.DataImport.ImportRunInfo​

One run as seen by GetRunAsync: live status plus, once finished, the report.

Constructors​

ConstructorDescription
ImportRunInfo(Guid, String, ImportRunStatus, Boolean, DateTime, Nullable<DateTime>, String, ImportReport, String)One run as seen by GetRunAsync: live status plus, once finished, the report.

Kandra.DataImport.ImportRunSummary​

A line of the run history. HasReport is true when the full report can still be fetched.

Constructors​

ConstructorDescription
ImportRunSummary(Guid, String, DateTime, String, Boolean, IReadOnlyDictionary<String, Int32>, ImportRunStatus, Boolean)A line of the run history. HasReport is true when the full report can still be fetched.

Kandra.DataImport.ImportRunTracker​

In-memory view of runs started by this process. Singleton.

Kandra.DataImport.ImportSchemaProvider​

Source generators can only emit C#, so the schema is built at runtime from the entity catalog and field metadata (the same sources the validator uses). The result is deterministic: entries are ordered by kind then name.

Constructors​

ConstructorDescription
ImportSchemaProvider(IEntityCatalog, ImportPackageValidator, ImportHostInfo)Source generators can only emit C#, so the schema is built at runtime from the entity catalog and field metadata (the same sources the validator uses). The result is deterministic: entries are ordered by kind then name.

Kandra.DataImport.ImportStep​

One step of a package. Which members are meaningful depends on Kind: Dictionary/Document use Items; Constant uses Id + Value; CreateFrom uses Id + Source + Set; DataProcessor uses Id + Input. EntityName is the catalog name (dictionary/document/constant/processor name, or the createFrom target).

Properties​

PropertyDescription
RawThe step's own JSON as written - hashed for Constant/CreateFrom/DataProcessor steps, which have no items.

Kandra.DataImport.ImportTokens​

Date tokens usable as string values in a package: $now, $today, $today-23d, $today+14d.

Methods​

MethodDescription
TokenRegexundocumented
TryParse(String, Boolean, Int32)Parses a token. $now takes no offset; days is the signed day offset of $today.

Kandra.DataImport.OnChangePolicy​

What to do when the package item changed since the last apply.

Kandra.DataImport.OnDeletedPolicy​

What to do when a user soft-deleted the imported row.

Kandra.DataImport.OnUserModifiedPolicy​

What to do when a user modified the row after it was imported.

System.Text.RegularExpressions.Generated.PackageIdRegex_0​

Custom Regex-derived type for the PackageIdRegex method.

Constructors​

ConstructorDescription
PackageIdRegex_0Initializes the instance.

Fields​

FieldDescription
InstanceCached, thread-safe singleton instance.

System.Text.RegularExpressions.Generated.PackageIdRegex_0.RunnerFactory​

Provides a factory for creating RegexRunner instances to be used by methods on Regex.

Methods​

MethodDescription
CreateInstanceCreates an instance of a RegexRunner used by methods on Regex.

System.Text.RegularExpressions.Generated.PackageIdRegex_0.RunnerFactory.Runner​

Provides the runner that contains the custom logic implementing the specified regular expression.

Methods​

MethodDescription
Scan(ReadOnlySpan<Char>)Scan the inputSpan starting from base.runtextstart for the next match.
TryFindNextPossibleStartingPosition(ReadOnlySpan<Char>)Search inputSpan starting from base.runtextpos for the next location a match could possibly start. Returns: true if a possible match was found; false if no more matches are possible.
TryMatchAtCurrentPosition(ReadOnlySpan<Char>)Determine whether inputSpan at base.runtextpos is a match for the regular expression. Returns: true if the regular expression matches at the current position; otherwise, false.

System.Text.RegularExpressions.Generated.TokenRegex_1​

Custom Regex-derived type for the TokenRegex method.

Constructors​

ConstructorDescription
TokenRegex_1Initializes the instance.

Fields​

FieldDescription
InstanceCached, thread-safe singleton instance.

System.Text.RegularExpressions.Generated.TokenRegex_1.RunnerFactory​

Provides a factory for creating RegexRunner instances to be used by methods on Regex.

Methods​

MethodDescription
CreateInstanceCreates an instance of a RegexRunner used by methods on Regex.

System.Text.RegularExpressions.Generated.TokenRegex_1.RunnerFactory.Runner​

Provides the runner that contains the custom logic implementing the specified regular expression.

Methods​

MethodDescription
Scan(ReadOnlySpan<Char>)Scan the inputSpan starting from base.runtextstart for the next match.
TryFindNextPossibleStartingPosition(ReadOnlySpan<Char>)Search inputSpan starting from base.runtextpos for the next location a match could possibly start. Returns: true if a possible match was found; false if no more matches are possible.
TryMatchAtCurrentPosition(ReadOnlySpan<Char>)Determine whether inputSpan at base.runtextpos is a match for the regular expression. Returns: true if the regular expression matches at the current position; otherwise, false.

System.Text.RegularExpressions.Generated.Utilities​

Helper methods used by generated Regex-derived implementations.

Methods​

MethodDescription
StackPush(Int32[], Int32, Int32, Int32)Pushes 2 values onto the backtracking stack.

Fields​

FieldDescription
s_defaultTimeoutDefault timeout value set in AppContext, or InfiniteMatchTimeout if none was set.
s_hasTimeoutWhether s_defaultTimeout is non-infinite.