Import System Overview
Phase 2 of InstallHub delivers the import pipeline — installing a package into a tenant safely, with integrity verification, security scanning, ID remapping, conflict resolution, and atomic rollback.
What the Import System Does
The import system takes an InstallHub package ZIP and installs its artifacts into a target tenant. It handles every complexity automatically: verifying the bundle was not tampered with, scanning for security threats, translating artifact IDs to avoid collisions, resolving conflicts with existing artifacts, and committing everything in a single database transaction.
Import Pipeline
Upload
The caller POSTs the ZIP file to /api/installhub/packages/import. The engine reads the ZIP into memory and extracts the manifest.
Manifest Validation
Schema validation of manifest.json: required fields, SemVer format, artifact file presence, package dependency declarations.
Checksum Verification
Recompute SHA-256 over artifact files in install order. Compare to manifest checksum. Reject on mismatch.
Security Scan
Expression injection detection, SQL injection patterns, content policy check. FAIL result blocks import immediately. WARN allows import with administrator acknowledgment.
Package Dependency Check
Verify all packageDependencies are satisfied: correct packages are installed in the target tenant at compatible versions.
ID Remapping
Map every artifact ID from the source tenant to a new ID in the target tenant. Update all cross-references in artifact definitions to use new IDs.
Conflict Detection
Identify artifacts where the package contains an artifact with the same name and type as an existing artifact in the target tenant.
Conflict Resolution
Apply the configured strategy (Replace, Merge, or Skip) to each conflict. See Guide 5.
Transactional Install
Create or update artifacts in the target tenant in install order, within a database transaction. All artifacts are installed or none.
Post-Install Verification
Query each installed artifact to confirm it is accessible and functional. If verification fails, the transaction is rolled back.
ImportOptions
public class ImportOptions
{
public string TargetTenantId { get; init; }
public ConflictResolutionStrategy DefaultConflictStrategy { get; init; }
// Replace | Merge | Skip — applied to all conflicts
public bool DryRun { get; init; }
// true = run full pipeline but do not commit — returns preview
public bool AllowMajorVersionUpgrade { get; init; }
// true = allow import when package major version > installed major version
public bool AllowSecurityWarnings { get; init; }
// true = proceed with import even if security scan returns WARN
public string ImportedBy { get; init; }
// User identity for audit log
}
Service Contract
public interface IImportService
{
/// <summary>
/// Imports a package bundle into the specified tenant.
/// All stages run in sequence. On failure at any stage, all changes are rolled back.
/// </summary>
Task<ImportResult> ImportAsync(
byte[] zipBytes,
ImportOptions options,
CancellationToken ct = default);
/// <summary>
/// Runs the full import pipeline but does not commit changes.
/// Returns a preview of what would be installed and any conflicts or issues.
/// </summary>
Task<DryRunResult> DryRunAsync(
byte[] zipBytes,
ImportOptions options,
CancellationToken ct = default);
/// <summary>
/// Returns the import history for a tenant, newest first.
/// </summary>
Task<IReadOnlyList<ImportHistoryRecord>> GetHistoryAsync(
string tenantId,
int pageSize = 50,
CancellationToken ct = default);
}
Dry Run Mode
The dry-run mode is invaluable before committing to an import. It runs the full pipeline — validation, security scan, ID remapping, conflict detection — but does not write any data to the database. The response tells you exactly what would be installed and what conflicts exist:
POST /api/installhub/packages/import?dryRun=true
// or in ImportOptions: "dryRun": true
// Response:
{
"isDryRun": true,
"wouldInstall": ["EmployeeOnboarding", "EmployeeForm", "ApprovalRules", "EmployeeSchema"],
"conflictsFound": [
{ "artifactName": "EmployeeForm", "type": "AtlasForm", "resolution": "Replace" }
],
"securityScanResult": "PASS",
"estimatedInstallOrder": ["ent-44", "rule-305", "form-2005", "proc-1001"],
"warnings": []
}