Skip to content

createPartitionedIdempotencyKeyFactory

createPartitionedIdempotencyKeyFactory(options): (context) => string

Defined in: packages/pipeline-idempotency/src/helpers/partitioned-key.ts:113

Creates an IdempotencyKeyFactory whose keys partition by tenant, principal and operation, and fail closed when any of them is missing.

Segments are escaped and joined with joinKeySegments from @cqrs-ddd/safe-stringify, so values containing the separator — email addresses, external subject claims, composite ids — cannot make two different operations collide on one key.

The key is an operation identity. Do not fold permissions into it: a key that changed with permissions would let the same side effect run again. Bind replay to the caller’s authorization with replayScopeFactory instead.

The produced key is [version:]<tenantId>:<principal…>:<action>:<operation>, with the tenant segment omitted when includeTenant is false.

PartitionedIdempotencyKeyOptions & object

(context) => string

When the tenant or principal is absent, or the operation is absent and onMissingOperation is 'throw'.

Per authenticated principal, deduplicated by a business identifier

const createOrderKey = createPartitionedIdempotencyKeyFactory({
version: 'v1',
action: 'order.create',
principal: (ctx) => ['user', ctx.items.get(CURRENT_USER_ID) as string],
operation: (ctx) => (ctx.request as CreateOrderCommand).externalRef,
});
class CreateOrderHandler {
@pipeline.wrap({ kind: 'command' }, [IdempotencyBehavior, { keyFactory: createOrderKey }])
async handle(command: CreateOrderCommand) {}
}

Optional client-supplied Idempotency-Key

createPartitionedIdempotencyKeyFactory({
principal: readUserId,
operation: (ctx) => (ctx.request as PayCommand).idempotencyKey,
onMissingOperation: 'skip',
});

createPartitionedIdempotencyKeyFactory(options): IdempotencyKeyFactory

Defined in: packages/pipeline-idempotency/src/helpers/partitioned-key.ts:116

Creates an IdempotencyKeyFactory whose keys partition by tenant, principal and operation, and fail closed when any of them is missing.

Segments are escaped and joined with joinKeySegments from @cqrs-ddd/safe-stringify, so values containing the separator — email addresses, external subject claims, composite ids — cannot make two different operations collide on one key.

The key is an operation identity. Do not fold permissions into it: a key that changed with permissions would let the same side effect run again. Bind replay to the caller’s authorization with replayScopeFactory instead.

The produced key is [version:]<tenantId>:<principal…>:<action>:<operation>, with the tenant segment omitted when includeTenant is false.

PartitionedIdempotencyKeyOptions

IdempotencyKeyFactory

When the tenant or principal is absent, or the operation is absent and onMissingOperation is 'throw'.

Per authenticated principal, deduplicated by a business identifier

const createOrderKey = createPartitionedIdempotencyKeyFactory({
version: 'v1',
action: 'order.create',
principal: (ctx) => ['user', ctx.items.get(CURRENT_USER_ID) as string],
operation: (ctx) => (ctx.request as CreateOrderCommand).externalRef,
});
class CreateOrderHandler {
@pipeline.wrap({ kind: 'command' }, [IdempotencyBehavior, { keyFactory: createOrderKey }])
async handle(command: CreateOrderCommand) {}
}

Optional client-supplied Idempotency-Key

createPartitionedIdempotencyKeyFactory({
principal: readUserId,
operation: (ctx) => (ctx.request as PayCommand).idempotencyKey,
onMissingOperation: 'skip',
});