Skip to content

Install-lifecycle data seeding

When you need this

Any time a data row must travel with the .spk instead of a manual per-tenant POST — reference data you own, default settings, and (the important case) rows in the shared platform config entities that make your scheduled jobs exist.

The file

metadata/seed-data/<name>.json:

json
{
  "entity": "oeq_category",
  "keyFields": ["category_code"],
  "source": "office-equipment",
  "rows": [
    { "category_code": "LAPTOP", "category_name": "Laptops", "status": "ACTIVE", "seeded_by": "office-equipment" }
  ]
}
  • entity — must already exist (ship it in metadata/entities/ if you own it).
  • keyFields — the natural key. On re-install a matching row is updated only if a non-key value changed, else inserted. Never duplicated.
  • source — your plugin id; stamped into a seeded_by field if present.
  • rows — plain field maps, no tenant id.

Verified idempotency

First install of the tutorial module:

PluginDataSeedInstaller: office-equipment-categories.json -> entity oeq_category (tenant 2): 4 created, 0 updated, 0 unchanged

Re-publish with one row added:

PluginDataSeedInstaller: office-equipment-categories.json -> entity oeq_category (tenant 2): 1 created, 0 updated, 4 unchanged

For scheduled-job config

When the target is a shared config entity (entity_status_date_sweep_config, entity_aggregation_config, entity_cadence_config, entity_compliance_config, entity_cross_plugin_action_config, entity_document_generator_config) also ship:

  1. the shared config entity file — with just the additive columns your rows need. PluginEntityInstaller is idempotent-additive: an existing table gains only the missing columns.
  2. an AFTER_CREATE register rule on that config entity calling ensure<Job>Registered, so the first seeded row auto-registers the job. (The status-date-sweep job's register rule ships with the platform; the other five you ship.)

The rules that bite

  • Non-unique keyFields → duplicates on re-install. Pick a real key.
  • A null in a key field in some rows → matches nothing / everything. Keep key fields populated in every row.
  • Seed targets an entity you forgot to ship → SEED-001 lint / install failure.