Entity Master Lifecycle
Master-data changes are gated by a versioned workflow. CDX products should use the canonical ApprovalWorkflowHandlerFactory rather than a custom graph per entity type.
Entity States
enum EntityStatus {
draft,
pendingApproval,
approved,
effective,
superseded,
archived,
}The workflow does not own the entity row. Outcome operations apply the status change after a durable decision.
Registration
final registrationDefinition = Workflow<
EntityDraft,
ApprovalResult,
EntityApprovalFailure
>(
code: 'directory.entity_registration',
version: 1,
input: entityDraftSchema,
output: approvalResultSchema,
failure: entityApprovalFailureSchema,
);
final registrationHandler = registrationDefinition.implement(
fingerprint: 'directory.entity_registration:v1',
execute: (workflow, draft) async {
final valid = await workflow.perform(
validate,
draft,
id: 'validate',
);
if (!valid.ok) return ApprovalResult.rejected();
final decision = await workflow.request(
approveRegistration,
valid,
id: 'approve',
title: 'Approve registration',
audience: Audience(roleIds: ['entity_approver']),
);
if (!decision.approved) return ApprovalResult.rejected();
await workflow.perform(activate, valid, id: 'activate');
return ApprovalResult.approved();
},
);Modification
Create a draft version in an operation, collect assigned edits and approvals, then supersede the previous effective version in another operation. Each side effect uses context.idempotencyKey.
For product master-data, prefer the shared approval family:
ApprovalWorkflowHandlerFactory.standard(
code: 'directory.entity_master_approval',
version: 1,
digest: 'directory.entity_master_approval:v1',
).buildHandler();Blueprint stores the master-data policy. The workflow service executes the pinned version. See CDX Integration.
Audit
History records who started the run, who responded to each work item, and which operation attempt applied the effect. The inspector can replay that evidence without reading product tables.