Franchise Partner Updated
The roles or the primary contact flag of a franchise partner changed. Carries both before and after. Consumed by cna-nexus to invalidate the economic group statistics cache and by cna-one to update the partner's access.
Overview
Fact: the roles or the primary contact flag of a Franchise PartnerFranchise PartnerEntityv1.1.0The link between a franchise unit and a person behind it, with one or more roles - FRANCHISEE (leads the unit) or OPERAT...Ownercna-platformView docs changed. The payload is the Franchise Partner AddedFranchise Partner AddedEventv1.2.0A person became a partner of a franchise unit, with their roles and whether they are a primary contact of the unit. One ...Ownercna-platformSchemaMapView docs payload plus previousRoles and previousIsPrimaryContact.
Since 1.2.0 the event carries isPrimaryContact and previousIsPrimaryContact, the flag after and before the change, in the same pattern as roles and previousRoles. The flag joined the roles as a mutable field of the partner link, so a change of the flag alone publishes this event with roles equal to previousRoles; consumers tell what changed by comparing each pair.
Since 1.1.0 person.birthDate is a calendar day, YYYY-MM-DD, as on FranchisePartnerAdded.
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 updatePartners, only for partners whose roles or primary contact flag differ from the stored ones. It runs inside replaceFranchisePartners, which never sets the flag and keeps the stored one, so contracts and legal info edits publish it only for role changes; inside the operation that sets the primary contacts of a franchise, which changes only the flag of the partners whose flag differs; and when an audit reversal restores a partner’s previous roles and flag. Registered with manager.afterCommit(), one message per changed partner. A change to the person’s own data (name, contacts, birth date) is not a change of the link and does not publish this event; it travels as Partner UpdatedPartner UpdatedEventv1.0.0The personal data of a franchise partner changed in CNA Nexus - name, legal name, e-mail, phone or birth date. Snapshot ...Ownercna-platformSchemaMapView docs on Partner (Kafka topic)Partner (Kafka topic)Channelv1.0.0Kafka topic for the Partner aggregate - a person in their capacity as partner of one or more franchise units. Carries Pa...Ownercna-platformView docs (target contract).
What the consumer does. Same as for FranchisePartnerAdded: cna-nexus bumps the updatedAt of the franchise’s economic group, if any. A role change can move a person in or out of the franchisee count; a change of the flag alone moves no count, and the bump only makes the next read recompute the same numbers. CNA OneCNA OneServicev1.0.0Franchise operating system (franchises and employees, pricing, products and learning books, school operations). Publishe...PublishesGrantApplicationAccess, EmployeeCreated +6SubscribesInviteUser, FranchiseCreated +12Ownercna-platformMapRepoView docs (group franchise-franchise-events, handler syncFranchisePartner, on staging through cna-br/cna-one#903, not yet in production): mirrors the partner as an employee with the FRANCHISEE job role and access to the franchise; a partner of a franchise cna-one does not carry is logged and dropped. Its 1.1.0 copy does not read the flags, so a change of the flag alone rewrites the same employee.
Kafka
Topic (aggregateRoot) | Franchise |
Message key (routingKey) | payload.franchiseId |
| Contract owner | NEXUS |
metadata.event | FranchisePartnerUpdated |
| Consumer groups | economic-group-partner-touch (cna-nexus), franchise-franchise-events (cna-one, pinned to 1.1.0) |
Payload schema
Source of truth
export type FranchisePartnerUpdatedPayload = { franchiseId: string; roles: FranchisePartnerRole[]; previousRoles: FranchisePartnerRole[]; isPrimaryContact: boolean; previousIsPrimaryContact: boolean; person: FranchisePartnerEventPerson;};
export class FranchisePartnerUpdated extends Event<FranchisePartnerUpdatedPayload> { static readonly owner = 'NEXUS'; static readonly aggregateRoot = 'Franchise'; static readonly routingKey = 'franchiseId'; static readonly version = '1.2.0';}Known drift
Observed 2026-10-05.
- cna-nexus
api/app/events/nexus/franchise/FranchisePartnerUpdated.ts: production (v0.14.0) sends the 1.1.0 payload, withperson.birthDateasYYYY-MM-DD, but declaresstatic readonly version = '1.0.0', sometadata.versionreads1.0.0.stagingdeclares1.1.0(cna-br/cna-nexus#587). The 1.2.0 payload, withisPrimaryContactandpreviousIsPrimaryContact, is on cna-nexus branchjc/feature/CWH-52595-publish-primary-contact-in-partner-events(pull request pending) and declares1.2.0. No pin: cna-nexus is the producer. This note goes when the class declaring1.2.0is in production. - cna-one
api/app/events/nexus/franchise/FranchisePartnerUpdated.tsonstaging(cna-br/cna-one#903, not yet in production) declaresversion = '1.1.0'and has noisPrimaryContactnorpreviousIsPrimaryContact; it also typesrolesandperson.documentTypeasstringinstead of the enums. cna-one’sreceivesis pinned to 1.1.0 until a copy carrying the flags is in production (no pull request yet).
Custom properties
| Property | Value |
|---|---|
| Contract Ownerx-contract-owner | NEXUS |
| Kafka Topicx-kafka-topic | Franchise |
| Message Keyx-message-key | franchiseId |
| Sourcex-source | cna-nexus api/app/events/nexus/franchise/FranchisePartnerUpdated.ts |
| Driftx-drift | cna-nexus production sends the 1.1.0 payload but its class declares version 1.0.0, and 1.2.0 (isPrimaryContact) is pending in a pull request; cna-one's copy is 1.1.0, without isPrimaryContact, and its receives is pinned to 1.1.0 until it is updated and in production. |
Franchise id (UUID). Kafka message key.
Roles after the change (FranchisePartnerRole). Never empty.
Roles before the change.
Whether the partner is a primary contact of this franchise for the franchisor team after the change. Belongs to the link with this franchise, not to the person.
Primary contact flag before the change. Differs from isPrimaryContact when the flag changed; equal when only the roles changed.
Snapshot of the person (common.persons).