event

Franchise Created(v1.0.0)

A franchise unit was created in CNA Nexus by activating an opening contract. Full snapshot of the unit; cna-one mirrors it, its address and its partners as employees.

Event Topic: FranchiseKey: idPayload drift
New version found

You are looking at a previous version of the event Franchise Created. The latest version of this event isv1.2.0 →

Overview

Fact: a franchise unit now exists in Nexus. The payload is a full snapshot of the aggregate re-read after commit: unit data, statuses, category, economic group, region, address, partners (without roles) and products.

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 createFranchiseForOpening, the only place a franchise is created: the activation of an OPENING ContractContractEntityv1.0.0A franchise contract in CNA Nexus - opening, renewal or resale - uploaded as a document, analysed by AI, reviewed by a p...Ownercna-platformView docs with no franchise yet (see Contract Activation RequestedContract Activation RequestedEventv1.0.0A user saved a contract for activation. cna-nexus's activation consumer turns it ACTIVE and creates or updates the franc...Ownercna-platformSchemaMapView docs). Registered with manager.afterCommit(), so it goes out only after the unit, its brand, address, territory and partners are committed. The same commit also emits one Franchise Partner AddedFranchise Partner AddedEventv1.1.0A person became a partner of a franchise unit, with their roles. One message per partner. Consumed by cna-nexus itself t...Ownercna-platformSchemaMapView docs per partner.

What the consumer does. CNA OneCNA OneServicev1.0.0Franchise operating system (franchises and employees, pricing, products and learning books, school operations). Publishe...PublishesGrantApplicationAccess, EmployeeCreated +6SubscribesInviteUser, FranchiseCreated +9Ownercna-platformMapRepoView docs (franchiseConsumer, handler syncFranchise), in three blocks:

  1. Franchise: requires and validates cnpj and legalName, checks name, slug and e-mail uniqueness, resolves economicGroup.id (it must have been mirrored by Economic Group CreatedEconomic Group CreatedEventv1.0.0An economic group was created in CNA Nexus. cna-one mirrors it by id so that franchises can reference it.Ownercna-platformSchemaMapView docs first, otherwise the message fails), maps the enums onto cna-one’s own, derives status (ACTIVE when operationalStatus is OPERATIONAL), keeps only the distinct product sub-categories, and upserts by id. If this block fails nothing is written.
  2. Address: skipped when absent; requires street, number, neighborhood, postal code and an IBGE cityId known to cna-one; upserts the unit’s address in place. Failure here is logged and skipped.
  3. Partners: one per distinct document; each becomes a person, an employee, an employment contract with the FRANCHISEE job role and an active staff link, in one transaction. cna-one then publishes its own Employee CreatedEmployee CreatedEventv1.0.0An employee was created in CNA One, with the person it points at. Consumed by cna-auth to provision the account and the ...Ownercna-platformSchemaMapView docs (new employee) or Employee UpdatedEmployee UpdatedEventv1.0.0An employee or the person it points at changed in CNA One. Consumed by cna-auth to update the account and the user, incl...Ownercna-platformSchemaMapView docs (already known), which is what provisions the login in cna-auth. One bad partner is skipped without stopping the others.

Failures are logged and reported to Sentry, never rethrown.

Kafka

Topic (aggregateRoot)Franchise
Message key (routingKey)payload.id
Contract ownerNEXUS
metadata.eventFranchiseCreated
Consumer groupfranchise-franchise-events

Payload schema

Source of truth

export type FranchisePayload = {
id: string;
name: string;
code?: string | null;
cnpj?: string | null;
legalName?: string | null;
stateRegistration?: string | null;
taxRegime?: string | null;
protheusId?: string | null;
conectaEnabled: boolean;
openingStatus: string;
operationalStatus: string;
financialStatus?: string | null;
operationalStartAt?: string | null;
operationalEndAt?: string | null;
firstContractStartsOn?: string | null;
category: FranchiseCategoryData;
economicGroup?: FranchiseEconomicGroupData | null;
operationalRegion?: FranchiseOperationalRegionData | null;
address?: FranchiseAddressData | null;
partners: FranchisePartnerData[];
products: FranchiseProductData[];
};
export class FranchiseCreated extends Event<FranchisePayload> {
static readonly owner = 'NEXUS';
static readonly aggregateRoot = 'Franchise';
static readonly routingKey = 'id';
}

Known drift

cna-one api/app/events/nexus/franchise/FranchiseCreated.ts differs from the canonical type:

Fieldcna-nexuscna-one
email, whatsapp, phoneabsent (never sent)present; the consumer reads them, so they are always undefined
firstContractStartsOnpresentabsent (ignored)
products[].subCategoryProductSubCategory enumstring
nested type names*Data*Payload

Custom properties

PropertyValue
Contract Ownerx-contract-ownerNEXUS
Kafka Topicx-kafka-topicFranchise
Message Keyx-message-keyid
Sourcex-sourcecna-nexus api/app/events/nexus/franchise/FranchiseCreated.ts
Driftx-driftcna-one's copy of FranchisePayload has email, whatsapp and phone (never sent by nexus) and lacks firstContractStartsOn; enums are typed as string and the nested types are renamed.
46 properties
idstring
required

Franchise id (UUID). Kafka message key; cna-one mirrors the unit under this id.

namestring
required

Unit name.

codestring | null

Internal unit code, unique.

cnpjstring | null

Company registration number as stored (no normalisation). cna-one requires and validates it.

legalNamestring | null

Legal company name. cna-one requires it.

stateRegistrationstring | null

State registration number.

taxRegimestring | null

Tax regime (FranchiseTaxRegime), typed as string in the class.

Allowed values: SIMPLES_NACIONAL LUCRO_PRESUMIDO LUCRO_REAL
protheusIdstring | null

Id in the Protheus ERP.

conectaEnabledboolean
required

Inter-school sharing enabled.

openingStatusstring
required

Lifecycle stage (FranchiseOpeningStatus), typed as string in the class.

Allowed values: CREATED BUILT TRAINED SUSPENDED UNDER_REVIEW DEFAULTING
operationalStatusstring
required

Operational status (FranchiseOperationalStatus). cna-one maps OPERATIONAL to ACTIVE, anything else to INACTIVE.

Allowed values: OPERATIONAL NON_OPERATIONAL UNDER_DEVELOPMENT
financialStatusstring | null

Financial standing (FranchiseFinancialStatus).

Allowed values: ACTIVE INACTIVE SUSPENDED DEFAULTING UNDER_REVIEW
operationalStartAtstring | null<date-time>

ISO-8601 instant when operations started.

operationalEndAtstring | null<date-time>

ISO-8601 instant when operations ended.

firstContractStartsOnstring | null<date>

YYYY-MM-DD start of the earliest opening contract, or null. Ignored by cna-one.

categoryobject
required

Size/type category of the unit.

economicGroupobject | null

Economic group of the unit, or null. cna-one requires the group to have been mirrored first (EconomicGroupCreated).

operationalRegionobject | null

Operational region, or null.

addressobject | null

Unit address, or null. cna-one requires street, number, neighborhood, postalCode and cityId to mirror it.

partnersarray[object]
required

People behind the unit. May be empty. Roles are not included; cna-one turns each into a FRANCHISEE employee.

productsarray[object]
required

Products the unit is enabled to sell. cna-one keeps only the distinct sub-categories.