GraphQL — Узел магазина
296 определений
← Вся документация · Источник: контракты, graphql/store.graphql на коммите 8000474.
Справочники на английском — на языке контрактов, из которых они созданы.
scalar UUID
# GraphQL schema of the node in the store role (spec/API.md). Queries only in
# this version: changes go through REST. Every field checks the same
# permission as its REST counterpart in openapi/store-v1.yaml.
"A UUID in its canonical text form."
scalar UUID
scalar DateTime
"An RFC 3339 time in UTC."
scalar DateTime
scalar Date
"A business date, YYYY-MM-DD."
scalar Date
scalar Int64
"A signed 64-bit integer as a JSON number (amounts in minor units, quantities in thousandths)."
scalar Int64
scalar JSON
"Any JSON value (localized texts, profile attributes)."
scalar JSON
type Query
type Query {
"The caller and its effective permissions."
me: Me!
"store.read: this store's update (spec/RELEASES.md, The store's update)"
storeUpdate: StoreUpdate!
"release.read: the releases this node holds, the latest version first: a hub's, or a store's with no hub (spec/RELEASES.md, A store with no hub); owned_by_hub at a store of a chain"
releases(first: Int! = 50, after: String): ReleasePage!
"release.read: one release with its signed manifest"
release(version: String!): Release
"store.read"
store: Store!
"store.read: the store's effective brand, the brand overlaid with its banner, or the default (spec/BRANDS.md, What the apps get)"
brand: EffectiveBrand!
"store.read"
taxRates: [TaxRate!]!
"store.read: spec/TAX.md, Container deposits"
deposits: [Deposit!]!
"store.read: spec/TAX.md, Rates from a provider; the key is only named"
taxProvider: TaxProvider!
"store.read"
license: License!
"item.read"
items(q: String, groupId: UUID, active: Boolean, parentId: UUID, kindOf: ItemKindOf, first: Int! = 50, after: String): ItemPage!
"item.read"
item(id: UUID!): Item
"item.read: code only as a variable (spec/API.md, Transport)"
lookup(code: String!): Lookup
"item.read"
groups: [Group!]!
"item.read: spec/SEARCH.md, Tags"
tags: [Tag!]!
"item.read"
promotions: [Promotion!]!
"stock.read"
stock(itemId: UUID!): Stock
"stock.read"
holds(itemId: UUID): [Hold!]!
"stock.read: the item serials matching a serial number, history newest first (spec/VARIANTS.md)"
serials(serial: String!): [SerialRecord!]!
"document.read"
documents(kind: DocumentKind, status: DocumentStatus, order: ListOrder = ASC, first: Int! = 50, after: String): DocumentPage!
"document.read"
document(id: UUID!): Document
"shift.read"
shifts(status: ShiftStatus, workplaceId: UUID, first: Int! = 50, after: String): ShiftPage!
"shift.read"
shift(id: UUID!): Shift
"shift.report.x"
shiftReport(id: UUID!, cashierId: UUID): ShiftTotals
"receipt.read"
receipts(shiftId: UUID, first: Int! = 50, after: String): ReceiptPage!
"receipt.read"
receipt(id: UUID!): Receipt
"employee.read"
employees(first: Int! = 50, after: String): EmployeePage!
"role.read"
roles: [Role!]!
"report.read: spec/REPORTS.md, Sales"
salesReport(from: DateTime!, to: DateTime!, groupBy: SalesGroupBy!, rollUpVariants: Boolean! = false): SalesReport!
"report.read: spec/REPORTS.md, Stock"
stockReport(groupId: UUID, belowZero: Boolean, first: Int! = 50, after: String): StockReportPage!
"report.read: spec/REPORTS.md, Movements"
movements(from: DateTime!, to: DateTime!, itemId: UUID, first: Int! = 50, after: String): MovementPage!
"price.edit: spec/PRICING.md, Markup (writes nothing)"
priceProposals(input: PriceProposalInput!): [PriceProposal!]!
"item.read: spec/SYNC.md, Change requests (empty in a store with no hub)"
changeRequests(status: ChangeRequestStatus, first: Int! = 50, after: String): ChangeRequestPage!
"Changes agents proposed that the caller asked for or may approve (spec/MCP.md)."
proposals(status: ProposalStatus, first: Int! = 50, after: String): ProposalPage!
"One proposal the caller asked for or may approve."
proposal(id: UUID!): Proposal
"assistant.use: the assistant's settings, never the key (spec/ASSISTANT.md)"
assistantSettings: AssistantSettings!
"item.read: search the catalog by meaning, exact matches first (spec/SEARCH.md, Searching); the license module search"
searchItems(q: String!, groupId: UUID, tagId: UUID, storeId: UUID, includeInactive: Boolean = false, limit: Int! = 20): SearchResult!
"item.read: suggested tags and groups, newest first (spec/SEARCH.md, Suggestions)"
searchSuggestions(status: SuggestionStatus = OPEN, kind: SuggestionKind, itemId: UUID, first: Int! = 50, after: String): SuggestionPage!
"item.read: the active index and the one building"
searchIndex: SearchIndexStatus!
"search.manage: the embedding provider and the suggestions' settings, never the key"
searchSettings: SearchSettings!
"network.read: spec/NETWORK.md, the private network as this store sees it"
network: StoreNetworkState!
"report.read: spec/REPORTS.md, Tax"
taxReport(from: Date!, to: Date!): TaxReport!
"kitchen.use: a station's tickets, oldest first (spec/FOOD_SERVICE.md, Kitchen display)"
kitchenTickets(station: String!, state: KitchenTicketList = OPEN): [KitchenTicket!]!
"pse.read: the pseudoephedrine logbook, newest first (spec/PHARMACY.md)"
pseLog(from: Date!, to: Date!, first: Int! = 50, after: String): PseLogPage!
"document.read: spec/STOCK.md, Transfers; both stores' documents"
transfers(direction: TransferDirection, state: TransferState, first: Int! = 50, after: String): TransferPage!
"document.read"
transfer(id: UUID!): Transfer
"stock.read: lines of transfers from or to this store that are in transit"
inTransit: [InTransitLine!]!
"store.read: the chain's stores, each by id, code and name only (spec/SYNC.md); empty with no hub"
storeDirectory: [StoreDirectoryEntry!]!
"document.read: spec/STOCK.md, Purchase orders"
suppliers: [Supplier!]!
"item.read: spec/STOCK.md, Recipes and production"
recipes(productItemId: UUID): [Recipe!]!
"item.read: spec/PRICING.md, Batch prices; holds nothing"
priceSplit(itemId: UUID!, quantityMilli: Int64!, lot: String): PriceSplit!
"item.read: spec/PRICING.md, Expiry rules"
expiryRules: [ExpiryRule!]!
"item.read: spec/LOYALTY.md, Programs"
loyaltyPrograms: [LoyaltyProgram!]!
"customer.read: masked (spec/LOYALTY.md, Customers); by a name's prefix or a phone's last four digits"
customers(q: String, first: Int! = 50, after: String): CustomerPage!
"customer.read: masked"
customer(id: UUID!): Customer
"customer.read: by a card number or an E.164 phone, exactly, each only as a variable (spec/API.md, Transport); masked; no presence token (REST POST /v1/customers/lookup gives one)"
customerLookup(card: String, phone: String): Customer
"customer.read: points and stamps at the balance owner"
customerBalances(id: UUID!): CustomerBalances
"loyalty.manage: newest first"
customerLedger(id: UUID!, programId: UUID, first: Int! = 50, after: String): LedgerPage!
"loyalty.manage: spec/LOYALTY.md, Balances and their owner"
balanceHolds(status: BalanceHoldStatus, first: Int! = 50, after: String): BalanceHoldPage!
"item.read: spec/LOYALTY.md, Vouchers and coupons"
vouchers(active: Boolean, coupons: Boolean, first: Int! = 50, after: String): VoucherPage!
"receipt.sell: a code's voucher and whether it can be used now; code only as a variable (spec/API.md, Transport)"
voucherLookup(code: String!): VoucherCheck
"gift_card.manage: masked (spec/LOYALTY.md, Gift cards); a balance by number is REST only, the number in its body"
giftCards(status: GiftCardStatus, batchId: UUID, first: Int! = 50, after: String): GiftCardPage!
"gift_card.manage"
giftCard(id: UUID!): GiftCard
"gift_card.manage: newest first"
giftCardLedger(id: UUID!, first: Int! = 50, after: String): LedgerPage!
"item.read: spec/LOYALTY.md, Partner codes"
partners: [Partner!]!
"bonus.read: spec/REPORTS.md, Employee bonuses"
bonusRules: [BonusRule!]!
"bonus.read: spec/REPORTS.md, Employee bonuses"
bonusReport(from: DateTime!, to: DateTime!): BonusReport!
"report.read: spec/REPORTS.md, Partners"
partnerReport(from: DateTime!, to: DateTime!): PartnerReport!
"check.use or floor.manage: spec/RESTAURANT.md, The floor; tables' QR tokens only with floor.manage"
floor: Floor!
"check.use: spec/RESTAURANT.md, Checks; open and billed by default, oldest first"
checks(state: CheckListState = ACTIVE, tableId: UUID, waiterId: UUID, first: Int! = 50, after: String): CheckPage!
"check.use"
check(id: UUID!): Check
"check.any: offline receipts of checks that did not apply (spec/RESTAURANT.md, Offline)"
checkConflicts(resolved: Boolean = false, first: Int! = 50, after: String): CheckConflictPage!
"check.use: guests' orders, pending first (spec/RESTAURANT.md, The guest listener)"
guestOrders(state: GuestOrderState, tableId: UUID, first: Int! = 50, after: String): GuestOrderPage!
"item.read: spec/RESTAURANT.md, The guest menu"
menus: [Menu!]!
"item.read"
menu(id: UUID!): Menu
"item.read: the guest menu's theme"
menuTheme: MenuTheme!
"item.read"
menuPhotos: [MenuPhoto!]!
"item.read: items temporarily not served"
stopList: [StopListEntry!]!
"store.read: whether the guest listener is on and its origin"
guestListener: GuestListener!
"report.read: spec/REPORTS.md, Restaurant"
restaurantReport(from: DateTime!, to: DateTime!, groupBy: RestaurantGroupBy!): RestaurantReport!
"report.read: spec/REPORTS.md, Service charges; the payroll basis apart from tips"
serviceChargeReport(from: DateTime!, to: DateTime!, groupBy: ServiceChargeGroupBy!): ServiceChargeReport!
}
enum ProposalStatus
enum ProposalStatus {
PENDING
APPROVED
REFUSED
FAILED
}
enum ProposalOrigin
enum ProposalOrigin {
ASSISTANT
MCP
}
type ProposalActor
"Who asked for a proposal."
type ProposalActor {
kind: PrincipalKind!
id: UUID!
name: String!
}
type Proposal
"A change an agent proposed, waiting for a person (spec/MCP.md)."
type Proposal {
id: UUID!
tool: String!
arguments: JSON!
summary: String!
permissions: [String!]!
origin: ProposalOrigin!
conversationId: UUID
createdBy: ProposalActor!
status: ProposalStatus!
result: JSON
error: JSON
reason: String
createdAt: DateTime!
resolvedBy: UUID
resolvedAt: DateTime
version: Int64!
}
type ProposalPage
type ProposalPage {
items: [Proposal!]!
next: String
}
enum AssistantProviderKind
enum AssistantProviderKind {
OPENAI
ANTHROPIC
GEMINI
OPENAI_COMPATIBLE
}
type AssistantProvider
type AssistantProvider {
kind: AssistantProviderKind!
model: String!
"From the environment beside the key (spec/ASSISTANT.md, Settings)"
baseUrl: String
"The key's name, never the key."
key: String!
}
type AssistantSettings
type AssistantSettings {
enabled: Boolean!
provider: AssistantProvider
shareRows: Boolean!
contextLimit: Int!
compactAt: Int!
resultBudget: Int!
"Cents per million tokens: input, cached_input, cache_write, output."
prices: JSON
keyPresent: Boolean!
version: Int64!
}
enum ChangeRequestStatus
enum ChangeRequestStatus {
PENDING
APPROVED
REFUSED
}
enum ChangeRequestKind
enum ChangeRequestKind {
ITEM
PRICE
}
type ChangeRequest
"A store's request to its hub for a hub-owned change (spec/SYNC.md)."
type ChangeRequest {
id: UUID!
storeId: UUID!
kind: ChangeRequestKind!
recordId: UUID!
proposed: JSON!
reason: String!
status: ChangeRequestStatus!
resolutionReason: String
createdBy: UUID!
createdAt: DateTime!
resolvedBy: UUID
resolvedAt: DateTime
version: Int64!
}
type ChangeRequestPage
type ChangeRequestPage {
items: [ChangeRequest!]!
next: String
}
enum PrincipalKind
enum PrincipalKind {
EMPLOYEE
DEVICE
INTEGRATION
}
type Principal
type Principal {
kind: PrincipalKind!
id: UUID!
displayName: String!
}
type EffectivePermission
type EffectivePermission {
code: String!
limit: Int64
}
type Me
type Me {
principal: Principal!
storeId: UUID!
workplaceId: UUID
permissions: [EffectivePermission!]!
}
enum UnitSystem
enum UnitSystem {
METRIC
US_CUSTOMARY
}
enum TaxMode
enum TaxMode {
EXCLUSIVE
INCLUSIVE
}
enum BaseUnit
enum BaseUnit {
EACH
KG
LB
L
US_GAL
M
FT
}
type BarcodeTemplate
type BarcodeTemplate {
pattern: String!
weightUnit: BaseUnit
weightDecimals: Int
}
type Store
type Store {
id: UUID!
code: String!
name: JSON!
country: String!
"`none` or `us`: the country pack whose rules the store follows (spec/COUNTRY_PACKS.md)."
countryPack: String!
currency: String!
currencyExponent: Int!
unitSystem: UnitSystem!
taxMode: TaxMode!
timezone: String!
receiptLanguage: String!
holdTtlSeconds: Int!
cashRoundingMinor: Int64
barcodeTemplates: [BarcodeTemplate!]!
registerShare: Int
"The store's switch for the private network (spec/NETWORK.md); null follows the organization."
networkEnabled: Boolean
"The store's /24 block in the organization's subnet; null outside a chain."
networkBlock: Int
"Lines carry the codes of their item's tax category (spec/TAX.md)."
taxByCategory: Boolean!
profile: StoreProfile!
pseLimits: PseLimits!
"A unit a GS1 code shows expired: refused, or sold with a senior's approval (spec/BARCODES.md)."
expiredSale: ExpiredSale!
"Whether receipts of the open shift may be voided (spec/FISCAL.md)."
voidsAllowed: Boolean!
"The local time after which the day's expiry rules run (spec/PRICING.md)."
expiryRunAt: String!
"How long a restaurant check's stock holds live after its last change or renewal (spec/RESTAURANT.md)."
checkHoldMinutes: Int!
"When a table counts as seated long, in whole minutes from its oldest open or billed check's opening (spec/RESTAURANT.md, The floor)."
seatedLongMinutes: Int!
"The store's service charges, at most three, in the order they apply (spec/API.md, Service charges)."
serviceCharges: [ServiceCharge!]!
"Whether the store's back offices install a ready update by themselves (spec/RELEASES.md, Installing)."
backOfficeUpdates: BackOfficeUpdates!
"The oldest version of each app the store's node serves, set by a person; none named by default (spec/RELEASES.md, The store's minimum)."
minAppVersions: MinAppVersions!
version: Int64!
}
enum BackOfficeUpdates
enum BackOfficeUpdates {
AUTOMATIC
ASK
}
type MinAppVersions
"Each app's minimum version; null where the store names none. An app below its minimum is refused 426 app_update_required (spec/RELEASES.md, Refused per request)."
type MinAppVersions {
"The register's, the handheld's and the kitchen display's."
cashier: String
"The back office's and the console's."
manager: String
"The device gateway's."
gateway: String
}
enum ServiceChargeBase
enum ServiceChargeBase {
AFTER_DISCOUNTS
BEFORE_DISCOUNTS
}
enum ServiceChargeTaxKind
enum ServiceChargeTaxKind {
"Taxed by the codes it names; none for an untaxed charge."
CODES
"Each line's share is taxed as the line is."
FOLLOW_LINES
}
type ServiceChargeTax
type ServiceChargeTax {
kind: ServiceChargeTaxKind!
"The store's tax codes; empty for an untaxed charge or one that follows the lines."
codes: [String!]!
}
type ServiceCharge
"One of a store's service charges; never a tip (spec/API.md, Service charges)."
type ServiceCharge {
id: String!
"Localized, 1 to 40 characters each."
label: JSON!
ratePpm: Int!
"The party size from which it applies to a check; null for every check and sale."
minCovers: Int
orderTypes: [OrderType!]!
base: ServiceChargeBase!
tax: ServiceChargeTax!
"The part the business pays its staff, printed and reported for payroll."
toStaffPpm: Int!
"The store's words, localized, on the pre-bill, the receipt and the guest menu."
notice: JSON!
}
enum ServiceChargeHow
enum ServiceChargeHow {
"Its conditions hold."
AUTOMATIC
ADDED
"Removed by hand with a reason."
REMOVED
}
type ServiceChargePart
"A charge as one item line a fiscal back end gets (spec/FISCAL.md)."
type ServiceChargePart {
taxCodes: [String!]!
amountMinor: Int64!
}
type ReceiptServiceCharge
"A service charge as the receipt keeps it, as it was at the sale."
type ReceiptServiceCharge {
id: String!
"In the receipt language."
label: String!
notice: String!
ratePpm: Int!
how: ServiceChargeHow!
reason: String
base: ServiceChargeBase!
"What the rate was applied to; null on a refund."
baseMinor: Int64
amountMinor: Int64!
taxMinor: Int64!
parts: [ServiceChargePart!]!
toStaffPpm: Int!
"Fixed at the sale (spec/REPORTS.md, Service charges)."
toStaffMinor: Int64!
}
type CheckServiceCharge
"A service charge a check carries (spec/RESTAURANT.md, Service charges)."
type CheckServiceCharge {
id: String!
how: ServiceChargeHow!
reason: String
by: UUID
approvedBy: UUID
at: DateTime
}
type CheckTotalsServiceCharge
"A charge that applies to a check, figured on its lines."
type CheckTotalsServiceCharge {
id: String!
how: ServiceChargeHow!
baseMinor: Int64!
amountMinor: Int64!
taxMinor: Int64!
}
enum ExpiredSale
enum ExpiredSale {
REFUSE
APPROVE
}
enum StoreProfile
enum StoreProfile {
GENERAL
SUPERMARKET
GROCERY
PHARMACY
COFFEE_SHOP
PIZZERIA
RESTAURANT
}
type PseLimits
type PseLimits {
dailyMg: Int!
windowMg: Int!
windowDays: Int!
}
enum Jurisdiction
enum Jurisdiction {
STATE
COUNTY
CITY
DISTRICT
}
enum TaxCategory
enum TaxCategory {
GENERAL
GROCERY
PREPARED_FOOD
CANDY
SOFT_DRINK
DIETARY_SUPPLEMENT
CLOTHING
OTC_DRUG
RX_DRUG
MEDICAL_EQUIPMENT
ALCOHOL
TOBACCO
NONTAXABLE
}
type TaxHoliday
type TaxHoliday {
from: Date!
to: Date!
categories: [TaxCategory!]!
maxUnitPriceMinor: Int64
}
type TaxRate
type TaxRate {
code: String!
ratePpm: Int!
name: JSON!
jurisdiction: Jurisdiction
"Null for every category."
categories: [TaxCategory!]
exemptCategories: [TaxCategory!]!
holidays: [TaxHoliday!]!
}
type Deposit
type Deposit {
code: String!
name: JSON!
amountMinor: Int64!
taxable: Boolean!
}
type TaxReportCode
type TaxReportCode {
code: String!
name: JSON!
jurisdiction: Jurisdiction
baseMinor: Int64!
taxMinor: Int64!
}
type TaxReport
type TaxReport {
from: Date!
to: Date!
codes: [TaxReportCode!]!
netSalesMinor: Int64!
nontaxableSalesMinor: Int64!
snapMinor: Int64!
depositMinor: Int64!
taxMinor: Int64!
}
enum KitchenTicketList
enum KitchenTicketList {
OPEN
READY
}
enum KitchenTicketState
enum KitchenTicketState {
NEW
STARTED
READY
CANCELED
}
type KitchenTicketLine
type KitchenTicketLine {
quantityMilli: Int64!
name: String!
options: [String!]!
"The check's line; null for a receipt's ticket."
lineNo: Int
"The check line's seat, 0 shared; null for a receipt's ticket."
seat: Int
"Voided after it was sent: shown struck through."
voided: Boolean!
}
enum OrderLabelKind
enum OrderLabelKind {
TABLE
TAB
}
enum KitchenTicketKind
enum KitchenTicketKind {
ORDER
"The voided lines of a check: acknowledged with a bump, never started."
CANCEL
}
type KitchenTicket
type KitchenTicket {
id: UUID!
kind: KitchenTicketKind!
"The receipt; null for a check's ticket."
receiptId: UUID
receiptNumber: Int64
"The restaurant check (spec/RESTAURANT.md); null for a receipt's ticket."
checkId: UUID
checkNumber: Int64
course: Int
waiterId: UUID
waiterName: String
"The ticket a cancel ticket cancels lines of."
cancelsTicketId: UUID
station: String!
state: KitchenTicketState!
orderType: OrderType
orderLabel: String
"Whether a check's orderLabel names a table or a tab; null for a receipt's ticket."
orderLabelKind: OrderLabelKind
lines: [KitchenTicketLine!]!
createdAt: DateTime!
startedAt: DateTime
readyAt: DateTime
version: Int64!
}
enum PseIdType
enum PseIdType {
DRIVER_LICENSE
STATE_ID
PASSPORT
MILITARY_ID
OTHER
}
type PsePurchaser
type PsePurchaser {
name: String!
address: String!
dateOfBirth: Date!
idType: PseIdType!
idState: String!
idNumber: String!
signed: Boolean!
}
type PseLogLine
type PseLogLine {
itemId: UUID!
name: String!
quantityMilli: Int64!
baseMg: Int!
}
type PseLogEntry
type PseLogEntry {
id: UUID!
receiptId: UUID!
receiptNumber: Int64!
businessDate: Date!
createdAt: DateTime!
employeeId: UUID!
lines: [PseLogLine!]!
baseMg: Int!
purchaser: PsePurchaser!
}
type PseLogPage
type PseLogPage {
items: [PseLogEntry!]!
next: String
}
enum DeliveryChannel
enum DeliveryChannel {
EMAIL
SMS
}
enum DeliveryStatus
enum DeliveryStatus {
QUEUED
SENT
FAILED
}
type ReceiptDelivery
type ReceiptDelivery {
id: UUID!
channel: DeliveryChannel!
"Masked: the address itself is never stored."
toMasked: String!
status: DeliveryStatus!
createdAt: DateTime!
sentAt: DateTime
error: String
}
enum LicenseStatus
enum LicenseStatus {
NONE
VALID
GRACE
EXPIRED
INVALID
}
type License
type License {
status: LicenseStatus!
tier: String!
org: String
orgName: String
modules: [String!]!
stores: Int!
registers: Int!
expires: Date
usage: LicenseUsage!
registerShare: Int
"The node's own organization id, the one a key must name (spec/LICENSE.md, Getting a key)"
organizationId: UUID
"The clock is more than 24 hours behind the latest time the node has seen (spec/LICENSE.md, Verification)"
clockBehind: Boolean
}
type LicenseUsage
type LicenseUsage {
stores: Int!
registers: Int!
"At a store, its tables; null at the hub (spec/LICENSE.md, Usage)."
tables: Int
"At a store, its open and billed tabs; null at the hub."
openTabs: Int
"3, the places each store has, when the key lacks the restaurant module; null (no limit) when it has it."
tableLimit: Int
}
enum ItemKind
enum ItemKind {
PIECE
WEIGHED
VARIABLE_WEIGHT
SERVICE
"Takes its components' stock at the sale (spec/STOCK.md, Kits)."
KIT
"Sells stored value (spec/LOYALTY.md, Gift cards)."
GIFT_CARD
}
enum StockPolicy
enum StockPolicy {
FIFO
FEFO
}
type Barcode
type Barcode {
barcode: String!
packQuantityMilli: Int64!
}
type StorePrice
type StorePrice {
priceMinor: Int64!
currency: String!
}
type Item
type Item {
id: UUID!
sku: String!
plu: String
name: JSON!
kind: ItemKind!
baseUnit: BaseUnit!
taxCodes: [String!]!
groupId: UUID
profile: String
attributes: JSON!
stockPolicy: StockPolicy!
discountable: Boolean!
active: Boolean!
barcodes: [Barcode!]!
modifierGroups: [ModifierGroup!]!
"The item's tags in the order of their ids."
tags: [ItemTag!]!
price: StorePrice
"On a parent, its options in order (spec/VARIANTS.md); empty otherwise."
variantOptions: [VariantOption!]!
"On a variant, its parent."
parentId: UUID
"On a variant, {option code: value code}."
variantValues: JSON
serialTracked: Boolean!
"A kit's components (spec/STOCK.md, Kits), each taxed as the kit is; empty otherwise."
kitComponents: [Component!]!
version: Int64!
}
type Component
"A kit's or a recipe's component."
type Component {
itemId: UUID!
quantityMilli: Int64!
}
type VariantValue
type VariantValue {
code: String!
name: JSON!
}
type VariantOption
type VariantOption {
code: String!
name: JSON!
values: [VariantValue!]!
}
enum ItemKindOf
enum ItemKindOf {
PARENT
VARIANT
PLAIN
}
enum SerialState
enum SerialState {
IN_STOCK
SOLD
WRITTEN_OFF
}
enum SerialEventKind
enum SerialEventKind {
RECEIVED
SOLD
RETURNED
VOIDED
WRITTEN_OFF
}
type SerialEvent
type SerialEvent {
event: SerialEventKind!
at: DateTime!
documentId: UUID
receiptId: UUID
overridden: Boolean!
conflict: Boolean!
}
type SerialRecord
type SerialRecord {
itemId: UUID!
serial: String!
state: SerialState!
history: [SerialEvent!]!
}
enum TaxProviderKind
enum TaxProviderKind {
AVALARA
TAXJAR
}
enum TaxSyncState
enum TaxSyncState {
NEVER
OK
FAILED
}
enum TaxSyncError
enum TaxSyncError {
KEY_MISSING
PROVIDER_UNREACHABLE
PROVIDER_REFUSED
BAD_ANSWER
}
type TaxProviderAddress
type TaxProviderAddress {
line1: String!
city: String!
region: String!
postalCode: String!
}
type TaxRateChange
type TaxRateChange {
code: String!
fromPpm: Int!
toPpm: Int!
}
type TaxProviderStatus
type TaxProviderStatus {
state: TaxSyncState!
lastAttemptAt: DateTime
lastSuccessAt: DateTime
error: TaxSyncError
changed: [TaxRateChange!]!
}
type TaxProvider
"spec/TAX.md, Rates from a provider: null provider is off."
type TaxProvider {
provider: TaxProviderKind
accountId: String
keyName: String
keyPresent: Boolean!
sandbox: Boolean!
address: TaxProviderAddress
"{jurisdiction: tax code}"
mapping: JSON!
status: TaxProviderStatus!
}
type ModifierOption
type ModifierOption {
id: String!
name: JSON!
priceDeltaMinor: Int64!
}
type ModifierGroup
type ModifierGroup {
id: String!
name: JSON!
min: Int!
max: Int!
options: [ModifierOption!]!
}
type Promotion
type Promotion {
id: UUID!
name: JSON!
active: Boolean!
startsAt: DateTime
endsAt: DateTime
itemIds: [UUID!]!
groupIds: [UUID!]!
"spec/PROMOTIONS.md: {kind: percent, rate_ppm} or {kind: quantity_break, tiers}."
rule: JSON!
version: Int64!
}
type ItemPage
type ItemPage {
items: [Item!]!
next: String
}
enum LookupSource
enum LookupSource {
BARCODE
PACK_BARCODE
VARIABLE_MEASURE
PLU
SKU
}
type Lookup
type Lookup {
item: Item!
source: LookupSource!
quantityMilli: Int64
priceMinor: Int64
}
type Group
type Group {
id: UUID!
parentId: UUID
name: JSON!
}
type Tag
"A tag of the catalog (spec/SEARCH.md)."
type Tag {
id: UUID!
name: JSON!
version: Int64!
}
enum TagSource
enum TagSource {
MANUAL
SUGGESTED
}
type ItemTag
type ItemTag {
tagId: UUID!
source: TagSource!
"The accepted suggestion's confidence, 0 to 1000; null when manual."
confidence: Int
}
enum SearchMatch
enum SearchMatch {
EXACT
SEMANTIC
}
type SearchHit
type SearchHit {
item: Item!
match: SearchMatch!
"Available quantity on a store node; null at the hub."
availableMilli: Int64
}
type SearchIndex
type SearchIndex {
id: UUID!
model: String!
dimensions: Int!
indexed: Int64!
total: Int64!
startedAt: DateTime!
readyAt: DateTime
}
type SearchIndexStatus
type SearchIndexStatus {
active: SearchIndex
building: SearchIndex
}
type SearchResult
type SearchResult {
items: [SearchHit!]!
index: SearchIndex!
}
enum SearchProviderKind
enum SearchProviderKind {
LOCAL
OPENAI_COMPATIBLE
}
type SearchProvider
type SearchProvider {
kind: SearchProviderKind!
"From the environment beside the key (spec/SEARCH.md, Settings)"
baseUrl: String
model: String
dimensions: Int
maxInputTokens: Int
"The key's name, or none; never the key."
key: String
}
type SearchSuggestionSettings
type SearchSuggestionSettings {
enabled: Boolean!
neighbors: Int!
minScore: Int!
minConfidence: Int!
}
type SearchSettings
type SearchSettings {
provider: SearchProvider!
suggestions: SearchSuggestionSettings!
keyPresent: Boolean!
version: Int64!
}
enum SuggestionKind
enum SuggestionKind {
TAG
GROUP
}
enum SuggestionStatus
enum SuggestionStatus {
OPEN
ACCEPTED
DISMISSED
}
type SuggestionResolver
type SuggestionResolver {
id: UUID!
name: String!
}
type Suggestion
"A tag or a group the node suggests for an item (spec/SEARCH.md, Suggestions)."
type Suggestion {
id: UUID!
itemId: UUID!
itemName: JSON!
kind: SuggestionKind!
targetId: UUID!
targetName: JSON!
confidence: Int!
status: SuggestionStatus!
createdAt: DateTime!
resolvedAt: DateTime
resolvedBy: SuggestionResolver
}
type SuggestionPage
type SuggestionPage {
items: [Suggestion!]!
next: String
}
type Batch
type Batch {
id: UUID!
itemId: UUID!
lot: String
expiresOn: Date
receivedAt: DateTime!
unitCostMinor: Int64!
costCurrency: String!
balanceMilli: Int64!
needsReview: Boolean!
"The batch's own sale price; null sells at the store price (spec/PRICING.md)."
priceMinor: Int64
}
type Stock
type Stock {
itemId: UUID!
baseUnit: BaseUnit!
onHandMilli: Int64!
heldMilli: Int64!
availableMilli: Int64!
batches: [Batch!]!
"A kit's stock, from its components."
kit: Boolean!
}
type Hold
type Hold {
id: UUID!
itemId: UUID!
quantityMilli: Int64!
workplaceId: UUID
expiresAt: DateTime!
"The price split of the quantity held, when batches carry prices."
split: [PriceSplitLine!]!
}
enum DocumentKind
enum DocumentKind {
RECEIVING
WRITE_OFF
INVENTORY
PRICE_CHANGE
TRANSFER_OUT
TRANSFER_IN
PURCHASE_ORDER
SUPPLIER_RETURN
REGRADE
PRODUCTION
}
enum DocumentStatus
enum DocumentStatus {
DRAFT
POSTED
CANCELED
}
enum ListOrder
"ASC oldest first, DESC newest first."
enum ListOrder {
ASC
DESC
}
type DocumentLine
type DocumentLine {
lineNo: Int!
itemId: UUID!
quantityMilli: Int64
countedMilli: Int64
bookMilli: Int64
unitCostMinor: Int64
retailPriceMinor: Int64
lot: String
expiresOn: Date
batchId: UUID
reason: String
"Price change: the new store price."
priceMinor: Int64
"Price change, after posting: the price it replaced."
previousPriceMinor: Int64
"A serial-tracked item's serials (spec/VARIANTS.md)."
serials: [String!]!
"Receiving: the sale price of the batch the line makes."
batchPriceMinor: Int64
"Re-grade: the item the quantity really is."
toItemId: UUID
"Transfer receiving: the transfer's line it receives."
transferLineNo: Int
"A posted transfer_out: the batches the line took."
shipped: [ShippedBatch!]!
"A posted transfer_in or re-grade: the batches the line made."
made: [MovedBatch!]!
shortageMilli: Int64
surplusMilli: Int64
shortageCostMinor: Int64
surplusCostMinor: Int64
"Purchase order: received so far and still due."
receivedMilli: Int64
dueMilli: Int64
"Once posted: the line's cost."
costMinor: Int64
}
type ShippedBatch
type ShippedBatch {
batchId: UUID!
quantityMilli: Int64!
unitCostMinor: Int64!
costCurrency: String!
lot: String
expiresOn: Date
}
type MovedBatch
type MovedBatch {
batchId: UUID!
fromBatchId: UUID
quantityMilli: Int64!
unitCostMinor: Int64!
}
type ProductionOutput
type ProductionOutput {
itemId: UUID!
quantityMilli: Int64!
lot: String
expiresOn: Date
batchId: UUID
unitCostMinor: Int64
}
enum DocumentOrigin
enum DocumentOrigin {
EXPIRY_RULE
}
enum OrderState
enum OrderState {
DRAFT
SENT
PARTLY_RECEIVED
RECEIVED
CLOSED
CANCELED
}
enum TransferState
enum TransferState {
DRAFT
IN_TRANSIT
RECEIVED
CANCELED
}
enum TransferDirection
enum TransferDirection {
OUTGOING
INCOMING
}
type Document
type Document {
id: UUID!
kind: DocumentKind!
status: DocumentStatus!
number: Int64!
comment: String
createdAt: DateTime!
createdBy: UUID!
postedAt: DateTime
postedBy: UUID
lines: [DocumentLine!]!
version: Int64!
"Price change: why; null for other kinds."
reason: PriceChangeReason
"Made by the expiry run; null when a person made it."
origin: DocumentOrigin
supplierId: UUID
expectedOn: Date
orderState: OrderState
purchaseOrderId: UUID
receivingId: UUID
fromStoreId: UUID
toStoreId: UUID
transferId: UUID
transferState: TransferState
recipeId: UUID
plannedMilli: Int64
output: ProductionOutput
lossMilli: Int64
yieldPpm: Int64
costMinor: Int64
}
enum PriceChangeReason
enum PriceChangeReason {
REPRICING
MARKDOWN
}
type DocumentPage
type DocumentPage {
items: [Document!]!
next: String
}
enum ShiftStatus
enum ShiftStatus {
OPEN
CLOSED
}
type Shift
type Shift {
id: UUID!
workplaceId: UUID!
cashierId: UUID!
number: Int64!
status: ShiftStatus!
openedAt: DateTime!
closedAt: DateTime
openingCashMinor: Int64!
currency: String!
"The fiscal shift's Z report, once closed with one (spec/FISCAL.md)."
fiscal: ShiftFiscal
}
type ShiftFiscal
type ShiftFiscal {
shiftNumber: Int64!
zNumber: Int64!
zAt: DateTime!
salesMinor: Int64!
refundsMinor: Int64!
taxes: [ReceiptTax!]!
tenders: [FiscalTenderTotal!]!
}
type FiscalTenderTotal
type FiscalTenderTotal {
tender: String!
amountMinor: Int64!
}
enum FiscalBackendKind
enum FiscalBackendKind {
DEVICE
SIGNER
SOFTWARE
SERVICE
}
type ReceiptFiscal
"The fiscal document a back end gave a receipt (spec/FISCAL.md)."
type ReceiptFiscal {
kind: FiscalBackendKind!
driver: String!
deviceSerial: String
registrationNumber: String
shiftNumber: Int64!
documentNumber: Int64!
sign: String!
qr: String
at: DateTime!
extra: JSON!
}
type ShiftPage
type ShiftPage {
items: [Shift!]!
next: String
}
enum Tender
enum Tender {
CASH
CARD
EBT_SNAP
EBT_CASH
GIFT_CARD
"A preorder's online payment, captured at hand-over (spec/PAYMENTS_ONLINE.md)."
ONLINE
OTHER
}
type TenderTotal
type TenderTotal {
tender: Tender!
amountMinor: Int64!
}
type CashTotals
type CashTotals {
openingMinor: Int64!
depositsMinor: Int64!
payoutsMinor: Int64!
pickupsMinor: Int64!
salesMinor: Int64!
refundsMinor: Int64!
expectedMinor: Int64!
}
type ShiftTotals
type ShiftTotals {
saleCount: Int!
refundCount: Int!
voidCount: Int!
salesMinor: Int64!
refundsMinor: Int64!
netSalesMinor: Int64!
taxMinor: Int64!
discountsMinor: Int64!
tipsMinor: Int64!
"The sales' service charges without their tax, less what refunds took back; never in tipsMinor."
serviceChargesMinor: Int64!
payments: [TenderTotal!]!
cash: CashTotals!
"The cashier the totals are for; null for the whole shift."
cashierId: UUID
"Per tax code, the base and the tax of sales minus refunds."
taxes: [ReceiptTax!]!
"The store's open and billed restaurant checks when the totals were read (spec/RESTAURANT.md)."
openChecks: OpenChecks!
}
enum ReceiptKind
enum ReceiptKind {
SALE
REFUND
VOID
}
type ReceiptLineBatch
type ReceiptLineBatch {
batchId: UUID!
quantityMilli: Int64!
"A kit line's component."
itemId: UUID
}
type ReceiptLine
type ReceiptLine {
lineNo: Int!
itemId: UUID!
name: String!
quantityMilli: Int64!
baseUnit: BaseUnit!
unitPriceMinor: Int64!
gross: Int64!
lineDiscount: Int64!
receiptDiscount: Int64!
net: Int64!
tax: Int64!
"The container deposit (spec/TAX.md); 0 without one."
deposit: Int64!
"What SNAP paid of the line; 0 without SNAP."
snap: Int64!
batches: [ReceiptLineBatch!]!
promotionId: UUID
modifiers: [ReceiptLineModifier!]!
"A serial-tracked item's serials (spec/VARIANTS.md)."
serials: [String!]!
"The lot a GS1 code named (spec/BARCODES.md)."
lot: String
"The marking code a GS1 code carried, as scanned."
markingCode: String
"The employee who sold the line (spec/REPORTS.md)."
sellerId: UUID
"The loyalty steps' parts of the line's discounts (spec/LOYALTY.md)."
stampDiscount: Int64!
cardDiscount: Int64!
voucherDiscount: Int64!
pointsSpent: Int64!
pointsEarned: Int64!
"The employee bonus fixed at the sale."
bonusMinor: Int64!
bonusEmployeeId: UUID
bonusRuleId: UUID
"The line's share of the partner's commission."
commissionMinor: Int64!
giftCardNumberMasked: String
"The restaurant check's line it paid; null without a check."
checkLineNo: Int
"The line's share of each service charge, with the tax on that share (not in tax)."
serviceCharges: [ServiceChargeShare!]!
}
type ReceiptLineModifier
type ReceiptLineModifier {
groupId: String!
optionId: String!
name: String!
priceDeltaMinor: Int64!
}
enum OrderType
enum OrderType {
DINE_IN
TAKE_OUT
DELIVERY
}
type ReceiptTax
type ReceiptTax {
code: String!
base: Int64!
amount: Int64!
}
type Payment
type Payment {
id: UUID!
tender: Tender!
amountMinor: Int64!
provider: String
providerRef: String
cardBrand: String
cardLast4: String
authorizationCode: String
}
type Receipt
type Receipt {
id: UUID!
number: Int64!
kind: ReceiptKind!
originalReceiptId: UUID
shiftId: UUID!
workplaceId: UUID!
cashierId: UUID!
currency: String!
createdAt: DateTime!
lines: [ReceiptLine!]!
taxes: [ReceiptTax!]!
grossTotal: Int64!
discountTotal: Int64!
netTotal: Int64!
taxTotal: Int64!
total: Int64!
cashDue: Int64
payments: [Payment!]!
changeMinor: Int64!
needsReview: Boolean!
orderType: OrderType
tipMinor: Int64!
depositTotal: Int64!
snapTotal: Int64!
"FSA- and HSA-eligible lines' net and tax (spec/PHARMACY.md)."
healthcareTotal: Int64!
rxTotal: Int64!
orderLabel: String
deliveries: [ReceiptDelivery!]!
"Closed offline: the serials a sale online would have refused."
serialConflicts: [String!]!
"The fiscal document; null without a fiscal back end (spec/FISCAL.md)."
fiscal: ReceiptFiscal
customerId: UUID
"What the loyalty steps did (spec/LOYALTY.md)."
loyalty: ReceiptLoyalty
"The partner and rate at the sale."
partner: ReceiptPartner
"The restaurant check it paid lines of (spec/RESTAURANT.md); null otherwise."
check: ReceiptCheck
"Every service charge it carries, removed ones included (spec/API.md, Service charges)."
serviceCharges: [ReceiptServiceCharge!]!
"The charges that apply, inside total."
serviceChargeTotal: Int64!
}
type ReceiptLoyalty
type ReceiptLoyalty {
cardNumberMasked: String
unresolvedCard: Boolean!
pointsSpent: Int64!
pointsValueMinor: Int64!
pointsEarned: Int64!
stamps: [ReceiptStamps!]!
voucherId: UUID
voucherCode: String
}
type ReceiptStamps
type ReceiptStamps {
programId: UUID!
earned: Int64!
rewards: Int64!
redeemed: Int64!
}
type ReceiptPartner
type ReceiptPartner {
partnerId: UUID!
code: String!
commissionPpm: Int!
commissionMinor: Int64!
}
type ReceiptPage
type ReceiptPage {
items: [Receipt!]!
next: String
}
enum Scope
enum Scope {
NETWORK
STORE
WORKPLACE
}
type Assignment
type Assignment {
id: UUID!
role: String!
scope: Scope!
storeId: UUID
workplaceId: UUID
}
type Employee
type Employee {
id: UUID!
login: String!
displayName: String!
language: String!
active: Boolean!
assignments: [Assignment!]!
version: Int64!
}
type EmployeePage
type EmployeePage {
items: [Employee!]!
next: String
}
type Role
type Role {
code: String!
name: JSON!
scope: Scope!
permissions: [String!]!
limits: JSON!
builtin: Boolean!
}
enum SalesGroupBy
enum SalesGroupBy {
DAY
EMPLOYEE
ITEM
GROUP
TENDER
}
type SalesReportRow
"spec/REPORTS.md, Sales: rows by tender carry only amount."
type SalesReportRow {
"The local date, employee id, item id, group id (null without a group) or tender."
key: String
name: String
sales: Int
refunds: Int
quantityMilli: Int64
gross: Int64
discounts: Int64
net: Int64
tax: Int64
revenue: Int64
cost: Int64
margin: Int64
marginPpm: Int64
tips: Int64
"The receipts' service charges without their tax, by day or employee."
serviceCharges: Int64
amount: Int64
}
type SalesTotals
type SalesTotals {
sales: Int
refunds: Int
quantityMilli: Int64
gross: Int64
discounts: Int64
net: Int64
tax: Int64
revenue: Int64
cost: Int64
margin: Int64
marginPpm: Int64
tips: Int64
"The receipts' service charges without their tax, by day or employee."
serviceCharges: Int64
amount: Int64
}
type SalesReport
type SalesReport {
groupBy: SalesGroupBy!
currency: String!
rows: [SalesReportRow!]!
totals: SalesTotals!
}
type StockReportRow
type StockReportRow {
itemId: UUID!
sku: String!
name: JSON!
baseUnit: BaseUnit!
groupId: UUID
onHandMilli: Int64!
heldMilli: Int64!
availableMilli: Int64!
valueMinor: Int64!
batches: Int!
nearestExpiry: Date
}
type StockReportPage
type StockReportPage {
items: [StockReportRow!]!
next: String
totalValueMinor: Int64!
}
enum MovementKind
enum MovementKind {
RECEIVING
SALE
REFUND
VOID
WRITE_OFF
INVENTORY_SURPLUS
INVENTORY_SHORTAGE
TRANSFER_OUT
TRANSFER_IN
SUPPLIER_RETURN
REGRADE_OUT
REGRADE_IN
PRODUCTION_OUT
PRODUCTION_IN
}
type Movement
type Movement {
at: DateTime!
itemId: UUID!
batchId: UUID!
quantityMilli: Int64!
kind: MovementKind!
sourceId: UUID!
sourceNumber: Int64!
needsReview: Boolean!
}
type MovementPage
type MovementPage {
items: [Movement!]!
next: String
}
input PriceProposalInput
input PriceProposalInput {
itemIds: [UUID!]
groupId: UUID
markupPpm: Int!
roundToMinor: Int! = 1
endingMinor: Int
endingBase: Int
}
type PriceProposal
type PriceProposal {
itemId: UUID!
costMinor: Int64
priceMinor: Int64
proposedMinor: Int64
}
enum TunnelState
enum TunnelState {
OFF
UP
DOWN
}
type StoreNetworkState
type StoreNetworkState {
enabled: Boolean!
address: String
hubAddress: String
endpoint: String
tunnelState: TunnelState!
lastHandshakeAt: DateTime
publicKey: String
devices: [DevicePeer!]!
}
type DevicePeer
type DevicePeer {
deviceId: UUID!
address: String!
publicKey: String!
lastHandshakeAt: DateTime
}
type Transfer
"A transfer with both stores' documents."
type Transfer {
id: UUID!
fromStoreId: UUID!
toStoreId: UUID!
state: TransferState!
transfer: Document!
receiving: Document
}
type TransferPage
type TransferPage {
items: [Transfer!]!
next: String
}
type InTransitLine
type InTransitLine {
transferId: UUID!
number: Int64!
fromStoreId: UUID!
toStoreId: UUID!
shippedAt: DateTime!
lineNo: Int!
itemId: UUID!
quantityMilli: Int64!
costMinor: Int64!
costCurrency: String!
}
type Supplier
type Supplier {
id: UUID!
code: String!
name: String!
comment: String
active: Boolean!
version: Int64!
}
type Recipe
type Recipe {
id: UUID!
productItemId: UUID!
yieldMilli: Int64!
components: [Component!]!
active: Boolean!
version: Int64!
}
type PriceSplitLine
type PriceSplitLine {
unitPriceMinor: Int64!
quantityMilli: Int64!
batches: [ReceiptLineBatch!]!
}
type PriceSplit
type PriceSplit {
itemId: UUID!
lines: [PriceSplitLine!]!
}
type ExpiryStep
type ExpiryStep {
daysBefore: Int!
ratePpm: Int!
}
type ExpiryRule
type ExpiryRule {
id: UUID!
itemIds: [UUID!]!
groupIds: [UUID!]!
markdowns: [ExpiryStep!]!
autoPost: Boolean!
writeOffExpired: Boolean!
roundToMinor: Int64!
endingMinor: Int64
endingBase: Int64
active: Boolean!
version: Int64!
}
enum LoyaltyKind
enum LoyaltyKind {
DISCOUNT
BONUS
STAMPS
}
type EarnRate
type EarnRate {
"Null for every group not listed."
groupId: UUID
ratePpm: Int!
}
type PointValue
type PointValue {
"Null for every other store."
storeId: UUID
valueMinor: Int64!
}
type LoyaltyProgram
type LoyaltyProgram {
id: UUID!
name: JSON!
kind: LoyaltyKind!
active: Boolean!
ratePpm: Int
earn: [EarnRate!]!
pointValues: [PointValue!]!
maxSpendPpm: Int
stampsPerReward: Int
itemIds: [UUID!]!
groupIds: [UUID!]!
excludedGroupIds: [UUID!]!
version: Int64!
}
type CustomerCard
type CustomerCard {
programId: UUID!
numberMasked: String!
}
enum ConsentSource
enum ConsentSource {
REGISTER
BACK_OFFICE
CUSTOMER_APP
IMPORT
}
type CustomerConsent
type CustomerConsent {
at: DateTime!
source: ConsentSource!
termsVersion: String!
}
type CustomerMarketing
type CustomerMarketing {
allowed: Boolean!
at: DateTime
}
type Customer
"A customer, masked: the phone and e-mail are never read back (spec/LOYALTY.md)."
type Customer {
id: UUID!
name: String
phoneMasked: String
emailMasked: String
cards: [CustomerCard!]!
consent: CustomerConsent!
marketing: CustomerMarketing!
deletedAt: DateTime
createdAt: DateTime!
version: Int64!
}
type CustomerPage
type CustomerPage {
items: [Customer!]!
next: String
}
type PointsBalance
type PointsBalance {
programId: UUID!
balance: Int64!
available: Int64!
pointValueMinor: Int64!
}
type StampsBalance
type StampsBalance {
programId: UUID!
balance: Int64!
available: Int64!
stampsPerReward: Int!
}
type CustomerBalances
type CustomerBalances {
customerId: UUID!
points: [PointsBalance!]!
stamps: [StampsBalance!]!
}
enum AccountKind
enum AccountKind {
POINTS
STAMPS
GIFT_CARD
VOUCHER
}
enum LedgerEntryKind
enum LedgerEntryKind {
POINTS_EARNED
POINTS_SPENT
POINTS_EARNED_REVERSED
POINTS_SPENT_RETURNED
STAMPS_EARNED
STAMPS_REDEEMED
STAMPS_REVERSED
GIFT_CARD_LOADED
GIFT_CARD_SPENT
GIFT_CARD_REFUNDED
GIFT_CARD_UNLOADED
VOUCHER_USED
VOUCHER_RETURNED
ADJUSTMENT
}
type LedgerEntry
type LedgerEntry {
id: UUID!
accountKind: AccountKind!
accountId: UUID!
programId: UUID
kind: LedgerEntryKind!
amount: Int64!
receiptId: UUID
holdId: UUID
storeId: UUID!
reason: String
at: DateTime!
}
type LedgerPage
type LedgerPage {
items: [LedgerEntry!]!
next: String
}
enum BalanceHoldStatus
enum BalanceHoldStatus {
HELD
COMMITTED
SETTLED
EXPIRED
RELEASED
ORPHANED
}
type BalanceHold
type BalanceHold {
id: UUID!
accountKind: AccountKind!
accountId: UUID!
programId: UUID
amount: Int64!
status: BalanceHoldStatus!
expiresAt: DateTime
storeId: UUID!
receiptId: UUID
createdAt: DateTime!
committedAt: DateTime
}
type BalanceHoldPage
type BalanceHoldPage {
items: [BalanceHold!]!
next: String
}
type Voucher
"A voucher or coupon; rule is PROMOTIONS.md's shape or {kind: amount, amount_minor} (spec/LOYALTY.md)."
type Voucher {
id: UUID!
code: String!
name: JSON
rule: JSON!
itemIds: [UUID!]!
groupIds: [UUID!]!
minSpendMinor: Int64!
startsAt: DateTime
endsAt: DateTime
"Null: a coupon, used any number of times."
maxUses: Int
customerId: UUID
uses: Int64!
active: Boolean!
version: Int64!
}
type VoucherPage
type VoucherPage {
items: [Voucher!]!
next: String
}
enum VoucherUnusable
enum VoucherUnusable {
INACTIVE
NOT_STARTED
ENDED
USED_UP
OTHER_CUSTOMER
}
type VoucherCheck
type VoucherCheck {
voucher: Voucher!
remainingUses: Int64
usable: Boolean!
reason: VoucherUnusable
}
enum GiftCardStatus
enum GiftCardStatus {
ACTIVE
BLOCKED
}
type GiftCard
"A gift card: only the number's mask; the owner finds a card by the number's keyed hash, which no answer carries (spec/LOYALTY.md, Gift card numbers)."
type GiftCard {
id: UUID!
numberMasked: String!
currency: String!
status: GiftCardStatus!
hasPin: Boolean!
"The issue or import that made the card."
batchId: UUID!
"The owner's; null in a replicated copy."
balanceMinor: Int64
availableMinor: Int64
createdAt: DateTime!
version: Int64!
}
type GiftCardPage
type GiftCardPage {
items: [GiftCard!]!
next: String
}
type Partner
type Partner {
id: UUID!
name: String!
codes: [String!]!
commissionPpm: Int!
itemIds: [UUID!]!
groupIds: [UUID!]!
startsAt: DateTime
endsAt: DateTime
active: Boolean!
version: Int64!
}
type BonusRule
type BonusRule {
id: UUID!
name: String!
ratePpm: Int!
itemIds: [UUID!]!
groupIds: [UUID!]!
startsOn: Date
endsOn: Date
active: Boolean!
version: Int64!
}
type BonusReportRow
type BonusReportRow {
"At the hub."
storeId: UUID
employeeId: UUID!
lines: Int64!
revenueMinor: Int64!
bonusMinor: Int64!
}
type BonusTotals
type BonusTotals {
lines: Int64!
revenueMinor: Int64!
bonusMinor: Int64!
}
type BonusReport
type BonusReport {
from: DateTime!
to: DateTime!
rows: [BonusReportRow!]!
totals: BonusTotals!
}
type PartnerReportRow
type PartnerReportRow {
"At the hub."
storeId: UUID
partnerId: UUID!
sales: Int64!
refunds: Int64!
revenueMinor: Int64!
costMinor: Int64!
marginMinor: Int64!
commissionMinor: Int64!
marginAfterCommissionMinor: Int64!
}
type PartnerTotals
type PartnerTotals {
sales: Int64!
refunds: Int64!
revenueMinor: Int64!
costMinor: Int64!
marginMinor: Int64!
commissionMinor: Int64!
marginAfterCommissionMinor: Int64!
}
type PartnerReport
type PartnerReport {
from: DateTime!
to: DateTime!
rows: [PartnerReportRow!]!
totals: PartnerTotals!
}
type StoreDirectoryEntry
"What a store of a chain knows of another store (spec/SYNC.md)."
type StoreDirectoryEntry {
id: UUID!
code: String!
name: JSON!
}
enum TableShape
enum TableShape {
RECT
CIRCLE
}
type Area
"A room of the floor (spec/RESTAURANT.md, The floor)."
type Area {
id: UUID!
name: JSON!
position: Int!
version: Int64!
}
type Table
"A table on its area's grid of whole units."
type Table {
id: UUID!
areaId: UUID!
name: String!
shape: TableShape!
x: Int!
y: Int!
w: Int!
h: Int!
"0, 90, 180 or 270 degrees, clockwise."
rotation: Int!
seats: Int!
"The QR token; null unless the caller holds floor.manage."
qrToken: String
version: Int64!
}
type FloorTable
type FloorTable {
table: Table!
"The table's open and billed checks, oldest first."
checks: [CheckSummary!]!
guestOrdersPending: Int!
"Past the store's first three tables by id without the restaurant module: no new check opens on it (spec/LICENSE.md, The restaurant's three places)."
locked: Boolean!
}
type Floor
type Floor {
areas: [Area!]!
tables: [FloorTable!]!
"Open and billed tabs, oldest first."
tabs: [CheckSummary!]!
}
enum CheckKind
enum CheckKind {
TABLE
TAB
}
enum CheckState
enum CheckState {
OPEN
BILLED
CLOSED
CANCELED
}
enum CheckListState
enum CheckListState {
"Open and billed."
ACTIVE
OPEN
BILLED
CLOSED
CANCELED
}
enum CheckLineState
enum CheckLineState {
UNSENT
SENT
VOIDED
}
enum HoldState
enum HoldState {
HELD
LAPSED
NONE
}
enum DiscountKind
enum DiscountKind {
PERCENT
AMOUNT
}
type LineDiscount
type LineDiscount {
kind: DiscountKind!
ratePpm: Int
amount: Int64
}
type CheckSummary
"A check without its lines."
type CheckSummary {
id: UUID!
number: Int64!
kind: CheckKind!
tableId: UUID
tableName: String
"A tab's name."
name: String
waiterId: UUID!
"The waiter's name as the staff list has it, as a kitchen ticket prints it."
waiterName: String!
covers: Int!
state: CheckState!
totalMinor: Int64!
openedAt: DateTime!
version: Int64!
}
type CheckLineVoid
type CheckLineVoid {
reason: String!
by: UUID!
approvedBy: UUID
at: DateTime!
}
type CheckLine
"A sale line with its seat and course."
type CheckLine {
lineNo: Int!
itemId: UUID!
name: String!
quantityMilli: Int64!
unitPriceMinor: Int64!
modifiers: [ReceiptLineModifier!]!
discounts: [LineDiscount!]!
"0 for a shared line."
seat: Int!
course: Int!
state: CheckLineState!
sentAt: DateTime
voided: CheckLineVoid
receiptId: UUID
holdState: HoldState!
sellerId: UUID
guestOrderId: UUID
addedBy: UUID!
addedAt: DateTime!
}
type CheckLineTotals
type CheckLineTotals {
lineNo: Int!
gross: Int64!
lineDiscount: Int64!
receiptDiscount: Int64!
net: Int64!
tax: Int64!
serviceCharges: [ServiceChargeShare!]!
}
type CheckTotals
"What one sale receipt of the check's lines that are not voided would be."
type CheckTotals {
lines: [CheckLineTotals!]!
taxes: [ReceiptTax!]!
grossTotal: Int64!
discountTotal: Int64!
netTotal: Int64!
depositTotal: Int64
taxTotal: Int64!
total: Int64!
pointsEarned: Int64
"The service charges that apply, judged on the check's covers and order type."
serviceCharges: [CheckTotalsServiceCharge!]!
serviceChargeTotal: Int64!
}
type Check
"An open order on a table, or a tab (spec/RESTAURANT.md, Checks)."
type Check {
id: UUID!
number: Int64!
kind: CheckKind!
tableId: UUID
tableName: String
areaId: UUID
name: String
waiterId: UUID!
covers: Int!
state: CheckState!
orderType: OrderType!
heldCourses: [Int!]!
customerId: UUID
cardNumberMasked: String
partnerCode: String
"Percentages only."
receiptDiscounts: [LineDiscount!]!
"The store's service charges it carries, each with how it came to."
serviceCharges: [CheckServiceCharge!]!
lines: [CheckLine!]!
totals: CheckTotals!
paidMinor: Int64!
receiptIds: [UUID!]!
prebillCount: Int!
openedAt: DateTime!
billedAt: DateTime
closedAt: DateTime
mergedInto: UUID
version: Int64!
}
type CheckPage
type CheckPage {
items: [Check!]!
next: String
}
enum CheckConflictReasonCode
enum CheckConflictReasonCode {
CHECK_CLOSED
CHECK_CANCELED
LINE_MISSING
LINE_VOIDED
LINE_PAID
LINE_CHANGED
"The charges that apply on the check now are not those the receipt applied."
SERVICE_CHARGES_CHANGED
}
type CheckConflictReason
type CheckConflictReason {
lineNo: Int
reason: CheckConflictReasonCode!
}
enum CheckConflictResolution
enum CheckConflictResolution {
APPLY
DISMISS
}
type CheckConflict
"An offline receipt of a check that did not apply (spec/RESTAURANT.md, Offline)."
type CheckConflict {
id: UUID!
checkId: UUID!
receiptId: UUID!
reasons: [CheckConflictReason!]!
createdAt: DateTime!
resolution: CheckConflictResolution
resolvedBy: UUID
resolvedAt: DateTime
version: Int64!
}
type CheckConflictPage
type CheckConflictPage {
items: [CheckConflict!]!
next: String
}
enum GuestOrderState
enum GuestOrderState {
PENDING
CONFIRMED
REFUSED
EXPIRED
}
type GuestOrderLine
type GuestOrderLine {
itemId: UUID!
name: String!
quantityMilli: Int64!
modifiers: [String!]!
unitPriceMinor: Int64!
amountMinor: Int64!
}
type GuestOrder
"An order a guest sent from a table's menu, waiting for a person."
type GuestOrder {
id: UUID!
tableId: UUID!
tableName: String!
state: GuestOrderState!
lines: [GuestOrderLine!]!
estimateMinor: Int64!
createdAt: DateTime!
checkId: UUID
"A refusal's reason, which the guest sees."
reason: String
resolvedBy: UUID
resolvedAt: DateTime
version: Int64!
}
type GuestOrderPage
type GuestOrderPage {
items: [GuestOrder!]!
next: String
}
enum DietTag
enum DietTag {
VEGETARIAN
VEGAN
HALAL
KOSHER
GLUTEN_FREE
LACTOSE_FREE
SPICY
}
enum Allergen
enum Allergen {
CELERY
CRUSTACEANS
EGGS
FISH
GLUTEN
LUPIN
MILK
MOLLUSKS
MUSTARD
PEANUTS
SESAME
SOY
SULFITES
TREE_NUTS
WHEAT
}
type MenuEntry
type MenuEntry {
itemId: UUID!
description: JSON!
photoId: UUID
diet: [DietTag!]!
allergens: [Allergen!]!
}
type MenuSection
type MenuSection {
id: String!
name: JSON!
entries: [MenuEntry!]!
}
type Menu
"A guest menu (spec/RESTAURANT.md, The guest menu)."
type Menu {
id: UUID!
name: JSON!
position: Int!
active: Boolean!
"The areas it is shown in; empty for every area."
areaIds: [UUID!]!
sections: [MenuSection!]!
version: Int64!
}
enum MenuFont
enum MenuFont {
INTER
NOTO_SERIF
NOTO_SANS_ARMENIAN
}
enum MenuLayout
enum MenuLayout {
LIST
GRID
}
type MenuTheme
"The guest menu's look; its colors reach WCAG 2.2 contrast."
type MenuTheme {
logoPhotoId: UUID
background: String!
text: String!
secondaryText: String!
accent: String!
onAccent: String!
font: MenuFont!
layout: MenuLayout!
"Codes of the product's languages; the first is the default."
languages: [String!]!
version: Int64!
}
type MenuPhoto
type MenuPhoto {
id: UUID!
contentType: String!
bytes: Int!
width: Int!
height: Int!
etag: String!
createdAt: DateTime!
}
type StopListEntry
type StopListEntry {
itemId: UUID!
"When it lifts by itself; null until taken off."
until: DateTime
reason: String
by: UUID!
at: DateTime!
}
type GuestListener
type GuestListener {
enabled: Boolean!
"The origin printed in the tables' QR codes."
origin: String
}
type OpenChecks
type OpenChecks {
count: Int!
totalMinor: Int64!
}
enum SplitKind
enum SplitKind {
NONE
ITEMS
SEATS
EQUAL
}
type ReceiptCheckSplit
type ReceiptCheckSplit {
kind: SplitKind!
seat: Int
parts: Int
}
type ReceiptCheck
"The check a receipt paid lines of."
type ReceiptCheck {
checkId: UUID!
checkNumber: Int64!
tableId: UUID
tableName: String
areaId: UUID
waiterId: UUID!
covers: Int!
openedAt: DateTime!
split: ReceiptCheckSplit!
"This receipt paid the check's last line."
closing: Boolean!
"An offline receipt that did not apply to its check."
conflict: Boolean!
"The check's version after this receipt."
version: Int64
}
enum RestaurantGroupBy
enum RestaurantGroupBy {
DAY
WAITER
TABLE
AREA
}
type RestaurantReportRow
type RestaurantReportRow {
"The day, waiter, table or area; null for a tab by table or area."
key: String
checks: Int!
covers: Int!
revenue: Int64!
tips: Int64!
"Service charges without their tax, less refunds' parts."
serviceCharges: Int64!
tableMinutes: Int64!
averageCheck: Int64
averageCover: Int64
averageMinutes: Int64
}
type RestaurantMetrics
type RestaurantMetrics {
checks: Int!
covers: Int!
revenue: Int64!
tips: Int64!
"Service charges without their tax, less refunds' parts."
serviceCharges: Int64!
tableMinutes: Int64!
averageCheck: Int64
averageCover: Int64
averageMinutes: Int64
}
type RestaurantReport
type RestaurantReport {
groupBy: RestaurantGroupBy!
currency: String!
rows: [RestaurantReportRow!]!
totals: RestaurantMetrics!
}
enum ServiceChargeGroupBy
enum ServiceChargeGroupBy {
DAY
EMPLOYEE
CHARGE
}
type ServiceChargeMetrics
type ServiceChargeMetrics {
sales: Int!
refunds: Int!
"Charges removed by hand on the sales."
removed: Int!
"Without their tax."
amountMinor: Int64!
taxMinor: Int64!
toStaffMinor: Int64!
houseMinor: Int64!
}
type ServiceChargeReportRow
type ServiceChargeReportRow {
"The local date, the employee id or the charge's id."
key: String!
sales: Int!
refunds: Int!
removed: Int!
amountMinor: Int64!
taxMinor: Int64!
toStaffMinor: Int64!
houseMinor: Int64!
}
type ServiceChargeReport
"spec/REPORTS.md, Service charges."
type ServiceChargeReport {
groupBy: ServiceChargeGroupBy!
currency: String!
rows: [ServiceChargeReportRow!]!
totals: ServiceChargeMetrics!
}
enum UpdateState
"A store's update state (spec/RELEASES.md, The states)."
enum UpdateState {
IDLE
DOWNLOADING
WAITING_WINDOW
APPLYING
VERIFYING
DONE
FAILED
ROLLED_BACK
MANUAL
}
enum UpdateStep
"The step a failed or rolled back update stopped at."
enum UpdateStep {
DOWNLOAD
VERIFY
BACKUP
REHEARSE
LOAD
MIGRATE
START
CHECK
}
enum UpdateAction
enum UpdateAction {
UPDATE
ROLLBACK
}
enum Healthz
"The updater's last probe of GET /healthz."
enum Healthz {
OK
FAILING
}
enum UpdaterKind
enum UpdaterKind {
COMPOSE
NONE
}
enum ReleasePlatform
enum ReleasePlatform {
LINUX_X64
LINUX_ARM64
WINDOWS_X64
MACOS_UNIVERSAL
}
type UpdateWindow
"Local wall-clock hours, from inclusive to exclusive (spec/RELEASES.md, The window)."
type UpdateWindow {
from: String!
to: String!
}
enum IncompatibleReason
enum IncompatibleReason {
NODE_TOO_OLD
NODE_TOO_NEW
}
type Compatibility
"Why the hub refuses this node (spec/RELEASES.md, Compatibility)."
type Compatibility {
reason: IncompatibleReason!
hubVersion: String!
"The hub's effective minimum."
minNodeVersion: String!
}
type UpdateTarget
"The store's update target as the hub sent it."
type UpdateTarget {
release: String!
action: UpdateAction!
"In the store's time zone; null for at once."
window: UpdateWindow
"Null for a store's own target (spec/RELEASES.md, A store with no hub)."
rolloutId: UUID
orderedAt: DateTime!
"When a person last cleared the store's held apps for this release (spec/RELEASES.md, One device first)."
appsClearedAt: DateTime
version: Int64!
"The signed manifest document, as JSON."
manifest: JSON!
}
type StoreUpdate
"This store's update, as GET /v1/update answers."
type StoreUpdate {
runningVersion: String!
previousVersion: String
target: UpdateTarget
state: UpdateState!
stateSince: DateTime
step: UpdateStep
error: String
updater: UpdaterKind!
healthz: Healthz
"The hub's refusal while the exchange is refused; null otherwise."
compatibility: Compatibility
"The pre-update archive of the target's attempt (spec/BACKUP.md, Before an update); null before it."
backup: UpdateBackup
"The rehearsal of the target's migrations (spec/RELEASES.md, Rehearsal); null before it."
rehearsal: UpdateRehearsal
backgroundTasks: [BackgroundTask!]!
"The store's apps by version (spec/RELEASES.md, Reporting)."
apps: [AppVersionCount!]!
"The offers of the release the node runs (spec/RELEASES.md, One device first)."
appOffers: [AppOffer!]!
}
enum UpdateBackup
"skipped comes only from an updater before 1.1."
enum UpdateBackup {
TAKEN
FAILED
SKIPPED
}
enum RehearsalOutcome
enum RehearsalOutcome {
PASSED
FAILED
SKIPPED
}
enum RehearsalSkipReason
enum RehearsalSkipReason {
TOO_LARGE
DISK
NOT_PERMITTED
}
type UpdateRehearsal
type UpdateRehearsal {
outcome: RehearsalOutcome!
"Why it was skipped; null otherwise."
reason: RehearsalSkipReason
}
enum BackgroundTaskState
enum BackgroundTaskState {
PENDING
RUNNING
DONE
FAILED
}
type BackgroundTask
"A long data change run after the node starts (spec/RELEASES.md, Migrations)."
type BackgroundTask {
id: String!
release: String!
state: BackgroundTaskState!
done: Int64!
total: Int64
startedAt: DateTime
finishedAt: DateTime
"A short code; null unless failed."
error: String
}
enum AppId
"An app that updates itself from its node (spec/RELEASES.md, The apps)."
enum AppId {
CASHIER
MANAGER
GATEWAY
}
type AppVersionCount
"Counts only, never a device (spec/RELEASES.md, Reporting)."
type AppVersionCount {
app: AppId!
platform: ReleasePlatform!
version: String!
devices: Int!
failed: Int!
silent: Int!
}
enum AppOfferState
enum AppOfferState {
OFFERED
INSTALLED
PROVEN
HELD
}
type AppOffer
"The offer of the release the node runs to one app and platform (spec/RELEASES.md, One device first)."
type AppOffer {
app: AppId!
platform: ReleasePlatform!
release: String!
state: AppOfferState!
since: DateTime!
}
enum ReleaseStatus
enum ReleaseStatus {
DOWNLOADING
VERIFIED
FAILED
}
enum ReleaseSource
enum ReleaseSource {
DOWNLOAD
BUNDLE
}
type ReleaseArtifactSummary
"An artifact of a release as the node lists it, its values as the signed manifest writes them: tokens a later release may add to (spec/RELEASES.md, Values a later release adds)."
type ReleaseArtifactSummary {
name: String!
"image, installer, binary or archive; a later release may add a value."
kind: String!
"node, console, updater, cashier, manager, gateway or deploy; a later release may add a value."
component: String!
"linux-x64, linux-arm64, windows-x64, macos-universal, or any for the deployment kit; a later release may add a value."
platform: String!
"hub or store; a later release may add a value."
roles: [String!]!
size: Int64!
sha256: String!
}
type Release
"A release a hub, or a store with no hub, holds (spec/RELEASES.md, The hub's releases, A store with no hub)."
type Release {
id: UUID!
version: String!
status: ReleaseStatus!
source: ReleaseSource!
publishedAt: DateTime!
minNodeVersion: String!
contractsCommit: String!
keyId: String!
artifacts: [ReleaseArtifactSummary!]!
size: Int64!
"A refusal code, source_unreachable or storage_failed; null unless failed."
error: String
importedAt: DateTime!
importedBy: UUID!
inUse: Boolean!
"The signed manifest document, as JSON."
manifest: JSON!
}
type ReleasePage
type ReleasePage {
items: [Release!]!
next: String
}
enum BrandSource
"Where an effective brand comes from (spec/BRANDS.md)."
enum BrandSource {
DEFAULT
BRAND
BANNER
}
type BrandImageRef
"An image of the brand; its bytes from GET /v1/brand/images/{id}."
type BrandImageRef {
"The lower-case hex SHA-256 of the PNG."
id: String!
width: Int!
height: Int!
}
type BrandThemeColors
"One theme's accent tokens, as #RRGGBB."
type BrandThemeColors {
accent: String!
accentHover: String!
accentActive: String!
accentOn: String!
accentText: String!
accentSoft: String!
}
type BrandColors
type BrandColors {
light: BrandThemeColors!
dark: BrandThemeColors!
}
type EffectiveBrand
"What the apps show in a store: every field null and no lines when the source is DEFAULT."
type EffectiveBrand {
source: BrandSource!
"The brand's and the banner's versions, 0 for one absent."
version: String!
"The chain's name by language."
name: JSON
logo: BrandImageRef
darkLogo: BrandImageRef
receiptLogo: BrandImageRef
colors: BrandColors
"Lines printed under the logo, each text by language."
receiptHeader: [JSON!]!
"Lines printed at the foot."
receiptFooter: [JSON!]!
senderName: String
}