-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.graphql
474 lines (417 loc) · 16.7 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
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# This file is automatically GENERATED.
# Manual changes might be lost - proceed with caution!
schema {
query: Query
mutation: Mutation
}
enum PriceSortDirection {
LOW_TO_HIGH
HIGH_TO_LOW
}
"""
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 SupportedCurrency {
MXN
}
enum SupportedLocale {
en_US
es_MX
}
input AllCatsFilter {
"When `true` returns only adopted cats. When `false` returns only cats available for adoption." adopted: Boolean!
}
input CheckoutSessionInput {
selectedProducts: [CheckoutSessionProductInput!]!
}
input CheckoutSessionProductInput {
productId: ID!
productUnits: Int!
productPriceUnitAmount: Int!
productPriceUnitAmountCurrency: SupportedCurrency!
}
input PosCheckoutInput {
selectedProducts: [PosCheckoutProductInput!]!
}
input PosCheckoutProductAddonInput {
productAddonId: ID!
productAddonExtraPriceUnitAmount: Int!
productAddonExtraPriceUnitAmountCurrency: SupportedCurrency!
}
input PosCheckoutProductInput {
productKey: ID!
productUnits: Int!
productPriceUnitAmount: Int!
productPriceUnitAmountCurrency: SupportedCurrency!
productAddons: [PosCheckoutProductAddonInput!]
}
input ProductMultilingualInput {
images: [ProductImageUploadable!]!
price: ProductPriceInput!
translations: [ProductMultilingualInputTranslations!]!
visibility: [ProductMultilingualInputVisibility!]!
categories: [ID!]!
addons: [ID!]!
}
input ProductMultilingualInputTranslations {
locale: SupportedLocale!
name: String!
description: String
}
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!
}
"""
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
type AnalyticsQuery {
redirectHits: [Redirect!]!
}
type AnyUser {
id: ID!
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 AuthMutation {
"""
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 (old sessions are not removed to support
multiple logins on multiple devices). 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!
}
type AuthQuery {
"Returns information about the current user (can be authenticated or anonymous)."
whoami: WhoamiPayload!
listUsers: [AnyUser!]!
}
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
}
type CatInfo {
id: ID!
name: String!
description: String
"Order in which the cat was admitted to KOCHKA Café."
order: Int!
"Most of the cats can be adopted but some cannot. This flag distinguishes exactly this."
canBeAdopted: Boolean
"When was the cat adopted (when it leaved KOCHKA Café)."
dateOfAdoption: String
"When was the cat dewormed for the last time."
dateOfDeworming: String
"When was the cat castrated."
dateOfCastration: String
dateOfVaccinationRabies: String
"Felocell 3 and similar."
dateOfVaccinationTripleFelina: String
"Purevax Feline 4 and similar."
dateOfVaccinationCuadrupleFelina: String
dateOfVaccinationLeucemiaFelina: String
}
type CatsQuery {
listAllCats(allCatsFilter: AllCatsFilter): [CatInfo!]!
}
type CheckoutSession {
id: ID!
"The URL to the Checkout Session. Users should be redirected here so they can pay the order."
paymentUrl: 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!, clientLocale: SupportedLocale!): 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!, clientLocale: SupportedLocale!): ProductOrError!
"""
Unpublishes product based on the product KEY. Unpublished products are available only inside
the backoffice.
"""
productUnpublish(productKey: ID!, clientLocale: SupportedLocale!): ProductOrError!
"""
Creates checkout session based on the inputs so that users can be redirected to the returned
session URL and finish paying their order.
Internally, we perform bunch of validation, most notably, we check whether the specified
prices are still valid and whether there is enough units to be sold.
"""
checkoutSessionCreate(input: CheckoutSessionInput!, clientLocale: SupportedLocale!): CheckoutSession!
}
type CommerceQuery {
"""
Searches ALL products (published and unpublished) anywhere in the system (no visibility
restrictions). Optionally, you can specify categories you'd like to filter instead of
returning all products. The specified categories must be valid (they must exist).
This query requires admin permissions so it should be used only in backoffice to
administer the products.
"""
searchAllProducts(clientLocale: SupportedLocale!, priceSortDirection: PriceSortDirection!, categories: [ID!]): [Product]!
"""
Searches all published products for the specified visibility. The permission requirements
depend on the visibility (for example, ESHOP is public but POS is private).
Optionally, you can specify categories you'd like to filter instead of
returning all products. The specified categories must be valid (they must exist).
TODO: deprecate this query and use "paginated" version instead
"""
searchAllPublishedProducts(clientLocale: SupportedLocale!, priceSortDirection: PriceSortDirection!, visibility: ProductMultilingualInputVisibility!, categories: [ID!]): [Product]!
"Returns ALL available product categories that can be applied to any product."
searchAllProductCategories(clientLocale: SupportedLocale!): [ProductCategory]!
"Returns ALL available product addons that can be assigned to products."
searchAllProductAddons(clientLocale: SupportedLocale!): [ProductAddon]!
"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!
}
type DeauthorizePayload {
success: Boolean!
}
type Image {
name: String!
blurhash: String!
url: String!
}
"Root mutation of the graph."
type Mutation {
auth: AuthMutation!
commerce: CommerceMutation!
pos: POSMutation!
}
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!, clientLocale: SupportedLocale!): PosCheckoutPayloadOrError!
}
type PosCheckoutError {
message: String!
}
type PosCheckoutPayload {
id: ID!
}
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!
}
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]!
"""
Returns ALL available addons that can be applied to this product. You might be also
interested in `selected_addons` which are addons previously selected for this product.
"""
availableAddons(clientLocale: SupportedLocale!): [ProductAddon]!
"""
Returns product addons that were assigned to the particular product. You might be also
interested in `available_addons` which are ALL addons available for the assignment.
"""
selectedAddons(clientLocale: SupportedLocale!): [ProductAddon]!
"Returns true when the product has some assigned addons, otherwise false."
hasSelectedAddons: Boolean!
}
"""
Product add-on can be attached to any product as an addition. For example, coffee Latte as a
product can have add-ons: dairy free milk, vanilla syrup, …
Each product add-on can affect the final product price. At this moment we support only one
pricing model: flat fee (for example, extra 10 MXN per coffee for milk without lactose).
"""
type ProductAddon {
id: ID!
"The product variant's name, meant to be displayable to the customer."
name: String!
"""
Extra price (flat fee) that should be added to the product price. For example, if coffee
consts 50 MXN and oat milk has price extra 10 MXN then the final price should be 60 MXN.
"""
priceExtra: Price!
}
type ProductCategory {
id: ID!
"""
Order in which the product categories should be sorted and displayed. Category with number
"1" goes first followed by "2", "3", …
"""
order: Int!
"The product category name, meant to be displayable to the customer."
name: String!
}
type ProductError {
message: String!
}
type ProductMultilingualTranslations {
locale: SupportedLocale!
name: String!
description: String
}
"Root query of the graph."
type Query {
analytics: AnalyticsQuery!
auth: AuthQuery!
cats: CatsQuery!
commerce: CommerceQuery!
}
type Redirect {
id: ID!
"UUID is the ID used for redirects, for example: https://…/redirect/:uuid"
uuid: String!
redirectsTo: String!
description: String!
hits: Int!
}
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!
}
union PosCheckoutPayloadOrError = PosCheckoutPayload | PosCheckoutError
union ProductOrError = Product | ProductError