Price Table Created
A price table was created with its default price groups. cna-one's pricing consumer seeds it with one price per available learning book, copying last year's amounts when they exist.
Overview
Fact: a price table exists, with its B2B and B2C default price groups. The payload is the table header.
When it is published. 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, in franchisorCreateLearningBookPriceTable, after the command that creates the table and its default groups returns. Before that, the validity is checked: no overlap with the last table and a duration between 3 and 18 months; the year is derived from the last table (plus one) or from startsOn. type is always LEARNING_BOOK today. Published after the write, not inside afterCommit.
What the consumer does. cna-one’s pricing process (priceTableConsumer, handler syncPriceTableCreatedToLearningBookPrices):
- Ignores tables whose
typeis notLEARNING_BOOK. - Loads the table’s default price groups and the learning books currently available. Either list empty: logs a warning and stops.
- Idempotency guard: if the default groups already hold any price, stops without writing. Redelivery neither duplicates nor overwrites.
- Builds one
FIXEDprice per default group and learning book. The amount is copied from the previous year’s table when that table has a price for the same sales channel and book; otherwise it is leftnullfor someone to fill in. - Upserts the prices.
Failures are logged and reported to Sentry, never rethrown.
Kafka
Topic (aggregateRoot) | PriceTable |
Message key (routingKey) | payload.id |
| Contract owner | ONE |
metadata.event | PriceTableCreated |
| Consumer group | pricing-price-table-events |
Payload schema
Source of truth
import { ProductType } from "db/enums/product/Product";
export type PriceTablePayload = { id: string; type: ProductType; year: number; name: string; startsOn: string; endsOn: string;};
class PriceTableCreated extends Event<PriceTablePayload> { public static owner = "ONE"; public static aggregateRoot = "PriceTable"; public static routingKey = "id";}The class exists only in cna-one.
Custom properties
| Property | Value |
|---|---|
| Contract Ownerx-contract-owner | ONE |
| Kafka Topicx-kafka-topic | PriceTable |
| Message Keyx-message-key | id |
| Sourcex-source | cna-one api/app/events/one/priceTable/PriceTableCreated.ts |
Price table id (UUID). Kafka message key.
Product type the table prices (cna-one ProductType). Always LEARNING_BOOK today; the consumer ignores other types.
COURSE CERTIFICATION LEARNING_BOOK PRODUCTCalendar year the table applies to.
Display name of the table.
First day of validity, YYYY-MM-DD.
Last day of validity, YYYY-MM-DD.