event

Contract Activation Requested

A user saved a contract for activation. cna-nexus's activation consumer turns it ACTIVE and creates or updates the franchise unit it governs.

Event Topic: ContractKey: contractId

Overview

Fact: a contract was saved in the state ACTIVATING and its activation is requested. It is the hand-off between the API request and the background work.

When it is published. CNA NexusCNA NexusServicev1.0.0Franchise network back-office (franchises, economic groups, partners, contracts and amendments, document storage, AI doc...PublishesInviteUser, ContractActivationRequested +13SubscribesContractActivationRequested, AmendmentApplyRequested +4Ownercna-platformMapRepoView docs, in createContract and updateContract, right after the transaction that writes the contract with its financial terms, franchise data, address, territory and participants returns with status = ACTIVATING. Every update of a contract publishes it again, so the franchise aggregate is brought back in sync. Published after the write, not registered with afterCommit: if the producer fails, the contract stays ACTIVATING with no message.

What the consumer does. cna-nexus (contractActivationConsumer, group contract-activation):

  1. Loads the contract; a missing contract throws (logged and reported to Sentry).
  2. Idempotency guard: ACTIVE or ACTIVATION_FAILED are skipped, so redelivery after success is harmless and a failed activation needs a manual retry.
  3. activateContract(contractId, userId): re-checks ACTIVATING, then in one transaction sets the contract ACTIVE with activatedAt, and projects it onto the franchise. The first activation of an OPENING with no franchise creates the Franchise aggregate (unit, brand, address, territory, partners) and links the contract to it; any other case applies the contract snapshot onto the existing franchise. A RENEWAL flips the previous active or expired contract to RENEWED. Field-level audit rows are written with the userId from the payload.
  4. On failure: logs and sets the contract to ACTIVATION_FAILED. Not rethrown, so Sentry is not notified from this path.

Follow-up messages. Inside the same transaction, via manager.afterCommit(): FranchiseCreated on the first activation of an opening, FranchiseUpdated otherwise (see the Franchise topic).

Kafka

Topic (aggregateRoot)Contract
Message key (routingKey)payload.contractId
Contract ownerNEXUS
metadata.eventContractActivationRequested
Consumer groupcontract-activation

Payload schema

Source of truth

type ContractActivationRequestedPayload = {
contractId: string;
userId: string;
};
export class ContractActivationRequested extends Event<ContractActivationRequestedPayload> {
static readonly owner = "NEXUS";
static readonly aggregateRoot = "Contract";
static readonly routingKey = "contractId";
}

The class exists only in cna-nexus.

Known drift

  • Docstrings in createContract, createContractAndRelations and updateContractAndRelations say a failed activation moves the contract to DRAFT; the consumer writes ACTIVATION_FAILED.
  • Published without afterCommit, unlike the Franchise events it triggers.

Custom properties

PropertyValue
Contract Ownerx-contract-ownerNEXUS
Kafka Topicx-kafka-topicContract
Message Keyx-message-keycontractId
Sourcex-sourcecna-nexus api/app/events/nexus/contract/ContractActivationRequested.ts
2 properties
contractIdstring
required

Contract id (UUID) in cna-nexus contract.contracts. Kafka message key.

userIdstring
required

User who saved the contract (authorization.users). Recorded as the author of the audit rows written by the activation.