This repository was archived by the owner on Jan 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.graphql
375 lines (331 loc) · 12.9 KB
/
schema.graphql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# @generated SignedSource<<a370140b207472efc35632c07ab034b3>>
enum PriceSortDirection {
LOW_TO_HIGH
HIGH_TO_LOW
}
type POSQuery {
"""
Lists published products for POS. Requires admin permissions so it should be used only in
POS after logging in.
"""
listPublishedProducts: [Product]
getTotalCheckoutStats: PosCheckoutTotalStats
}
input PosCheckoutProductInput {
productKey: ID!
productUnits: Int!
productPriceUnitAmount: Int!
productPriceUnitAmountCurrency: SupportedCurrency!
}
type DeauthorizePayload {
success: Boolean!
}
enum SupportedCurrency {
MXN
}
"Root mutation of the graph."
type Mutation {
"""
This function accepts Google ID token (after receiving it from Google Sign-In in a webapp)
and returns authorization payload. There is no concept of sign-in and sign-up: every
whitelisted user with a valid JWT ID token will be authorized. Invalid tokens and users
that are not whitelisted will be rejected.
Repeated calls will result in a new session token and deauthorization of the previous
token (if it exist). Original session token is returned back only once and cannot be
retrieved later (it's irreversibly hashed in the database).
"""
authorizeWebapp(googleIdToken: String!): AuthorizeWebappPayload!
"""
The purpose of this `deauthorize` mutation is to remove the active sessions and effectively
make the mobile application/webapp unsigned. Applications should remove the session token
once de-authorized.
Repeated calls will result in failure since it's not possible to deauthorize twice.
"""
deauthorize(sessionToken: String!): DeauthorizePayload!
commerce: CommerceMutation!
pos: POSMutation!
}
type ProductMultilingualTranslations {
locale: SupportedLocale!
name: String!
description: String
}
type CommerceMutation {
"""
Creates a new product.
Note on uploading product images: image names specified in the GraphQL input must correspond
to the uploadables (multipart/form-data) and vice versa. Requests with invalid uploadables
will be rejected.
"""
productCreate(clientLocale: SupportedLocale!, productMultilingualInput: ProductMultilingualInput!): ProductOrError!
"""
Updates already existing product with new values. It requires not only product KEY but also
product REVISION to avoid lost update situations (when someone else tried to update the
product and this update would overwrite the latest changes).
Note on updating product images: already existing image names must be send to the server
otherwise they will be deleted. You can optionally specify some extra (new) images to upload
them via uploadables. This feature will eventually be used even for images re-ordering.
"""
productUpdate(clientLocale: SupportedLocale!, productKey: ID!, productRevision: ID!, productMultilingualInput: ProductMultilingualInput!): ProductOrError!
"""
Archives product based on the product KEY making it effectively inaccessible. From the user
perspective it's like deleting the product, however, internally the product still exists in
the archive and could potentially be restored.
Note: the product cannot be searched for and cannot be retrieved in any way (other than via
the archive). It can also be hard deleted without prior notice.
"""
productArchive(productKey: ID!): ProductOrError!
"""
Publishes product based on the product KEY. Various validation requirements must be met
before the product can be published. Published product is available outside of backoffice.
"""
productPublish(productKey: ID!): ProductOrError!
"""
Unpublishes product based on the product KEY. Unpublished products are available only inside
the backoffice.
"""
productUnpublish(productKey: ID!): ProductOrError!
}
"""
Specifies additional visibility of the product. Each product is always visible in the backoffice
but can additionally be displayed in POS, eshop (public) or both.
"""
enum ProductMultilingualInputVisibility {
"Visible in eshop only (therefore it's public)." ESHOP
"Visible in POS only (accessible to authorized users)." POS
}
enum SupportedLocale {
en_US
es_MX
}
type Price {
"""
The unit amount in centavo to be charged, represented as a whole integer.
Centavo equals ¹⁄₁₀₀ of the basic monetary unit.
"""
unitAmount: Int!
"Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html)."
unitAmountCurrency: SupportedCurrency!
}
union PosCheckoutPayloadOrError = PosCheckoutPayload | PosCheckoutError
"Root query of the graph."
type Query {
"Returns information about the current user (can be authenticated or anonymous)."
whoami: WhoamiPayload!
listUsers: [AnyUser!]!
commerce: CommerceQuery!
menu: MenuQuery!
pos: POSQuery!
}
type WhoamiPayload {
id: ID
"""
Human readable type should be used only for testing purposes. The format is not guaranteed
and can change in the future completely.
"""
humanReadableType: String
"""
Debug assertions indicates that the Rust server runs in a development mode (compiled without
optimizations). FOR DEVELOPMENT ONLY!
"""
isDebugAssertionsEnabled: Boolean!
}
type MenuQuery {
"""
Returns a specified section of our menu. This is to maintain one source of truth (in our
database) about the prices, descriptions, translations and similar.
"""
menu(clientLocale: SupportedLocale!, section: MenuSections!): [Product!]!
}
type POSMutation {
"""
This is a simplified POS checkout. We simply record what the user bought for how much and
so on. There is almost no validation - what the client sends is what we record. This is the
main difference from eshop checkout where we would have to verify the prices for example.
Why not to verify that the checkout price matches the product price? It's because when
cashier accepts the money, the product is sold for the given price and there is not time for
price adjustments (customers would be angry if we would say "oh, actually it just got more
expensive").
"""
checkout(input: PosCheckoutInput!): PosCheckoutPayloadOrError!
}
union ProductOrError = Product | ProductError
type AnyUser {
id: String!
isActive: Boolean!
"Name is a full name of the user (\"John Doe\")."
name: String
"Given name is \"John\" in \"John Doe\"."
givenName: String
"Family name is \"Doe\" in \"John Doe\"."
familyName: String
hasEmailVerified: Boolean
}
type ProductCategory {
id: ID!
"The product category name, meant to be displayable to the customer."
name: String!
}
type ProductError {
message: String!
}
type CommerceQuery {
"""
Searches all published (publicly accessible) products. Everyone can do it without any
special permission so it should be used on FE.
"""
searchPublishedProducts(clientLocale: SupportedLocale!, priceSortDirection: PriceSortDirection!, searchTerm: String): [Product]
"""
Searches all products (published and unpublished). Requires admin permissions so it should
be used only in backoffice to administer the products.
"""
searchAllProducts(clientLocale: SupportedLocale!, priceSortDirection: PriceSortDirection!, searchTerm: String): [Product]!
"Returns ALL available product categories that can be applied to any product."
searchAllProductCategories(clientLocale: SupportedLocale!): [ProductCategory]!
"Returns one publicly available product by its key. Anyone can call this resolver."
getPublishedProductByKey(clientLocale: SupportedLocale!, productKey: ID!): Product!
"Only admins can call this function! It returns published OR unpublished product by its key."
getUnpublishedProductByKey(clientLocale: SupportedLocale!, productKey: ID!): Product!
}
input ProductMultilingualInput {
images: [ProductImageUploadable!]!
price: ProductPriceInput!
translations: [ProductMultilingualInputTranslations!]!
visibility: [ProductMultilingualInputVisibility!]!
categories: [ID!]!
}
"""
This type should be used together with GraphQL uploads and it should hold the file names
being uploaded. It's used together with the actual uploaded files for validation purposes.
Only files which are defined using this scalar will be processed.
"""
scalar ProductImageUploadable
input ProductPriceInput {
"""
The unit amount in centavo to be charged, represented as a whole integer.
Centavo equals ¹⁄₁₀₀ of the basic monetary unit.
""" unitAmount: Int!
"Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html)." unitAmountCurrency: SupportedCurrency!
}
input ProductMultilingualInputTranslations {
locale: SupportedLocale!
name: String!
description: String
}
type Product {
"""
Product ID is unique in our whole GraphQL universe. Please note however, that it's not URL
friendly.
"""
id: ID!
"""
Product KEY is unique only amongst other products but can potentially conflict with other
keys of other types. Use product ID if you want truly unique value.
"""
key: ID!
"""
The read-only `revision` value should be used as a pre-condition for mutations, to avoid
"lost update" situations when editing the product. That is, if a client fetches a product
from the server, modifies it locally (but with the `revision` value untouched) and sends it
back to the server to update the product, but meanwhile the product was changed by another
operation, then the revisions do not match anymore and the operation is cancelled by the
server. Without this mechanism, the client would accidentally overwrite changes made
to the product without knowing about it.
When an existing product is updated or replaced successfully, our database will create a
new revision value. From a user perspective, there is just one single product revision
present per different `key` at every point in time. There is no built-in system to
automatically keep a history of all changes done to a product and old versions of a
product can not be restored via the `revision` value.
For more information see: https://www.arangodb.com/docs/stable/data-modeling-documents-document-address.html#document-revision
"""
revision: ID!
"The product's name, meant to be displayable to the customer."
name: String!
"""
The product's description, meant to be displayable to the customer. Use this field to
optionally store a long form explanation of the product being sold for your own rendering
purposes.
"""
description: String
"""
A list of images for this product, meant to be displayable to the customer. You can get
image cover via `imageCover` field.
"""
images: [Image!]!
"""
Returns the most important image which should be displayed as a product cover. Other images
are available under field `images`.
"""
imageCover: Image
"""
A label that represents units of this product in Stripe and on customers’ receipts and
invoices. When set, this will be included in associated invoice line item descriptions.
"""
unitLabel: String!
price: Price!
isPublished: Boolean!
visibility: [ProductMultilingualInputVisibility!]!
"""
Same as `translations` except for one locale: it exposes the translated variant of the
product with localized name, description etc.
"""
translation(locale: SupportedLocale!): ProductMultilingualTranslations
"""
Exposes all available product translations. What is the difference between `translations`
and `name`/`description`? Name and description are localized based on the eshop locale,
however, translations are all the available translations ignoring the locale.
"""
translations: [ProductMultilingualTranslations!]!
"""
Returns ALL available product categories that can be applied to this product. You might be
also interested in `selected_categories` which are categories previously selected for this
product.
"""
availableCategories(clientLocale: SupportedLocale!): [ProductCategory]!
"""
Returns categories that were assigned to the particular product. You might be also
interested in `available_categories` which are ALL categories available for the assignment.
"""
selectedCategories(clientLocale: SupportedLocale!): [ProductCategory]!
}
input PosCheckoutInput {
selectedProducts: [PosCheckoutProductInput!]!
}
type PosCheckoutError {
message: String!
}
type AuthorizeWebappPayload {
success: Boolean!
"Failure message is available only when success=false."
failureMessage: String
"""
Session token should be send with every GraphQL request which requires auth.
Returns `None` if the request was not successful.
"""
sessionToken: String
}
enum MenuSections {
COFFEE
TEA
MILKSHAKES
SPECIALITIES
DUMPLING_SWEET
DUMPLING_SAVORY
}
type PosCheckoutPayload {
id: ID!
}
type PosCheckoutTotalStats {
totalCheckouts: Int!
totalSoldUnits: Int!
totalSoldUnitAmount: Int!
}
type Image {
name: String!
blurhash: String!
url: String!
}
schema {
query: Query
mutation: Mutation
}