Write an adapter
An adapter connects one point-of-sale system. Orderable handles hours, lead times, zones, quotes, policy, idempotency and storage, so the adapter only translates.
interface Adapter {
readonly name: string;
listBusinesses(): Promise<Business[]>;
listLocations(): Promise<Location[]>;
getMenu(locationId: string): Promise<Menu>;
getItem(itemId: string): Promise<Item | null>;
getAvailability(locationId: string, itemIds: string[]): Promise<StockLevel[]>;
quote(req: PricingRequest): Promise<PricingResult>;
placeOrder(req: AdapterOrderRequest): Promise<AdapterOrderResult>;
getOrderStatus(externalId: string, order: Order): Promise<AdapterOrderStatus>;
cancelOrder(externalId: string, reason: string, order: Order): Promise<{ cancelled: boolean }>;
}Rules
- Map, don't invent. No allergen data in the POS means all
unknown. Untracked stock meansstatus: "unknown". - Be honest about freshness.
as_ofis when the POS last confirmed the data, not when you read your cache. - Money in minor units with an explicit currency.
- Throw
OrderableErrorfor expected failures; anything else becomesADAPTER_ERROR. - Use Orderable's order_id as the POS idempotency key so a retried send never duplicates there either.
Start from
src/adapters/local.ts: extend it if your source can produce a whole catalog (CSV, Google Sheet, JSON API).src/adapters/square.ts: a partial real POS adapter with TODOs.- Register it in
createAdapter(src/server.ts) and add a quote → order test.
Planned: Square (finish), Toast, Clover, Shopify, Lightspeed. Tell us which one you need.