@flipdish/events
v1.26156.0
Published
A TypeScript package for handling event schemas and types in Flipdish's event-driven architecture.
Keywords
Readme
@flipdish/events
A TypeScript package for handling event schemas and types in Flipdish's event-driven architecture.
Overview
This package is the contract-first source of truth for Flipdish events on EventBridge and webhooks. It provides strongly-typed definitions and Zod schemas for validation at publish and consume time across Zeus v3 events, RMS v1 events, org management, loyalty, and more.
Contact the platform enablement team in #ask-platform-enablement-team with any questions.
Installation
npm install @flipdish/eventsFeatures
- Type-safe event definitions
- Runtime schema validation using Zod
- EventBridge envelope support
- Shared EventBridge metadata schema (
metadata.ts) - Webhook-emittable RMS events (menu publishing, sales, snoozes)
Event envelope and metadata
Most EventBridge events use a common envelope: top-level EventBridge fields plus a detail object with metadata and properties. The shared metadata schema lives in metadata.ts and is re-used (sometimes extended) per domain.
Required metadata fields include dataschema, id, source, specversion, time, type, x-span-id, and x-trace-id.
Commonly optional metadata fields:
| Field | Schema | Notes |
|-------|--------|-------|
| actorUserId | number \| null (optional) | User who triggered the change; emitters often send null when no user context |
| actor | object (optional) | Richer actor details (id, email, name, etc.) |
| externalPayload | object (optional) | URL + TTL for large payloads stored externally (see common/external-payload.ts) |
| webhookConfig, auditLogConfig, initiator, sequence, stage, … | various | See metadata.ts |
When validating or parsing events, treat omitted fields and explicit null for actorUserId as equivalent unless a domain schema documents otherwise. Use .nullable().optional() in Zod for fields production may send as null.
Menu events (rms/menus) extend metadata via MenuMetadataSchema; externalPayload is optional there as well (inline menu data may appear under detail.properties.menu instead).
Development
When adding types or making changes, bump the version in package.json before raising a PR (npm run bump:version).
Public events and webhooks
Webhook-emittable events are defined in a single list: webhooks/webhookEventTypes.
When you add a new event that should be webhook-emittable:
Add the event type to
webhooks/index.tsinsidewebhookEventTypes.Ensure the event has a schema in its domain
eventSchemaMapand that the schema includes a non-emptydescription(either directly or via OpenAPI metadata).Validate locally
npm run build
npm test -- webhooks/webhook-events.test.tsNotes:
- There is no separate public events registry;
webhookEventTypesis the source of truth. - Tests enforce that each webhookable event has a schema with a non-empty description.
Workflow: Add and Publish a Webhook Event
%%{init: {'theme': 'default'}}%%
sequenceDiagram
autonumber
%% === Lanes / Color Groups ===
box rgb(214,233,255) Dev & Repo
actor Dev as Developer
participant Repo as GitHub Repo (flipdishbytes/events)
end
box rgb(243,229,245) Build & Docs Gen
participant Index as webhooks/index.ts
participant CI as GitHub Actions
participant Gen as Generator (openapi:from-zod)
participant ReadMe as ReadMe.com
end
box rgb(226,240,217) Distribution
participant NPM as npm Registry
end
box rgb(255,236,204) Runtime
participant Service as Webhooks Service
end
%% === Flow ===
Dev->>Repo: Add Zod event schema + .openapi() metadata
Dev->>Repo: Export in module (eventTypes + eventSchemaMap)
Dev->>Index: Append event to webhookEventTypes
Dev->>Repo: PR → merge to main
Repo-->>CI: Workflow trigger
CI->>Gen: npm run openapi:from-zod -- --title "Webhook Events" --version v1 --out openapi.webhooks.json
Gen->>Index: Import webhookEventTypes
Gen->>Repo: Load providers exporting eventSchemaMap
Gen->>Gen: Extract detail.properties schemas
Gen->>Gen: Generate OAS 3.1 + webhooks section
CI->>ReadMe: rdme openapi openapi.webhooks.json --id <slug> --key $README_API_KEY --version v3.1
CI->>NPM: npm version <semver> && npm publish
Service->>NPM: Install @flipdish/events@<new>
Service->>Service: Validate payloads with exported Zod schemas
%% === Notes / Legend ===
note over Dev,Repo: Author & curate event schemas
note over CI,Gen: Generate OpenAPI + publish docs to ReadMe
note over NPM: Version & publish @flipdish/events
note over Service: Consume package & validate payloadsQuick commands:
# Generate OAS 3.1 with webhooks
npm run openapi:from-zod
# Validate then upload to ReadMe (requires README_API_KEY)
npx rdme@10 openapi validate ./openapi.webhooks.json
npx rdme@10 openapi upload ./openapi.webhooks.json --slug "<slug>" --key "$README_API_KEY" --branch "3.0"Prerequisites
- Node.js
- npm or yarn
Example Usage
EventBridge envelope (RMS menu published)
import { MenuEventBaseSchema } from '@flipdish/events/rms/menus';
const event = {
source: 'rms',
'detail-type': 'menu.published.v1',
detail: {
properties: {
orgId: 'org123',
menuId: '123e4567-e89b-12d3-a456-426614174000',
menuRevisionId: 1,
},
metadata: {
actorUserId: null, // optional; null when no user context
dataschema: 'https://events.flipdish.com/menu.published.v1.json',
id: '550e8400-e29b-41d4-a716-446655440000',
source: 'rms',
specversion: '1.0',
time: '2026-05-20T12:00:00.000Z',
type: 'menu.published.v1',
'x-span-id': 'span-id',
'x-trace-id': 'trace-id',
// externalPayload optional — menu may be inline in properties.menu
},
},
};
const validated = MenuEventBaseSchema.parse(event);Loyalty Events
import {
loyaltyEventSchema,
RewardEarned,
StampEarned,
} from '@flipdish/events/loyalty';
const event = {
profileId: '123',
customerId: '456',
brandId: '789',
campaignId: 'camp_123',
rewardId: 'reward_123',
eventName: 'loyalty.reward.earned.v1',
};
const validatedEvent = loyaltyEventSchema.parse(event);Events Reference
Testing Coverage Summary
- Total Schemas: 111
- Tested Schemas: 97
- Untested Schemas: 14
- Coverage: 87.39%
This package supports a wide range of event types across different domains. Below is a comprehensive list of all available events, organized by domain:
App
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | app.created.v3 | Triggered when a new app is created | ⚠️ Tested with less than 10 samples | 5 | | app.updated.v3 | Triggered when an app is updated | ✅ Tested | 37 |
Appstore
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | appstore.configuration.created.v3 | Triggered when an appstore configuration is created | ⚠️ Tested with less than 10 samples | 1 | | appstore.configuration.deleted.v3 | Triggered when an appstore configuration is deleted | ⚠️ Tested with less than 10 samples | 1 | | appstore.configuration.updated.v3 | Triggered when an appstore configuration is updated | ✅ Tested | 12 |
Bank Account
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | bankaccount.assigned.v3 | Triggered when a bank account is assigned | ⚠️ Tested with less than 10 samples | 7 | | bankaccount.created.v3 | Triggered when a bank account is created | ⚠️ Tested with less than 10 samples | 1 | | bankaccount.deleted.v3 | Triggered when a bank account is deleted | ⚠️ Tested with less than 10 samples | 4 | | bankaccount.updated.v3 | Triggered when a bank account is updated | ✅ Tested | 12 |
Campaign
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | campaign.loyalty.created.v3 | Triggered when a loyalty campaign is created | ⚠️ Tested with less than 10 samples | 5 | | campaign.loyalty.updated.v3 | Triggered when a loyalty campaign is updated | ⚠️ Tested with less than 10 samples | 4 | | campaign.loyalty.deleted.v3 | Triggered when a loyalty campaign is deleted | ⚠️ Tested with less than 10 samples | 1 | | campaign.retention.created.v3 | Triggered when a retention campaign is created | ⚠️ Tested with less than 10 samples | 2 | | campaign.retention.updated.v3 | Triggered when a retention campaign is updated | ⚠️ Tested with less than 10 samples | 5 | | campaign.retention.deleted.v3 | Triggered when a retention campaign is deleted | ⚠️ Tested with less than 10 samples | 1 |
Card Readers
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | cardreaders.kiosk.bluetooth.initiatepairingmode.v3 | Triggered when card reader pairing mode is initiated | ✅ Tested | 24 | | cardreaders.kiosk.bluetooth.initiateunpairingmode.v3 | Triggered when card reader unpairing mode is initiated | ⚠️ Tested with less than 10 samples | 1 | | cardreaders.kiosk.bluetooth.terminalactionstatechanged.v3 | Triggered when terminal action state is changed | ✅ Tested | 754 | | cardreaders.kiosk.bluetooth.unpaired.v3 | Triggered when a card reader is unpaired | ⚠️ Tested with less than 10 samples | 1 | | cardreaders.kiosk.bluetooth.updated.v3 | Triggered when a card reader is updated | ✅ Tested | 147 |
Catalog
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | catalog.group.created.v3 | Triggered when a catalog group is created | ❌ Untested | 0 | | catalog.group.updated.v3 | Triggered when a catalog group is updated | ✅ Tested | 611 | | catalog.item.created.v3 | Triggered when a catalog item is created | ❌ Untested | 0 | | catalog.item.updated.v3 | Triggered when a catalog item is updated | ✅ Tested | 2184 |
Channel
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | channel.stores.updated.v3 | Triggered when channel stores are updated | ✅ Tested | 13 |
Customer
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | customer.created.v3 | Triggered when a customer is created | ✅ Tested | 195 | | customer.updated.v3 | Triggered when a customer is updated | ✅ Tested | 2011 | | customer.consent.updated.v3 | Triggered when customer consent is updated | ✅ Tested | 2618 |
External Event
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | externalevent.store.v3 | Triggered when a store external event occurs | ✅ Tested | 2055 |
Hydra
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | hydra.assigned.v3 | Triggered when hydra is assigned | ⚠️ Tested with less than 10 samples | 8 | | hydra.conection_status_changed.v3 | Triggered when hydra connection status changes | ⚠️ Tested with less than 10 samples | 7 | | hydra.unassigned.v3 | Triggered when hydra is unassigned | ⚠️ Tested with less than 10 samples | 6 |
Menu
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | menu.created.v3 | Triggered when a menu is created | ✅ Tested | 113 | | menu.updated.v3 | Triggered when a menu is updated | ✅ Tested | 286 | | menu.uploaded.v3 | Triggered when a menu is uploaded | ✅ Tested | 143 | | menu.async_creation.completed.v3 | Triggered when async menu creation completes | ✅ Tested | 60 | | menu.section.created.v3 | Triggered when a menu section is created | ✅ Tested | 68 | | menu.section.updated.v3 | Triggered when a menu section is updated | ✅ Tested | 576 | | menu.section_item.created.v3 | Triggered when a menu section item is created | ✅ Tested | 11 | | menu.section_item.updated.v3 | Triggered when a menu section item is updated | ✅ Tested | 3636 | | menu.section_item.deleted.v3 | Triggered when a menu section item is deleted | ⚠️ Tested with less than 10 samples | 4 | | menu.option_set.created.v3 | Triggered when a menu option set is created | ✅ Tested | 22 | | menu.option_set.updated.v3 | Triggered when a menu option set is updated | ✅ Tested | 51 | | menu.option_set.deleted.v3 | Triggered when a menu option set is deleted | ⚠️ Tested with less than 10 samples | 9 | | menu.option_set_item.created.v3 | Triggered when a menu option set item is created | ✅ Tested | 28 | | menu.option_set_item.updated.v3 | Triggered when a menu option set item is updated | ✅ Tested | 8158 | | menu.option_set_item.deleted.v3 | Triggered when a menu option set item is deleted | ✅ Tested | 343 |
Menu Checkpoint
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | menu_checkpoint.created.v3 | Triggered when a menu checkpoint is created | ✅ Tested | 869 |
Order
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | order.created.v3 | Triggered when an order is created | ✅ Tested | 880 | | order.accepted.v3 | Triggered when an order is accepted | ✅ Tested | 863 | | order.rejected.v3 | Triggered when an order is rejected | ✅ Tested | 251 | | order.dispatched.v3 | Triggered when an order is dispatched | ✅ Tested | 864 | | order.refunded.v3 | Triggered when an order is refunded | ✅ Tested | 308 | | order.rating.updated.v3 | Triggered when an order rating is updated | ✅ Tested | 92 | | order.tip.updated.v3 | Triggered when an order tip is updated | ❌ Untested | 0 | | order.capacity.updated.v3 | Triggered when order capacity is updated | ✅ Tested | 16 | | order.location.created.v3 | Triggered when an order location is created | ⚠️ Tested with less than 10 samples | 3 | | order.location.deleted.v3 | Triggered when an order location is deleted | ⚠️ Tested with less than 10 samples | 3 | | order.location_area.created.v3 | Triggered when an order location area is created | ⚠️ Tested with less than 10 samples | 3 | | order.location_area.updated.v3 | Triggered when an order location area is updated | ⚠️ Tested with less than 10 samples | 3 | | order.deliverytracking.status.updated.v3 | Triggered when delivery tracking status is updated | ✅ Tested | 790 | | order.fulfillment.status.updated.v3 | Triggered when fulfillment status is updated | ✅ Tested | 3270 | | order.terminal.notification.v3 | Triggered when a terminal notification is sent | ❌ Untested | 0 |
Online Orders
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | order.created.notification.required.v1 | Triggered when an online order is created | -| - | | order.status.notification.required.v1 | Triggered when an online order status is updated | - | - |
Phone Call
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | phone_call.started.v3 | Triggered when a phone call is started | ✅ Tested | 3777 | | phone_call.ended.v3 | Triggered when a phone call is ended | ✅ Tested | 4114 |
Printer
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | printer.turned_on.v3 | Triggered when a printer is turned on | ⚠️ Tested with less than 10 samples | 4 | | printer.turned_off.v3 | Triggered when a printer is turned off | ⚠️ Tested with less than 10 samples | 6 |
Push Notification
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | push_notification.sent.v3 | Triggered when a push notification is sent | ✅ Tested | 18 | | push_notification.scheduled.v3 | Triggered when a push notification is scheduled | ✅ Tested | 19 | | push_notification.deleted.v3 | Triggered when a push notification is deleted | ❌ Untested | 0 |
Store
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | store.created.v3 | Triggered when a store is created | ✅ Tested | 13 | | store.updated.v3 | Triggered when a store is updated | ✅ Tested | 123 | | store.address.updated.v3 | Triggered when a store address is updated | ⚠️ Tested with less than 10 samples | 8 | | store.archived.v3 | Triggered when a store is archived | ⚠️ Tested with less than 10 samples | 2 | | store.unarchived.v3 | Triggered when a store is unarchived | ⚠️ Tested with less than 10 samples | 4 | | store.published.v3 | Triggered when a store is published | ⚠️ Tested with less than 10 samples | 8 | | store.unpublished.v3 | Triggered when a store is unpublished | ⚠️ Tested with less than 10 samples | 7 | | store.business_hours_override.created.v3 | Triggered when business hours override is created | ✅ Tested | 185 | | store.business_hours_override.deleted.v3 | Triggered when business hours override is deleted | ✅ Tested | 179 | | store.delivery_zone.created.v3 | Triggered when a delivery zone is created | ✅ Tested | 32 | | store.delivery_zone.updated.v3 | Triggered when a delivery zone is updated | ✅ Tested | 164 | | store.delivery_zone.deleted.v3 | Triggered when a delivery zone is deleted | ✅ Tested | 20 | | store.fee_config.updated.v3 | Triggered when fee config is updated | ✅ Tested | 22 | | store.kiosk_setting.updated.v3 | Triggered when kiosk setting is updated | ⚠️ Tested with less than 10 samples | 1 | | store.logo.created.v3 | Triggered when a store logo is created | ❌ Untested | 0 | | store.logo.deleted.v3 | Triggered when a store logo is deleted | ❌ Untested | 0 | | store.menu.assigned.v3 | Triggered when a menu is assigned to a store | ✅ Tested | 195 | | store.opening_hours.updated.v3 | Triggered when opening hours are updated | ✅ Tested | 4136 | | store.preorder_config.updated.v3 | Triggered when preorder config is updated | ✅ Tested | 58 | | store.service_charge.updated.v3 | Triggered when service charge is updated | ❌ Untested | 0 | | store.tip.updated.v3 | Triggered when store tip is updated | ❌ Untested | 0 |
Store Group
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | store_group.created.v3 | Triggered when a store group is created | ⚠️ Tested with less than 10 samples | 5 | | store_group.updated.v3 | Triggered when a store group is updated | ⚠️ Tested with less than 10 samples | 2 | | store_group.deleted.v3 | Triggered when a store group is deleted | ❌ Untested | 0 |
Stripe Account
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | stripecustomconnectedaccount.updated.v3 | Triggered when a Stripe custom connected account is updated | ✅ Tested | 31 |
Teammate
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | teammate.updated.v3 | Triggered when a teammate is updated | ⚠️ Tested with less than 10 samples | 2 | | teammate.deleted.v3 | Triggered when a teammate is deleted | ⚠️ Tested with less than 10 samples | 5 | | teammate.invite.accepted.v3 | Triggered when a teammate invite is accepted | ⚠️ Tested with less than 10 samples | 1 | | teammate.invite.sent.v3 | Triggered when a teammate invite is sent | ⚠️ Tested with less than 10 samples | 1 |
Telephony Config
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | telephony_config.updated.v3 | Triggered when a telephony config is updated | ⚠️ Tested with less than 10 samples | 6 |
User
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | user.updated.v3 | Triggered when a user is updated | ✅ Tested | 11 | | user.login.v3 | Triggered when a user logs in | ⚠️ Tested with less than 10 samples | 4 | | user.roleschanged.v3 | Triggered when user roles are changed | ⚠️ Tested with less than 10 samples | 5 |
Voucher
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | voucher.created.v3 | Triggered when a voucher is created | ✅ Tested | 475 | | voucher.updated.v3 | Triggered when a voucher is updated | ✅ Tested | 12 | | voucher.applied.v3 | Triggered when a voucher is applied | ✅ Tested | 97 |
Webhook Subscription
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | webhook_subscription.created.v3 | Triggered when a webhook subscription is created | ❌ Untested | 0 | | webhook_subscription.updated.v3 | Triggered when a webhook subscription is updated | ❌ Untested | 0 | | webhook_subscription.deleted.v3 | Triggered when a webhook subscription is deleted | ❌ Untested | 0 |
Website
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | website.updated.v3 | Triggered when a website is updated | ⚠️ Tested with less than 10 samples | 8 | | website.vanityurl.updated.v3 | Triggered when a website vanity URL is updated | ❌ Untested | 0 |
Loyalty
| Event Type | Description | Testing Status | Sample Count | |------------|-------------|---------------|--------------| | loyalty.reward.earned.v1 | Triggered when a loyalty reward is earned | - | - | | loyalty.stamp.earned.v1 | Triggered when a loyalty stamp is earned | - | - |
RMS Webhooks (v1)
These events are registered in webhooks/webhookEventTypes and documented in ReadMe via OpenAPI generation. They use the EventBridge envelope with detail.metadata and detail.properties.
| Event Type | Description | |------------|-------------| | menu.published.v1 | Menu published to sales channels (closed beta) | | menu.validation.failed.v1 | Menu publish failed validation | | menu.item.snoozed.v1 | Menu item snoozed | | menu.item.unsnoozed.v1 | Menu item unsnoozed | | sales_channel.snoozed.v1 | Sales channel snoozed | | sales_channel.unsnoozed.v1 | Sales channel unsnoozed | | sales.pos.status.updated.v1 | POS order status updated | | sales.delivery.status.updated.v1 | Delivery status updated | | sales.created.v1 | Sale created | | sales.cancelled.v1 | Sale cancelled |
Org Management
| Event Type | Description | |------------|-------------| | org.created.v1 | Organization created | | org.created.v2 | Organization created | | org.updated.v1 | Organization updated | | org.updated.v2 | Organization updated | | property.created.v2 | Property created | | property.updated.v2 | Property updated | | property.opening_hours.created.v1 | Property opening hours created | | property.opening_hours.updated.v1 | Property opening hours updated | | sales_channel.created.v1 | Sales channel created | | sales_channel.updated.v1 | Sales channel updated | | sales_channel.opening_hours.created.v1 | Sales channel opening hours created | | sales_channel.opening_hours.updated.v1 | Sales channel opening hours updated | | brand.created.v1 | Brand created | | brand.updated.v1 | Brand updated |
Property Management
| Event Type | Description | |------------|-------------| | property_config.collection.created | Property configuration created | | property_config.collection.updated | Property configuration updated |
Storefront
| Event Type | Description | |------------|-------------| | storefront.created.v1 | Storefront created | | storefront.updated.v1 | Storefront updated |
