@sparkerp/plugin-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/bundle/blocks.json +12229 -0
  4. package/bundle/catalog.json +32475 -0
  5. package/bundle/docs/applications/hcm/employee-profile.md +144 -0
  6. package/bundle/docs/concepts/artifact-types.md +80 -0
  7. package/bundle/docs/concepts/glossary.md +124 -0
  8. package/bundle/docs/concepts/overview.md +88 -0
  9. package/bundle/docs/concepts/page-data-flow.md +84 -0
  10. package/bundle/docs/concepts/plugin-lifecycle.md +81 -0
  11. package/bundle/docs/concepts/sdk-modes.md +71 -0
  12. package/bundle/docs/docs.json +109 -0
  13. package/bundle/docs/guides/add-a-cadence-job.md +134 -0
  14. package/bundle/docs/guides/add-a-compliance-job.md +139 -0
  15. package/bundle/docs/guides/add-a-create-edit-form.md +167 -0
  16. package/bundle/docs/guides/add-a-custom-block.md +225 -0
  17. package/bundle/docs/guides/add-a-data-provider.md +216 -0
  18. package/bundle/docs/guides/add-a-kpi.md +154 -0
  19. package/bundle/docs/guides/add-a-reminder-job.md +181 -0
  20. package/bundle/docs/guides/add-an-aggregation-job.md +153 -0
  21. package/bundle/docs/guides/add-an-approval-workflow.md +222 -0
  22. package/bundle/docs/guides/add-an-entity.md +170 -0
  23. package/bundle/docs/guides/add-business-rules.md +147 -0
  24. package/bundle/docs/guides/add-i18n.md +121 -0
  25. package/bundle/docs/guides/add-menus.md +149 -0
  26. package/bundle/docs/guides/build-a-code-plugin.md +141 -0
  27. package/bundle/docs/guides/build-a-page.md +213 -0
  28. package/bundle/docs/guides/build-a-polyglot-service-plugin.md +201 -0
  29. package/bundle/docs/guides/build-a-tenant-extension-service.md +149 -0
  30. package/bundle/docs/guides/create-a-plugin.md +172 -0
  31. package/bundle/docs/guides/expose-a-plugin-operation-as-an-ai-tool.md +114 -0
  32. package/bundle/docs/guides/index.md +53 -0
  33. package/bundle/docs/guides/publish-and-upgrade.md +152 -0
  34. package/bundle/docs/guides/responsive-plugin.md +117 -0
  35. package/bundle/docs/guides/seed-data-on-install.md +127 -0
  36. package/bundle/docs/guides/set-up-the-sdk.md +120 -0
  37. package/bundle/docs/guides/use-the-mcp-server.md +104 -0
  38. package/bundle/docs/guides/validate-and-test.md +119 -0
  39. package/bundle/docs/guides/wire-a-pages-data.md +153 -0
  40. package/bundle/docs/quickstart/index.md +118 -0
  41. package/bundle/docs/recipes/condition-based-compliance-flag.md +70 -0
  42. package/bundle/docs/recipes/cross-plugin-offboarding-fanout.md +68 -0
  43. package/bundle/docs/recipes/cross-row-aggregation.md +67 -0
  44. package/bundle/docs/recipes/entity-with-approval-workflow.md +72 -0
  45. package/bundle/docs/recipes/index.md +40 -0
  46. package/bundle/docs/recipes/install-lifecycle-data-seeding.md +76 -0
  47. package/bundle/docs/recipes/kpi-dashboard-page.md +92 -0
  48. package/bundle/docs/recipes/master-detail-page.md +84 -0
  49. package/bundle/docs/recipes/n-days-before-reminder.md +72 -0
  50. package/bundle/docs/recipes/per-row-document-generator.md +65 -0
  51. package/bundle/docs/recipes/related-record-lookup-field.md +74 -0
  52. package/bundle/docs/recipes/resolved-reference-grid-column.md +63 -0
  53. package/bundle/docs/recipes/scheduled-record-generation.md +68 -0
  54. package/bundle/docs/reference/action.md +18 -0
  55. package/bundle/docs/reference/block-definition.md +35 -0
  56. package/bundle/docs/reference/block-instance.md +33 -0
  57. package/bundle/docs/reference/composite-pack-manifest.md +33 -0
  58. package/bundle/docs/reference/connector-definition.md +36 -0
  59. package/bundle/docs/reference/data-service-definition.md +22 -0
  60. package/bundle/docs/reference/data-view-definition.md +26 -0
  61. package/bundle/docs/reference/entity-aggregation-config.md +38 -0
  62. package/bundle/docs/reference/entity-cadence-config.md +33 -0
  63. package/bundle/docs/reference/entity-compliance-config.md +37 -0
  64. package/bundle/docs/reference/entity-cross-plugin-action-config.md +37 -0
  65. package/bundle/docs/reference/entity-definition.md +18 -0
  66. package/bundle/docs/reference/entity-document-generator-config.md +35 -0
  67. package/bundle/docs/reference/entity-rule-definition.md +29 -0
  68. package/bundle/docs/reference/entity-status-date-sweep-config.md +27 -0
  69. package/bundle/docs/reference/form.md +35 -0
  70. package/bundle/docs/reference/index.md +37 -0
  71. package/bundle/docs/reference/menu.md +26 -0
  72. package/bundle/docs/reference/mobile-nav.md +22 -0
  73. package/bundle/docs/reference/page-template.md +29 -0
  74. package/bundle/docs/reference/page.md +44 -0
  75. package/bundle/docs/reference/plugin-manifest.md +54 -0
  76. package/bundle/docs/reference/plugin-seed-data.md +21 -0
  77. package/bundle/docs/reference/print-template-definition.md +22 -0
  78. package/bundle/docs/reference/provider-definition.md +22 -0
  79. package/bundle/docs/reference/report-definition.md +22 -0
  80. package/bundle/docs/reference/rule.md +30 -0
  81. package/bundle/docs/reference/workflow-definition.md +28 -0
  82. package/bundle/docs/troubleshooting/grid-shows-zero-rows.md +82 -0
  83. package/bundle/docs/troubleshooting/job-never-runs.md +89 -0
  84. package/bundle/docs/troubleshooting/known-gotchas.md +193 -0
  85. package/bundle/docs/troubleshooting/publishing-errors.md +119 -0
  86. package/bundle/docs/tutorial/01-create-the-plugin.md +157 -0
  87. package/bundle/docs/tutorial/02-category-entity-and-seed.md +94 -0
  88. package/bundle/docs/tutorial/03-equipment-entity.md +121 -0
  89. package/bundle/docs/tutorial/04-equipment-register-page.md +153 -0
  90. package/bundle/docs/tutorial/05-checkout-entity-and-page.md +116 -0
  91. package/bundle/docs/tutorial/06-checkout-approval-workflow.md +139 -0
  92. package/bundle/docs/tutorial/07-return-due-reminder-job.md +129 -0
  93. package/bundle/docs/tutorial/08-menus-i18n-publish.md +123 -0
  94. package/bundle/docs/tutorial/index.md +72 -0
  95. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-aggregation-configs.json +18 -0
  96. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-cadence-configs.json +9 -0
  97. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-compliance-configs.json +74 -0
  98. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-cross-plugin-configs.json +9 -0
  99. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-document-configs.json +9 -0
  100. package/bundle/examples/backend/modules/hcm-assets/spk-assembly/metadata/seed-data/hcm-assets-sweep-configs.json +260 -0
  101. package/bundle/examples/backend/modules/hcm-compensation/spk-assembly/metadata/entities/hcm_salary_planning_entry.json +41 -0
  102. package/bundle/examples/backend/modules/hcm-compensation/spk-assembly/metadata/page/salary-planning.json +1 -0
  103. package/bundle/examples/backend/modules/hcm-employee/spk-assembly/metadata/page/promotions.json +10944 -0
  104. package/bundle/examples/backend/modules/hcm-employee/spk-assembly/metadata/workflow/employee.movement.json +44 -0
  105. package/bundle/examples/backend/modules/hcm-employee/spk-assembly/metadata/workflow/employee.promotion-acknowledge.json +19 -0
  106. package/bundle/examples/backend/modules/hcm-employee/spk-assembly/metadata/workflow/employee.resignation.json +29 -0
  107. package/bundle/examples/example-patterns.mjs +94 -0
  108. package/bundle/manifest.json +14 -0
  109. package/bundle/schemas/action.schema.json +102 -0
  110. package/bundle/schemas/block-definition.schema.json +222 -0
  111. package/bundle/schemas/block-instance.schema.json +139 -0
  112. package/bundle/schemas/composite-pack-manifest.schema.json +160 -0
  113. package/bundle/schemas/connector-definition.schema.json +29 -0
  114. package/bundle/schemas/data-service-definition.schema.json +64 -0
  115. package/bundle/schemas/data-view-definition.schema.json +148 -0
  116. package/bundle/schemas/entity-aggregation-config.schema.json +32 -0
  117. package/bundle/schemas/entity-cadence-config.schema.json +27 -0
  118. package/bundle/schemas/entity-compliance-config.schema.json +31 -0
  119. package/bundle/schemas/entity-cross-plugin-action-config.schema.json +31 -0
  120. package/bundle/schemas/entity-definition.schema.json +126 -0
  121. package/bundle/schemas/entity-document-generator-config.schema.json +29 -0
  122. package/bundle/schemas/entity-rule-definition.schema.json +75 -0
  123. package/bundle/schemas/entity-status-date-sweep-config.schema.json +21 -0
  124. package/bundle/schemas/form.schema.json +281 -0
  125. package/bundle/schemas/menu.schema.json +106 -0
  126. package/bundle/schemas/mobile-nav.schema.json +53 -0
  127. package/bundle/schemas/page-template.schema.json +46 -0
  128. package/bundle/schemas/page.schema.json +292 -0
  129. package/bundle/schemas/plugin-manifest.schema.json +139 -0
  130. package/bundle/schemas/plugin-seed-data.schema.json +24 -0
  131. package/bundle/schemas/print-template-definition.schema.json +90 -0
  132. package/bundle/schemas/provider-definition.schema.json +27 -0
  133. package/bundle/schemas/report-definition.schema.json +96 -0
  134. package/bundle/schemas/rule.schema.json +82 -0
  135. package/bundle/schemas/workflow-definition.schema.json +42 -0
  136. package/bundle/validators/block-engine.mjs +23222 -0
  137. package/bundle/validators/page-engine.mjs +21645 -0
  138. package/erp-cli/authoring-root.mjs +344 -0
  139. package/erp-cli/erp.mjs +4065 -0
  140. package/erp-cli/example-patterns.mjs +94 -0
  141. package/erp-mcp-server/index.mjs +818 -0
  142. package/package.json +27 -0
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: connector-definition schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `connector-definition` schema
8
+
9
+ Generic External Provider Connector Engine's content model (engine-provider-connector) — domain/providerKey/connectorKind(DIRECT|HTTP)/baseUrl/auth/request-template/response-mapping.
10
+
11
+ Pull the full JSON Schema: `erp schema pull connector-definition`  ·  MCP: `erp_get_schema {"name":"connector-definition"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `domain` | string | yes | Consumer namespace, e.g. "hcm-employee-documents.signature" — any plugin/feature can register its own domain. |
18
+ | `providerKey` | string | yes | Unique per (tenant, domain) — what the consuming entity's provider_name/provider_key column resolves against. |
19
+ | `name` | string | yes | |
20
+ | `connectorKind` | string | yes | one of: `DIRECT`, `HTTP` |
21
+ | `active` | boolean | | |
22
+ | `isDefault` | boolean | | |
23
+ | `baseUrl` | string | | |
24
+ | `authType` | string | | one of: `NONE`, `API_KEY_HEADER`, `BEARER_TOKEN`, `BASIC` |
25
+ | `authConfig` | object | | e.g. {headerName, secretRef} — secretRef of shape "env:VAR_NAME" resolved from environment at call time, never a literal secret stored here. |
26
+ | `requestPath` | string | | |
27
+ | `httpMethod` | string | | one of: `POST`, `PUT` |
28
+ | `requestTemplate` | object | | JSON object whose string leaves may contain {{fieldName}} tokens substituted at call time. |
29
+ | `responseMapping` | object | | {providerReferencePath, statusPath, signingUrlPath} dot-paths into the vendor's JSON response. |
30
+ | `statusMapping` | object | | Vendor status string -> this domain's own internal status vocabulary. |
31
+ | `completionMode` | string | | one of: `MANUAL_CONFIRM`, `POLL`, `WEBHOOK` |
32
+ | `pollPathTemplate` | string | | |
33
+ | `webhookPath` | string | | |
34
+ | `notes` | string | | |
35
+ | `ownerPlugin` | string | | |
36
+
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: data-service-definition schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `data-service-definition` schema
8
+
9
+ Data Service layer's content model (engine-entity DataServiceSpec) — provider/entity/dataView source + filters/parameters/composite steps.
10
+
11
+ Pull the full JSON Schema: `erp schema pull data-service-definition`  ·  MCP: `erp_get_schema {"name":"data-service-definition"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `name` | string | yes | |
18
+ | `description` | string | | |
19
+ | `metadata` | object | | |
20
+ | `modules` | array | | |
21
+ | `definition` | object | yes | |
22
+
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: data-view-definition schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `data-view-definition` schema
8
+
9
+ Data View layer's content model (engine-entity DataViewSpec) — a real multi-table SQL join over plain physical tables.
10
+
11
+ Pull the full JSON Schema: `erp schema pull data-view-definition`  ·  MCP: `erp_get_schema {"name":"data-view-definition"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `name` | string | yes | |
18
+ | `description` | string | | |
19
+ | `metadata` | object | | |
20
+ | `modules` | array | | |
21
+ | `definition` | object | yes | |
22
+
23
+ ## Named sub-definitions
24
+
25
+ `calcExpr`
26
+
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: entity-aggregation-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-aggregation-config` schema
8
+
9
+ One config row for the generic engine-entity.aggregation-sweep job — fold count/sum/avg/min/max across a source entity and upsert the result into a target entity.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-aggregation-config`  ·  MCP: `erp_get_schema {"name":"entity-aggregation-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `sweep_code` | string | yes | Stable identifier / natural key for idempotent seeding. |
18
+ | `source_entity` | string | yes | |
19
+ | `filter_field` | string | | Optional single-column equality pre-filter. |
20
+ | `filter_value` | string | | |
21
+ | `when_status_in` | string | | Optional comma-separated status filter. |
22
+ | `status_field` | string | | |
23
+ | `date_field` | string | | Optional date pre-filter column. |
24
+ | `date_compare_op` | string | | one of: `lte`, `lt`, `gte`, `gt` |
25
+ | `day_offset` | integer | | |
26
+ | `aggregation` | string | yes | one of: `count`, `sum`, `avg`, `min`, `max` |
27
+ | `agg_field` | string | | Required for sum/avg/min/max; the numeric column to fold. |
28
+ | `group_by_field` | string | | Optional; one result bucket per distinct value. |
29
+ | `target_entity` | string | yes | |
30
+ | `target_key_field` | string | yes | Column on target_entity that holds the bucket key (a declared field). Special value "id": the bucket key IS a row's own primary key — the fold is written straight back onto target_entity row #<key> (never a create). Use with group_by_field yielding the parent id (e.g. maintenance_id), target_entity = that parent entity, and a blank target_key_prefix — this is the true 'roll child lines up onto the parent record' form (MaintenanceCostSyncJob). |
31
+ | `target_key_prefix` | string | | Prepended to the bucket key when writing (so multiple configs can share one summary entity without collisions). |
32
+ | `result_key` | string | | Used as the bucket key when group_by_field is blank; defaults to sweep_code. |
33
+ | `target_value_field` | string | yes | |
34
+ | `target_timestamp_field` | string | | Optional; now written here on each run. |
35
+ | `target_extra_json` | object | | Optional static fields set only when a target row is first created. |
36
+ | `seeded_by` | string | | |
37
+ | `active` | boolean | yes | |
38
+
@@ -0,0 +1,33 @@
1
+ ---
2
+ title: entity-cadence-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-cadence-config` schema
8
+
9
+ One config row for the generic engine-entity.cadence-generator job — create new target-entity rows on a cadence, source-driven or standalone, deduped.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-cadence-config` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-cadence-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `cadence_code` | string | yes | Stable identifier / natural key for idempotent seeding. |
18
+ | `target_entity` | string | yes | |
19
+ | `interval_days` | integer | yes | Minimum days between generations; the job stamps last_generated_at on its own config row after each run. |
20
+ | `last_generated_at` | string | | Managed by the job; leave unset in seed files. |
21
+ | `template_json` | object | | Static field values for each created row. String values may use ${date} ${ts} ${uuid} ${sourceId} placeholders. |
22
+ | `source_entity` | string | | Set for source-driven generation (one target row per due source row); leave blank for a standalone single-row generator. |
23
+ | `source_filter_field` | string | | |
24
+ | `source_filter_value` | string | | |
25
+ | `source_status_field` | string | | |
26
+ | `source_status_in` | string | | |
27
+ | `source_date_field` | string | | Only source rows whose date_field <= now + due_within_days are generated from. |
28
+ | `due_within_days` | integer | | |
29
+ | `field_map_json` | object | | { targetField: sourceField } - copies values from each source row. |
30
+ | `dedupe_target_field` | string | | Target column holding the source row id (source-driven) or the cadence marker (standalone) - the idempotency key. |
31
+ | `seeded_by` | string | | |
32
+ | `active` | boolean | yes | |
33
+
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: entity-compliance-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-compliance-config` schema
8
+
9
+ One config row for the generic engine-entity.compliance-sweep job — evaluate a rule-engine boolean expression against every row of an entity and flag/escalate offenders.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-compliance-config` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-compliance-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `compliance_code` | string | yes | Stable identifier / natural key for idempotent seeding. |
18
+ | `source_entity` | string | yes | Entity evaluated row-by-row. |
19
+ | `status_field` | string | | |
20
+ | `when_status_in` | string | | Optional comma-separated status pre-filter. |
21
+ | `filter_field` | string | | Optional single-column equality pre-filter. |
22
+ | `filter_value` | string | | |
23
+ | `related_count_entity` | string | | Optional: count child rows of this entity whose related_count_key_field equals the source row's id, and bind the result as `related_count` in the expression context. |
24
+ | `related_count_key_field` | string | | The FK column on related_count_entity that points back to the source row's id. |
25
+ | `related_count_status_field` | string | | |
26
+ | `related_count_status_in` | string | | Optional comma-separated status filter for the related count. |
27
+ | `condition_expr` | string | yes | MVEL boolean expression evaluated against each row's fields (+ `now`, + `related_count`). Whitelisted functions only (daysBetween, now, etc.). True => apply the outcome. |
28
+ | `set_field` | string | | Flag outcome: column on the source row to write when the condition is true (idempotent — skipped if already equal to set_value). |
29
+ | `set_value` | string | | Flag outcome: value written into set_field. |
30
+ | `escalation_entity` | string | | Escalation outcome: create one row in this separate entity per violating source row, deduped by escalation_dedupe_field = source id. |
31
+ | `escalation_dedupe_field` | string | | Column on escalation_entity that holds the source row id (used for dedupe). |
32
+ | `escalation_timestamp_field` | string | | Optional column on escalation_entity that receives `now` on create. |
33
+ | `field_map_json` | object | | Escalation outcome: {targetField: sourceField} — copies source row values into the new escalation row. |
34
+ | `escalation_template_json` | object | | Escalation outcome: static fields set on every created escalation row. |
35
+ | `seeded_by` | string | | |
36
+ | `active` | boolean | yes | |
37
+
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: entity-cross-plugin-action-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-cross-plugin-action-config` schema
8
+
9
+ One config row for the generic engine-entity.cross-plugin-action job — a trigger_entity row entering a triggering status fans out create/update onto every related_entity row keyed back to it (offboarding fan-out; trigger may be another plugin's entity).
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-cross-plugin-action-config` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-cross-plugin-action-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `action_code` | string | yes | Stable identifier / natural key for idempotent seeding. |
18
+ | `trigger_entity` | string | yes | Entity A - the record whose status change triggers the fan-out (often owned by another plugin, e.g. employee). |
19
+ | `trigger_status_field` | string | | |
20
+ | `trigger_status_in` | string | | Comma-separated statuses that make a trigger row eligible (e.g. TERMINATED,SEPARATED). Blank = every row. |
21
+ | `trigger_date_field` | string | | Optional date gate column on the trigger row (e.g. separation_date). |
22
+ | `trigger_date_compare_op` | string | | one of: `lte`, `lt`, `gte`, `gt` |
23
+ | `trigger_day_offset` | integer | | Compare trigger_date_field against now + this many days. |
24
+ | `trigger_key_field` | string | | Field on the trigger row whose value matches related rows (usually id -> employee id). |
25
+ | `related_entity` | string | yes | Entity B - the rows acted on. |
26
+ | `related_match_field` | string | yes | FK column on related_entity that equals the trigger row's key (e.g. employee_id). |
27
+ | `related_status_field` | string | | |
28
+ | `related_status_in` | string | | Comma-separated statuses a related row must be in to be acted on (e.g. ALLOCATED,ACKNOWLEDGED,IN_USE). |
29
+ | `create_entity` | string | | Create-outcome: entity a row is created in per matched related row (e.g. hcm_asset_return). Omit to only update the related row. |
30
+ | `create_dedupe_field` | string | | Numeric (long) column on create_entity holding the related row's id - dedupes re-runs. MUST be numeric, not text (EntityRecordService binds numeric-looking filter values as bigint). |
31
+ | `create_template_json` | object | | Static fields set on every created row. String values may contain ${date} ${ts} ${uuid} ${relatedId} ${triggerKey} - substituted per created row so a required-unique column (e.g. return_number) never collides. |
32
+ | `create_field_map_json` | object | | {targetField: relatedField} - copies related row values into the created row. |
33
+ | `related_set_field` | string | | Update-outcome: column on the related row to write (e.g. status). Idempotent - skipped when already equal to related_set_value. |
34
+ | `related_set_value` | string | | Value written into related_set_field (e.g. RETURN_PENDING). |
35
+ | `seeded_by` | string | | |
36
+ | `active` | boolean | yes | |
37
+
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: entity-definition schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-definition` schema
8
+
9
+ A real Entity Engine entity (engine-entity) — fields/relationships, produces real DDL, zero hand-written CRUD Java.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-definition` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-definition"}`
12
+
13
+ _This schema's root is not a plain object (see the full schema for its shape)._
14
+
15
+ ## Named sub-definitions
16
+
17
+ `entityProps`, `flatEntity`, `field`, `relationship`
18
+
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: entity-document-generator-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-document-generator-config` schema
8
+
9
+ One config row for the generic engine-entity.document-generator job — generate a structured-data artifact (json/csv) per eligible row via the FileService, store it in a DMS cabinet, and stamp the file id onto the row.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-document-generator-config` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-document-generator-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `document_code` | string | yes | Stable identifier / natural key for idempotent seeding. |
18
+ | `source_entity` | string | yes | Entity whose rows get a document. |
19
+ | `status_field` | string | | |
20
+ | `when_status_in` | string | | Comma-separated statuses a row must be in to be eligible (e.g. COMPLETED for an audit report). Blank = every row. |
21
+ | `filter_field` | string | | Optional single-column equality pre-filter. |
22
+ | `filter_value` | string | | |
23
+ | `target_file_field` | string | yes | Text column on the source row that receives the generated file id. Its non-blank state IS the dedupe marker. |
24
+ | `format` | string | | one of: `json`, `csv` |
25
+ | `cabinet_id` | integer | | DMS cabinet id (engine-file) the artifact is stored in. Give this OR cabinet_name. |
26
+ | `cabinet_name` | string | | Portable alternative to cabinet_id: the job resolves a cabinet by this name for the tenant, creating it if absent. Preferred for seed-data rows (no hardcoded id). |
27
+ | `file_name_template` | string | | Generated file name. Supports ${id} ${date} ${ts} ${uuid} and ${field:<name>}. Default: <document_code>-${id}-${date}.<ext>. |
28
+ | `include_fields` | string | | Comma-separated source fields to include in the artifact. Blank = all fields. |
29
+ | `child_entity` | string | | Optional child entity whose rows (matched by child_match_field == source id) are embedded (json) alongside the record. |
30
+ | `child_match_field` | string | | FK column on child_entity pointing at the source row's id. |
31
+ | `template_ref` | string | | Reserved: a print-template id, for the future render_mode:template branch. Not used today (see description). |
32
+ | `regenerate` | boolean | | When true, regenerate even if target_file_field is already populated. |
33
+ | `seeded_by` | string | | |
34
+ | `active` | boolean | yes | |
35
+
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: entity-rule-definition schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-rule-definition` schema
8
+
9
+ A declarative entity-lifecycle rule (engine-rule) — conditions/actions firing at BEFORE_CREATE/AFTER_UPDATE/etc.
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-rule-definition` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-rule-definition"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `entityType` | string | yes | The EntityDefinition.name this rule fires against. |
18
+ | `name` | string | yes | |
19
+ | `description` | string | | |
20
+ | `triggerEvent` | string | yes | one of: `BEFORE_CREATE`, `AFTER_CREATE`, `BEFORE_UPDATE`, `AFTER_UPDATE`, `BEFORE_DELETE`, `AFTER_DELETE` |
21
+ | `priority` | integer | | Lower runs first when multiple rules match the same trigger. |
22
+ | `active` | boolean | | |
23
+ | `conditions` | `#/definitions/condition` | yes | |
24
+ | `actions` | array | yes | |
25
+
26
+ ## Named sub-definitions
27
+
28
+ `condition`, `action`
29
+
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: entity-status-date-sweep-config schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `entity-status-date-sweep-config` schema
8
+
9
+ One config row for the generic engine-entity.status-date-sweep job — flip an entity's own status/flag field once its own date column crosses now (±day_offset days).
10
+
11
+ Pull the full JSON Schema: `erp schema pull entity-status-date-sweep-config` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"entity-status-date-sweep-config"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `entity_name` | string | yes | Entity Engine entity to sweep, e.g. hcm_asset. |
18
+ | `status_field` | string | | Column holding the gating status. |
19
+ | `when_status_in` | string | yes | Comma-separated statuses a row must currently be in to be eligible. |
20
+ | `date_field` | string | yes | Date/datetime column compared against now (+day_offset). |
21
+ | `compare_op` | string | | one of: `lte`, `lt`, `gte`, `gt` |
22
+ | `day_offset` | integer | | Compare date_field against now + day_offset days (negative shifts earlier). Enables N-days-before reminders. Added 2026-09. |
23
+ | `set_field` | string | | Field to WRITE when a row matches; defaults to status_field. Use a distinct flag field (e.g. warranty_alert_30d) so a reminder never corrupts the lifecycle enum. |
24
+ | `set_status_to` | string | yes | Value written into set_field on match (e.g. "true" for a boolean flag, or a new status enum value). |
25
+ | `seeded_by` | string | | Provenance stamp (the plugin id). Set automatically by PluginDataSeedInstaller from the seed file's "source". |
26
+ | `active` | boolean | yes | |
27
+
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: form schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `form` schema
8
+
9
+ A form's field/section/validation contract.
10
+
11
+ Pull the full JSON Schema: `erp schema pull form` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"form"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `contractVersion` | — | yes | |
18
+ | `id` | string | yes | Dot-namespaced form id, e.g. hr.employee-lookup. |
19
+ | `version` | string | yes | |
20
+ | `publisher` | string | yes | |
21
+ | `fields` | array | yes | |
22
+ | `sections` | array | yes | |
23
+ | `tabs` | array | yes | |
24
+ | `layout` | object | yes | |
25
+ | `canvas` | array | | |
26
+ | `validations` | array | yes | |
27
+ | `rules` | array | yes | |
28
+ | `events` | array | yes | |
29
+ | `permissions` | `#/$defs/permissionSurface` | yes | |
30
+ | `designer` | object | yes | |
31
+
32
+ ## Named sub-definitions
33
+
34
+ `identifier`, `i18nKey`, `permissionSurface`, `boundKey`, `fieldValue`, `selectOption`, `fieldConstraints`, `fieldDesigner`, `computedSpec`, `fetchFromBinding`, `rollupBinding`, `childTableSpec`, `fieldSpec`, `sectionSpec`, `tabSpec`, `actionDefinition`, `validationSpec`, `ruleBindingSpec`, `formEventBinding`, `canvasPosition`, `canvasPlacement`
35
+
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: Schema reference
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # Schema reference
8
+
9
+ One page per authoring artifact schema, generated by `erp docs gen-reference` from the SDK authoring bundle. Regenerate after `erp bundle build`.
10
+
11
+ - [`action`](./action.md)
12
+ - [`block-definition`](./block-definition.md)
13
+ - [`block-instance`](./block-instance.md)
14
+ - [`composite-pack-manifest`](./composite-pack-manifest.md)
15
+ - [`connector-definition`](./connector-definition.md)
16
+ - [`data-service-definition`](./data-service-definition.md)
17
+ - [`data-view-definition`](./data-view-definition.md)
18
+ - [`entity-aggregation-config`](./entity-aggregation-config.md)
19
+ - [`entity-cadence-config`](./entity-cadence-config.md)
20
+ - [`entity-compliance-config`](./entity-compliance-config.md)
21
+ - [`entity-cross-plugin-action-config`](./entity-cross-plugin-action-config.md)
22
+ - [`entity-definition`](./entity-definition.md)
23
+ - [`entity-document-generator-config`](./entity-document-generator-config.md)
24
+ - [`entity-rule-definition`](./entity-rule-definition.md)
25
+ - [`entity-status-date-sweep-config`](./entity-status-date-sweep-config.md)
26
+ - [`form`](./form.md)
27
+ - [`menu`](./menu.md)
28
+ - [`mobile-nav`](./mobile-nav.md)
29
+ - [`page-template`](./page-template.md)
30
+ - [`page`](./page.md)
31
+ - [`plugin-manifest`](./plugin-manifest.md)
32
+ - [`plugin-seed-data`](./plugin-seed-data.md)
33
+ - [`print-template-definition`](./print-template-definition.md)
34
+ - [`provider-definition`](./provider-definition.md)
35
+ - [`report-definition`](./report-definition.md)
36
+ - [`rule`](./rule.md)
37
+ - [`workflow-definition`](./workflow-definition.md)
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: menu schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `menu` schema
8
+
9
+ Menu Designer's content model (@erp/menu-engine) — hierarchical sidenav tree (nodes/navigation/visibility/security/badge/personalization/advanced).
10
+
11
+ Pull the full JSON Schema: `erp schema pull menu` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"menu"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `name` | string | yes | |
18
+ | `description` | string | | |
19
+ | `metadata` | object | | |
20
+ | `modules` | array | | |
21
+ | `definition` | object | yes | |
22
+
23
+ ## Named sub-definitions
24
+
25
+ `menuNode`
26
+
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: mobile-nav schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `mobile-nav` schema
8
+
9
+ Mobile Navigation Designer's content model (@erp/mobile-nav-engine) — a FLAT item list (bottom-tabs/drawer/hybrid), deliberately distinct from menu-definition.
10
+
11
+ Pull the full JSON Schema: `erp schema pull mobile-nav` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"mobile-nav"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `name` | string | yes | |
18
+ | `description` | string | | |
19
+ | `metadata` | object | | |
20
+ | `modules` | array | | |
21
+ | `definition` | object | yes | |
22
+
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: page-template schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `page-template` schema
8
+
9
+ A reusable page template (see the generic-capability generator pattern).
10
+
11
+ Pull the full JSON Schema: `erp schema pull page-template` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"page-template"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `contractVersion` | — | yes | |
18
+ | `id` | string | yes | |
19
+ | `version` | string | yes | |
20
+ | `publisher` | string | yes | |
21
+ | `extends` | string | | |
22
+ | `kind` | enum | | one of: `standard`, `wizard` |
23
+ | `steps` | array | | |
24
+ | `regions` | array | yes | |
25
+
26
+ ## Named sub-definitions
27
+
28
+ `identifier`, `i18nKey`, `row`
29
+
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: page schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `page` schema
8
+
9
+ A page's rows/overlays/variants/designer metadata — the top-level page.json contract.
10
+
11
+ Pull the full JSON Schema: `erp schema pull page` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"page"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `contractVersion` | — | yes | |
18
+ | `id` | string | yes | |
19
+ | `version` | string | yes | |
20
+ | `publisher` | string | yes | |
21
+ | `title` | `#/$defs/i18nKey` | yes | |
22
+ | `template` | string | | |
23
+ | `slotFills` | object | | |
24
+ | `rows` | array | yes | |
25
+ | `canvas` | array | | |
26
+ | `overlays` | array | | |
27
+ | `theme` | object | | |
28
+ | `route` | `#/$defs/route` | yes | |
29
+ | `menu` | `#/$defs/menuEntry` | | |
30
+ | `breadcrumb` | `#/$defs/breadcrumb` | | |
31
+ | `variants` | array | | |
32
+ | `designer` | `#/$defs/designer` | yes | |
33
+ | `access` | string | | one of: `public`, `authenticated` |
34
+ | `backgroundImageUrl` | string | | |
35
+ | `isLoginPage` | boolean | | |
36
+ | `isSessionExpiredPage` | boolean | | |
37
+ | `isAccessDeniedPage` | boolean | | |
38
+ | `devicePersistence` | array | | |
39
+ | `modules` | array | | App-module ids this page belongs to (e.g. "hcm-foundation-home") - TenantPageHost's per-module page listing only surfaces a page if it's present here. Load-bearing in practice for any page reached via the app sidenav/module shell, even on pages authored before this was documented. |
40
+
41
+ ## Named sub-definitions
42
+
43
+ `identifier`, `i18nKey`, `expression`, `breakpointOverride`, `breakpointOverrides`, `linkItem`, `item`, `column`, `row`, `routeParam`, `route`, `menuEntry`, `breadcrumb`, `overlay`, `variantRule`, `variant`, `canvasPosition`, `canvasItem`, `designer`, `devicePersistenceRule`
44
+
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: plugin-manifest schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `plugin-manifest` schema
8
+
9
+ A real .spk business-application plugin's own spk-assembly/plugin.json contract (id/version/permissions/roles/dependencies).
10
+
11
+ Pull the full JSON Schema: `erp schema pull plugin-manifest` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"plugin-manifest"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `id` | string | yes | |
18
+ | `name` | string | yes | |
19
+ | `version` | string | yes | |
20
+ | `type` | string | | |
21
+ | `vendor` | string | | |
22
+ | `license` | string | | |
23
+ | `licenseTier` | string | | |
24
+ | `category` | string | | |
25
+ | `erpVersion` | string | | |
26
+ | `minErpVersion` | string | | |
27
+ | `maxErpVersion` | string | | |
28
+ | `mainClass` | string \| null | | Fully-qualified PF4J plugin main class. Optional (null/absent) for a pure-JSON plugin that ships zero Java classes -- the platform loads it via the built-in JsonOnlyPlugin entry point. |
29
+ | `schemaName` | string | | App-owned Postgres schema this plugin's Entity-Engine tables route to — see feedback-entity-engine-tables-must-route-to-app-schema. |
30
+ | `scope` | string | | one of: `global`, `tenant` — Tenant-Safe Plugin & Extension Architecture spec §54. 'global' (default, every manifest that predates this field): a shared plugin installable by any tenant. 'tenant': a private single-tenant L5 extension — MUST also set tenantId, and if it carries Java code (mainClass, or type java-extension/code-plugin) it MUST declare runtimeModes: ['service'] — the shared runtime refuses to load it (ExtensionInstallValidator, spec §11/§28.10/§74). |
31
+ | `tenantId` | string | | Spec §54 — the owning tenant of a scope:'tenant' plugin. Required iff scope=='tenant'; must match the tenant the plugin is installed into. Absent for a global plugin. |
32
+ | `erpApiVersion` | string | | Spec §25 — the ERP extension-API contract version this plugin targets (e.g. '5.0'), distinct from erpVersion/minErpVersion (platform build versions). Optional; informational in E1. |
33
+ | `supportedApplications` | array | | Spec §25 — applications this extension supports, e.g. ['HCM']. Optional; empty/absent means unconstrained. |
34
+ | `dependencies` | array | | |
35
+ | `optionalDependencies` | array | | |
36
+ | `permissions` | array | | Legacy flat permission-key catalogue; real installs read roles[].permissionKeys instead (PluginRoleInstaller) — commonly left empty on modules whose roles[] is populated. |
37
+ | `owner` | string | | |
38
+ | `editable` | boolean | | |
39
+ | `extendable` | boolean | | |
40
+ | `capabilitiesProvided` | array | | |
41
+ | `capabilitiesRequired` | array | | |
42
+ | `featureFlags` | array | | |
43
+ | `configSchemaJson` | object \| string \| null | | |
44
+ | `frontendBundle` | object | | Optional — dynamic frontend-plugin-loading (ai/patterns/code-plugin-sdk.md). Absent on every plugin.json that predates it. |
45
+ | `roles` | array | | |
46
+ | `runtimeModes` | array | | Added 2026-09-03 (real gap — this field is genuinely load-bearing on every shipped plugin.json today, e.g. hcm-learning's own ["embedded"], but was entirely absent from this schema until now, so erp_get_schema/erp schema pull misrepresented the real manifest shape). Which Plugin Runtime modes this plugin can run under: 'embedded' (loaded in-process via PF4J, the only behavior every pre-existing manifest declares) and/or 'service' (its own standalone Spring Boot process, routed to over HTTP — see PluginManifest#runtimeModes' own Javadoc in engine-plugin-api). Defaults to ['embedded'] when absent. Declaring 'service' here does not itself switch anything — the actual mode is chosen per-plugin via Studio's Plugin Runtime toggle (erp_core.application.deployment_type). |
47
+ | `serviceRuntime` | string \| null | | one of: `java`, `python`, `nodejs`, `null` — Added 2026-09-14 (Polyglot Plugin Runtime initiative, PluginManifest#serviceRuntime's own Javadoc in engine-plugin-api). Which language a Service-mode plugin's own process is implemented in. Only meaningful when runtimeModes contains 'service' — an embedded-only plugin is always Java (nothing else can load into the JVM), and installing a manifest that sets this to 'python'/'nodejs' without declaring 'service' in runtimeModes fails install (PluginCodeLifecycle#validateServiceRuntime). null/absent defaults to 'java' — every manifest that predates this field keeps its exact current behavior. Real, proven implementations exist for all three values: hello-plugin-service (java), hello-plugin-service-python (python), hello-plugin-service-node (nodejs) — see 'Build a Service-mode plugin in Python or Node.js' for the SDK and full build/deploy path for each. |
48
+ | `serviceFramework` | string \| null | | one of: `spring-boot`, `fastapi`, `express`, `null` — Added 2026-09-14, same initiative as serviceRuntime — purely informational (shown as a read-only chip in Studio's Plugin Runtime panel; not validated against serviceRuntime today, so keep them consistent yourself: spring-boot pairs with java, fastapi with python, express with nodejs). null/absent defaults to 'spring-boot'. |
49
+ | `serviceDeployment` | object \| null | | Added 2026-09-03 (same real-gap fix as runtimeModes). Recommended deployment/runtime defaults for this plugin when run in 'service' mode (PluginManifest.PluginServiceDeploymentSpec in engine-plugin-api). null (the default for almost every manifest) means Studio seeds an empty config the admin fills in the first time they switch this plugin to Service mode. Only healthPath/timeoutMs/heartbeatIntervalSeconds actually drive runtime behavior today (health checks, proxy call timeout) — docker/kubernetes/cloud are real, persisted, Studio-editable data for a future Deployment Manager, not wired to any live provisioning API. |
50
+
51
+ ## Named sub-definitions
52
+
53
+ `resourceLimits`
54
+
@@ -0,0 +1,21 @@
1
+ ---
2
+ title: plugin-seed-data schema
3
+ audience: tenant
4
+ generated: true
5
+ ---
6
+
7
+ # `plugin-seed-data` schema
8
+
9
+ metadata/seed-data/*.json — Entity-Engine data rows a plugin seeds on install/upgrade, idempotently (upsert by keyFields). See ai/patterns/plugin-install-data-seeding.md.
10
+
11
+ Pull the full JSON Schema: `erp schema pull plugin-seed-data` &nbsp;·&nbsp; MCP: `erp_get_schema {"name":"plugin-seed-data"}`
12
+
13
+ ## Top-level properties
14
+
15
+ | Property | Type | Required | Notes |
16
+ | --- | --- | --- | --- |
17
+ | `entity` | string | yes | Entity Engine entity name the rows belong to. Must already exist (ship it in metadata/entities/ if the plugin owns it). |
18
+ | `keyFields` | array | yes | The natural-key fields that uniquely identify a row. On re-install, a row matching all keyFields is updated (only if a non-key value changed); otherwise inserted. Never produces duplicates. |
19
+ | `source` | string | | The plugin id. Stamped into a seeded_by field when the entity has one. |
20
+ | `rows` | array | yes | The rows to upsert. Each is a plain field map for the entity - no tenant id (the installer supplies it). |
21
+