Skip to content
Reference

Installation content

The tenant installation lifecycle, its initialization states, and the three content sources that create tenant rows.

Installation content

App authors provide migrations and public SDK contributions in their own App. When a tenant installation administrator installs from the catalog, the platform prepares required data and exposes the App only after success. App authors do not run Core or manually execute another App's seeders.

Data purpose and execution

SourceTriggerCreatesOptional
App migrationInstallation/updateApp-owned schema and required data transitionsNo
App initializerInstallation/update with a new initialization versionMinimum operational rowsImplement only when needed; runs automatically when declared
Copyable templateUser applicationEditable tenant-owned copiesYes
Development fixturenexia db seed requestDisposable test dataYes

Descriptors and catalogs provide definitions; declaring them does not create business rows. The host materializes platform definitions such as permissions and baseline roles.

Installation and failures

The platform checks prerequisites and publication/installation eligibility, then applies migrations, required initialization and activation in dependency order. Each App's initialization data and completed version share a transaction. Failed Apps and dependents that are not ready remain inactive. Do not assume work already committed by another App belongs to the same transaction.

Initialization stateMeaning
pendingWaiting or running
initializedRequired initialization completed
failedResolve the cause before retrying

An App is exposed only when its installation, prerequisites and initialization are ready. Installation does not grant user permissions; tenant administrators assign roles. Retry through the platform installation flow rather than editing installation records or database rows manually.

Never edit or delete an applied migration; add a new migration for the transition. Uninstalling/disabling an App or disconnecting the CLI does not remove migration history, tables or data. Preserve user-edited defaults during updates.

App initializer

New Apps implement VersionedTenantAppSeederContribution::appKey() and versions(): array to register ordinary Laravel seeders by version. Development uses nexia db seed; installation/production updates execute pending versions during preparation. Each version commits its writes and completion record together. Fix and retry failed versions; completed-source changes warn in development and fail publication checks.

See Required installation content for registration, recovery and update examples. Models generate IDs automatically. The two legacy initializer contracts retain their existing behavior and cannot be combined with the new contract.

Copyable templates

CopyableTemplateContributionRegistry discovers code-defined sources — it is not a database catalog. CopyableTemplateFacade combines them with the current ApprovalFormPresetCatalog adapter.

Applying one records provenance in the tenant-local template_applications ledger:

Ledger fieldContent
App keyOwning App
Template key and versionThe immutable source identity
Scopetenant or legal_entity
Legal EntityNullable
ActorWho applied it
Result statusSuccess or failure
Failure reasonOn failure
Created resource referencesWhat the copy produced

The ledger is provenance only. It never becomes the template source catalog, and it does not track later edits to the copies.

Two current constraints worth knowing before you plan around them:

  • Approval form presets are tenant-scoped, so passing --legal-entity to nexia-apps:apply-template fails for them.
  • Process templates do not go through this path at all. Selecting one changes the unsaved BPMN editor document; normal definition save and publish owns persistence and paired-decision deployment.

Apps publish templates through Nexia\Templates\Contracts\CopyableTemplateContribution. Its templates() method declares the sources and apply() receives a TemplateApplicationContext carrying the actor and optional Legal Entity. The host owns discovery, execution, and the provenance ledger.

Demo data

Development data runs through the keys exposed by an App's Nexia\Fixture\Contracts\FixtureContribution. Keep it separate from required installation data. App authors write their own records and make repeatable fixtures avoid duplicates and preserve user edits. Do not provide another App's source or an arbitrary seeder class.

Run from the selected App. The CLI requests an App database operation. The Console development-data history below belongs to the separate installed-App fixture workflow; do not mix their operation IDs or status routes. Use Console for fixtures of other installed Apps.

Code example
Shell
nexia db seed <fixture-key>
nexia db status

The project console’s Development data page lists available fixtures and the latest 20 operations. History remains visible after sandbox expiry. A Result needs review state requires checking actual data before further action. Opening or refreshing this page does not seed data.

Only operational Apps installed in the connected project's active sandbox are available. queued means accepted, not completed. Connection authorization and sandbox expiry are rechecked before execution and before committing data. Fixture jobs do not install or activate Apps.

If a response is lost, reuse the request ID printed by the CLI with --request-id <request-id>. A running or completed request does not seed again. needs_review means the commit outcome needs inspection. Ask the platform administrator before creating a new request; do not recover by resetting data.

FixtureContext carries host-restored actor identity and scalar identifiers. Use public Resource References for cross-App integration data. This command executes a declared installed-App fixture, not an arbitrary class, path or SQL. If a feature only works after demo data is seeded, move those required rows into the installation initializer.

Errors

SymptomCauseResolution
app.installed:{key} refuses a requestInstallation is pending or failed, or a prerequisite is not operationalInspect the installation failure and retry through the platform
Installation stops before writing rowsMissing prerequisite, duplicate key, or a cycleFix the prerequisite graph and install required Apps
Activation fails on database connectionManifest sync is strictAsk the platform operator to inspect the sandbox connection
App installed but invisible to usersNo Role carries its permissionsAn administrator creates and assigns an App Role
A template rejects a Legal Entity targetThe template is tenant-scopedUse its tenant-wide application flow
Feature broken on a fresh tenant, fine on a demo tenantRequired rows live in demo dataMove them into installation

Real usage

For optional content, read an App-owned CopyableTemplateContribution: its declaration lists available templates and apply() creates the editable tenant copy in the supplied context.

See the public CLI documentation for command and option details.

Development fixtures and production initializers can inject SDK ResourceReferences to read active providers with the requester's actual permissions. Installation management permission does not grant business-data access. Production seeders can inject SDK Actor to identify the requester. Prepared but inactive Apps in the same installation plan are not readable.

Fixtures and production installation requests have at most one hour from execution start; the whole production plan shares that deadline. Individual read, SQL lock and online statement limits remain unchanged. Authority is checked on reads and before commit. Failure rolls back the current fixture or initialization version, preserving earlier completed versions. Database rollback cannot undo external side effects.

Matching Core, Manager, runtime images and callback routing must be installed together. Separate development DB commands, including arbitrary Seeder classes and migrate --seed, do not receive fixture grants.

Source of truth: docs/developers/content/en/app-sdk/installation-content.md