@peabody-soft/mbs-protos 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/Address.proto +36 -0
  2. package/AddressList.proto +18 -0
  3. package/AddressType.proto +11 -0
  4. package/Attachment.proto +48 -0
  5. package/AttachmentType.proto +56 -0
  6. package/AuthTokens.proto +51 -0
  7. package/AuthenticationMethod.proto +21 -0
  8. package/Business.proto +32 -0
  9. package/BusinessIdentifier.proto +16 -0
  10. package/BusinessIdentifierType.proto +30 -0
  11. package/BusinessLink.proto +59 -0
  12. package/BusinessSyncInRequest.proto +42 -0
  13. package/BusinessSyncInResponse.proto +23 -0
  14. package/BusinessSyncOutRequest.proto +100 -0
  15. package/BusinessSyncOutResponse.proto +109 -0
  16. package/Configuration.proto +26 -0
  17. package/Constants.proto +217 -0
  18. package/DimensionUnit.proto +15 -0
  19. package/Dimensions.proto +18 -0
  20. package/Entity.proto +45 -0
  21. package/FulfillmentMode.proto +21 -0
  22. package/GeneralSettings.proto +56 -0
  23. package/Item.proto +26 -0
  24. package/LICENCE +661 -0
  25. package/Message.proto +40 -0
  26. package/MessageType.proto +23 -0
  27. package/OrderStatus.proto +30 -0
  28. package/Package.proto +34 -0
  29. package/PackageIdentifier.proto +16 -0
  30. package/PackageIdentifierType.proto +30 -0
  31. package/PartyPreferencesPayload.proto +20 -0
  32. package/PaymentMethod.proto +15 -0
  33. package/PaymentMethodDetail.proto +17 -0
  34. package/Price.proto +28 -0
  35. package/PriceList.proto +31 -0
  36. package/Product.proto +42 -0
  37. package/ProductCategory.proto +16 -0
  38. package/ProductType.proto +26 -0
  39. package/ProfileSyncOutRequest.proto +42 -0
  40. package/ProfileSyncOutResponse.proto +64 -0
  41. package/README.md +27 -0
  42. package/ReservedPackage.proto +35 -0
  43. package/Role.proto +44 -0
  44. package/SalesOrderPayload.proto +37 -0
  45. package/ShoppingList.proto +57 -0
  46. package/ShoppingListItem.proto +53 -0
  47. package/TaskStatus.proto +13 -0
  48. package/Tax.proto +16 -0
  49. package/TaxType.proto +13 -0
  50. package/UrlAndToken.proto +57 -0
  51. package/User.proto +36 -0
  52. package/Weight.proto +14 -0
  53. package/WeightUnit.proto +15 -0
  54. package/WorkingDays.proto +26 -0
  55. package/WorkingHours.proto +19 -0
  56. package/WorkingHoursRange.proto +22 -0
  57. package/package.json +25 -0
package/Address.proto ADDED
@@ -0,0 +1,36 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "AddressType.proto";
7
+
8
+ // A postal address - a delivery address of a customer, or an address of a business
9
+ message Address {
10
+
11
+ // Unique id of this address within the list that holds it
12
+ int64 id = 1;
13
+
14
+ AddressType addressType = 2;
15
+
16
+ // Flat / house / building number (at most Constants.ADDRESS_UNIT_NUMBER_MAX_LENGTH)
17
+ optional string unitNumber = 3;
18
+
19
+ // Street, locality or neighbourhood (at most Constants.ADDRESS_COMMUNITY_MAX_LENGTH)
20
+ optional string community = 4;
21
+
22
+ // At most Constants.ADDRESS_LINE2_MAX_LENGTH
23
+ optional string line2 = 5;
24
+
25
+ // At most Constants.ADDRESS_CITY_MAX_LENGTH
26
+ optional string city = 6;
27
+
28
+ // At most Constants.ADDRESS_STATE_MAX_LENGTH
29
+ optional string state = 7;
30
+
31
+ // Postal code / PIN code (at most Constants.ADDRESS_PIN_CODE_MAX_LENGTH)
32
+ optional string pinCode = 8;
33
+
34
+ // ISO 3166-1 numeric country code
35
+ int32 countryCode = 9;
36
+ }
@@ -0,0 +1,18 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "Address.proto";
7
+
8
+ // A list of addresses, one of which is the default.
9
+ // Not included because it is derived: size, and the default Address itself (look up
10
+ // defaultAddressId in addresses; when it is not found, the first address is the default).
11
+ message AddressList {
12
+
13
+ // Id of the default address in the list below
14
+ int64 defaultAddressId = 1;
15
+
16
+ // At most Constants.MAX_ADDRESSES addresses
17
+ repeated Address addresses = 2;
18
+ }
@@ -0,0 +1,11 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // Type of an address. Values match the ADDRESS_TYPE_* constants of Address.
7
+ enum AddressType {
8
+
9
+ HOME = 0;
10
+ BUSINESS = 1;
11
+ }
@@ -0,0 +1,48 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "AttachmentType.proto";
7
+ import "Entity.proto";
8
+
9
+ // A file (a photo of a business, product or package, for example) attached to an entity.
10
+ // Excluded: isPublic, isReadyForSync and isProcessingComplete.
11
+ // Not included because it is derived: storageFileName, the name the file is stored under. A client
12
+ // needs it to fetch the file, so here is exactly how Attachment.getStorageFileName builds it, from
13
+ // the createdAt of this entity, its id, its fileHash and its fileExtension:
14
+ //
15
+ // "%04d-%02d-%02d-%016X-%s.%s" (Java Attachment.ATTACHMENT_FILE_NAME_FORMAT)
16
+ //
17
+ // year, month and day the createdAt of this entity, read in UTC. The month is the one
18
+ // java.util.Calendar gives and is therefore zero based: January is 00 and
19
+ // December is 11, so a file created in September 2026 is stored under
20
+ // "2026-08-...". Both ends of the protocol do this, so a client must too.
21
+ // id Entity.id, 16 upper case hex digits, zero padded, with no 0x prefix
22
+ // fileHash the 16 bytes of fileHash as 32 upper case hex digits
23
+ // fileExtension appended after a dot, as it is
24
+ //
25
+ // The case matters: a blob name is case sensitive. The whole name is one flat name, not a path -
26
+ // see UrlAndToken for how a url is built from it.
27
+ message Attachment {
28
+
29
+ Entity entity = 1;
30
+
31
+ // Exposed instead of the raw type id held in the category of this attachment
32
+ AttachmentType attachmentType = 2;
33
+
34
+ // Id of the entity this file is attached to - a business, a product or a package in this
35
+ // protocol. Nothing nests here, so this is how a client finds the photos of an entity. The
36
+ // entity type of the owner is the most significant byte of this id (see Constants).
37
+ int64 owningEntityId = 3;
38
+
39
+ // MD5 hash of the attached file, exactly Constants.ATTACHMENT_FILE_HASH_SIZE_BYTES bytes long.
40
+ // Null / empty when the attachment is deleted.
41
+ optional bytes fileHash = 4;
42
+
43
+ // File name extension, without the dot (at most Constants.ATTACHMENT_FILE_EXTENSION_MAX_LENGTH)
44
+ optional string fileExtension = 5;
45
+
46
+ // File name, without the extension (at most Constants.ATTACHMENT_FILE_NAME_MAX_LENGTH)
47
+ optional string fileName = 6;
48
+ }
@@ -0,0 +1,56 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // The type of an attachment, and - for catalog and store images - the slot the image occupies.
7
+ // Values match the ids of the corresponding Java enum entries and must never be changed.
8
+ enum AttachmentType {
9
+
10
+ // General purpose attachments of any entity
11
+ GENERAL_0 = 0;
12
+ GENERAL_1 = 1;
13
+ GENERAL_2 = 2;
14
+ GENERAL_3 = 3;
15
+
16
+ // The main catalog image of a product or a package
17
+ CATALOG_MAIN_0 = 8;
18
+
19
+ // Catalog images showing the product in use
20
+ CATALOG_LIFESTYLE_0 = 16;
21
+ CATALOG_LIFESTYLE_1 = 17;
22
+ CATALOG_LIFESTYLE_2 = 18;
23
+ CATALOG_LIFESTYLE_3 = 19;
24
+ CATALOG_LIFESTYLE_4 = 20;
25
+ CATALOG_LIFESTYLE_5 = 21;
26
+ CATALOG_LIFESTYLE_6 = 22;
27
+ CATALOG_LIFESTYLE_7 = 23;
28
+
29
+ // Catalog images of the product from different angles
30
+ CATALOG_ANGLE_0 = 40;
31
+ CATALOG_ANGLE_1 = 41;
32
+ CATALOG_ANGLE_2 = 42;
33
+ CATALOG_ANGLE_3 = 43;
34
+ CATALOG_ANGLE_4 = 44;
35
+ CATALOG_ANGLE_5 = 45;
36
+ CATALOG_ANGLE_6 = 46;
37
+ CATALOG_ANGLE_7 = 47;
38
+
39
+ // Other catalog images
40
+ CATALOG_OTHER_0 = 56;
41
+ CATALOG_OTHER_1 = 57;
42
+ CATALOG_OTHER_2 = 58;
43
+ CATALOG_OTHER_3 = 59;
44
+
45
+ // Photos of the store / business
46
+ STORE_0 = 64;
47
+ STORE_1 = 65;
48
+ STORE_2 = 66;
49
+ STORE_3 = 67;
50
+
51
+ // Attachments of a transaction
52
+ TRANSACTION_0 = 80;
53
+ TRANSACTION_1 = 81;
54
+ TRANSACTION_2 = 82;
55
+ TRANSACTION_3 = 83;
56
+ }
@@ -0,0 +1,51 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "AuthenticationMethod.proto";
7
+
8
+ // The tokens that prove who is making a request. This is serialized into the authorization header
9
+ // of every request, the way ServiceProxy.setAuthorizationHeader serializes the Java AuthTokens, so
10
+ // it is a credential envelope rather than part of the entity model and never appears in a body.
11
+ //
12
+ // The three tokens answer different questions: authenticationToken says which person is calling,
13
+ // userToken says which MeraBills user that person is, and linkToken says which business they may
14
+ // act against. They are parsed in that order and the first is a prerequisite for the second, so a
15
+ // userToken is never trusted on its own (Authority.parseUserToken parses the authentication token
16
+ // first). A storefront acquires them in that order too - it signs in with an identity provider,
17
+ // exchanges that for a user token by calling the profile sync out, and gets a link token per
18
+ // business from the BusinessLinks that call returns.
19
+ //
20
+ // Not included because the server derives it: the subject id, and the phone number, which
21
+ // Authority.parseAuthenticationToken reads out of authenticationToken rather than trusting a field.
22
+ // A client that knows its own subject id has no reason to send it, and no way to be believed if it
23
+ // did.
24
+ //
25
+ // Every value here is a bearer credential: never log one, never put one in a url, and hold them
26
+ // only for as long as the session lasts.
27
+ message AuthTokens {
28
+
29
+ // Which identity provider issued authenticationToken, and so how the server parses it. Always
30
+ // set - it selects the parser, and a request whose method has none is refused. There is no
31
+ // unspecified value, because zero is FIREBASE.
32
+ AuthenticationMethod authenticationMethod = 1;
33
+
34
+ // The credential from that identity provider - a Firebase id token when the method is FIREBASE.
35
+ // Always set: every request is parsed for a subject, so there is no anonymous form of this
36
+ // message. This is not issued by this server, and this server does not renew it; a client
37
+ // refreshes it with its identity provider.
38
+ string authenticationToken = 2;
39
+
40
+ // Token proving which MeraBills user the subject is, issued and signed by this server, carrying
41
+ // the user id and the rights of the caller. Absent until a client has called the profile sync out
42
+ // once, and again once it expires, at which point a client calls that again to be given another
43
+ // rather than deriving one.
44
+ optional string userToken = 3;
45
+
46
+ // Token authorizing the caller to act against one business - the BusinessLink.linkToken of that
47
+ // business, which a ProfileSyncOutResponse carries. Absent for a request that names no business,
48
+ // required for one that does. It is per business, so a client that shows two businesses holds one
49
+ // of these for each and sends the one that matches the request.
50
+ optional string linkToken = 4;
51
+ }
@@ -0,0 +1,21 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // Which identity provider issued the AuthTokens.authenticationToken of a request, and so how the
7
+ // server parses it.
8
+ // Values match the ids of the corresponding Java enum entries and must never be changed.
9
+ // Note that there is no unspecified value: zero is FIREBASE. AuthTokens.authenticationMethod is
10
+ // always set, so a client never needs one.
11
+ enum AuthenticationMethod {
12
+
13
+ // The authentication token is a Firebase id token, and the subject id the server reads out of it
14
+ // is a Firebase uid, which is not the same thing as the MeraBills User.entity.id. The userToken
15
+ // of an AuthTokens is not a Firebase token - it is issued by this server, whatever method
16
+ // authenticated the subject.
17
+ FIREBASE = 0;
18
+
19
+ // Reserved for internal administrative callers. A storefront never uses this method.
20
+ ADMIN = 127;
21
+ }
package/Business.proto ADDED
@@ -0,0 +1,32 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "Entity.proto";
7
+
8
+ // A business that a customer can buy from.
9
+ // A business contains no other entity: its settings arrive as a Configuration, its photos as
10
+ // Attachments whose owningEntityId is this business, and its catalog as the item entities of a
11
+ // BusinessSyncOutResponse.
12
+ // This is a profile database entity, so it is carried by a ProfileSyncOutResponse - one per business
13
+ // the caller is linked to. A BusinessSyncOutResponse carries it as well, for the one business it is
14
+ // about, because a client that has not signed in has no profile sync out to read it from.
15
+ // Excluded: category (and the BusinessType derived from it), displayNameOld,
16
+ // allowJoinWithoutInvitation, forTraining and all Translations fields.
17
+ message Business {
18
+
19
+ Entity entity = 1;
20
+
21
+ // Unique, lower case, url friendly id of this business
22
+ // (Constants.BUSINESS_ID_MIN_LENGTH to Constants.BUSINESS_ID_MAX_LENGTH)
23
+ string businessId = 2;
24
+
25
+ // Name of this business, as displayed to customers ("Warm Loaf")
26
+ // (Constants.BUSINESS_DISPLAY_NAME_MIN_LENGTH to Constants.BUSINESS_DISPLAY_NAME_MAX_LENGTH)
27
+ string displayName = 3;
28
+
29
+ // ISO 3166-1 numeric country code. Every amount in this protocol is in the currency of this
30
+ // country - no amount carries a currency of its own.
31
+ int32 countryCode = 4;
32
+ }
@@ -0,0 +1,16 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "BusinessIdentifierType.proto";
7
+
8
+ // An identifier of a business, and the kind of identifier it is. A protobuf map cannot be keyed by
9
+ // an enum, so the identifiers of a business are a repeated pair rather than a map.
10
+ message BusinessIdentifier {
11
+
12
+ BusinessIdentifierType type = 1;
13
+
14
+ // The identifier itself (at most Constants.IDENTIFIER_MAX_LENGTH)
15
+ string value = 2;
16
+ }
@@ -0,0 +1,30 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // A kind of identifier that a business can carry. Every value below is restricted to India.
7
+ // The Java enum identifies these by string id rather than by number, so the values below are
8
+ // numbered here: map each one to the Java id given in its comment.
9
+ enum BusinessIdentifierType {
10
+
11
+ UNSPECIFIED_BUSINESS_IDENTIFIER_TYPE = 0;
12
+
13
+ // "cin" - Corporate Identity Number
14
+ CIN = 1;
15
+
16
+ // "fssai" - Food Safety and Standards Authority of India licence number
17
+ FSSAI = 2;
18
+
19
+ // "gstin" - Goods and Services Tax Identification Number
20
+ GSTIN = 3;
21
+
22
+ // "pan" - Permanent Account Number
23
+ PAN = 4;
24
+
25
+ // "tan" - Tax Deduction and Collection Account Number
26
+ TAN = 5;
27
+
28
+ // "udyam" - Udyam registration number
29
+ UDYAM = 6;
30
+ }
@@ -0,0 +1,59 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "Entity.proto";
7
+ import "Role.proto";
8
+
9
+ // Associates an entity - a user or a business - with a business, in a particular role. This is what
10
+ // tells a signed in customer which businesses they are a customer of, and it carries the token that
11
+ // lets them act against each one.
12
+ //
13
+ // A business link lives in a profile database, alongside the User and the Business entities it names,
14
+ // so it is carried by a ProfileSyncOutResponse and never by a BusinessSyncOutResponse.
15
+ //
16
+ // Excluded: invitationDetails - the name of the inviter, the note they wrote and the rest of it are
17
+ // about accepting an invitation, which is not part of a storefront.
18
+ // Not included because they are derived from expiry: isExpirySet and hasExpired.
19
+ message BusinessLink {
20
+
21
+ Entity entity = 1;
22
+
23
+ // Id of the entity this link is for: a user or a business, and nothing else. The entity type is
24
+ // the most significant byte of this id (Constants.USER_ENTITY_TYPE_ID or
25
+ // Constants.BUSINESS_ENTITY_TYPE_ID), which is how a client tells the two apart. For a storefront
26
+ // this is the User of the caller.
27
+ int64 linkedEntityId = 2;
28
+
29
+ // Id of the business this link is to.
30
+ //
31
+ // This is an entity id, so it matches Business.entity.id - not Business.businessId, which is the
32
+ // lower case url friendly string a storefront is reached by. The Java accessors are both called
33
+ // getBusinessId and return different things (a long here, a String on Business), so this is easy to
34
+ // get wrong.
35
+ int64 businessId = 3;
36
+
37
+ // What the linked entity may do with the business. A storefront customer is normally
38
+ // Role.CUSTOMER.
39
+ Role role = 4;
40
+
41
+ // Id of the party record of the linked entity within that business, or Constants.ENTITY_ID_NULL
42
+ // when there is none. A Party is not generated by this protocol, so this id cannot be resolved by
43
+ // a storefront; it is here because it is a field of the Java class and because the server needs it.
44
+ // Every role outside the partner group has one.
45
+ int64 partyId = 5;
46
+
47
+ // Token proving that the linked entity may act against this business. This is what goes into
48
+ // AuthTokens.linkToken of every later request that names the business.
49
+ //
50
+ // It is a bearer credential: never log it, never put it in a URL, and never show it to anyone but
51
+ // the entity it was issued to. It is not one of the stored attributes of the entity - the server
52
+ // issues it - so a link that arrives without one cannot be used to reach the business.
53
+ optional string linkToken = 6;
54
+
55
+ // Time after which this link is no longer valid, in milliseconds since Jan 1, 1970 00:00:00 UTC.
56
+ // BusinessLink.NO_EXPIRY (0) means it does not expire. A client must compare this against its own
57
+ // clock, so allow for Constants.MAX_CLOCK_SKEW before deciding a link has expired.
58
+ int64 expiry = 7;
59
+ }
@@ -0,0 +1,42 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ import "Message.proto";
7
+
8
+ // A request to sync in the entities a customer has changed: their shopping cart, and the orders
9
+ // they place from it. This is the counterpart of BusinessSyncOutRequest and mirrors the Java sync in
10
+ // (Service.businessSyncIn, which takes the Entity[][] that BusinessDb.syncInToMaster authorizes a
11
+ // table at a time): entities travel flat, one array per entity type, and nothing is nested.
12
+ //
13
+ // This writes one business database, which is what it is named after. A message is a business entity
14
+ // even though the customer sent it, so the cart and the orders belong here; the profile of the
15
+ // customer does not, and is written by a sync in of its own.
16
+ //
17
+ // Who is asking is not part of this message: it is in the AuthTokens of the authorization header. The
18
+ // server authorizes each array against the rights of that caller - messages against
19
+ // Right.MESSAGES_MODIFY - so a client cannot push an entity type it has no right to, and a
20
+ // storefront customer may push only their own messages.
21
+ //
22
+ // An entity being synced in carries the id it already has, or Constants.ENTITY_ID_NULL when the
23
+ // client is creating it and the server is to assign one. The update numbers of the incoming
24
+ // entities are the client's own and are not comparable with the server's: the server assigns new
25
+ // ones and returns them in the BusinessSyncInResponse.
26
+ message BusinessSyncInRequest {
27
+
28
+ // The business these entities belong to, named by its unique, lower case, url friendly id - the
29
+ // same Business.businessId that BusinessSyncOutRequest names
30
+ // (Constants.BUSINESS_ID_MIN_LENGTH to Constants.BUSINESS_ID_MAX_LENGTH)
31
+ string businessId = 1;
32
+
33
+ // The shopping cart of the customer (a message whose payload is a PartyPreferencesPayload) and
34
+ // the orders they place (a payload of SalesOrderPayload) - entity type
35
+ // Constants.MESSAGE_ENTITY_TYPE_ID.
36
+ //
37
+ // This is the only entity type a storefront may push. A customer does not edit the business, its
38
+ // settings, its catalog or its photos, and their own User lives in a profile database that this
39
+ // call does not touch - so there is deliberately no field for any of those types here, rather
40
+ // than a field the server would reject.
41
+ repeated Message messages = 2;
42
+ }
@@ -0,0 +1,23 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // The answer to a BusinessSyncInRequest: the update number the server assigned to the entities that
7
+ // were pushed, one per entity type, the way Java sync in returns the long[] of max incoming update
8
+ // numbers that BusinessDb.syncIn produces, indexed by table entity type id.
9
+ //
10
+ // A client raises its cursor for that entity type to the number below, so that the next
11
+ // BusinessSyncOutRequest does not fetch back what it has just sent. Zero means nothing of that type
12
+ // was accepted, which is what a request that carried none of them gets back.
13
+ //
14
+ // This response carries no entities. A client that needs the server's view of what it pushed - the
15
+ // id assigned to an entity the server created, or the authoritative totals of a shopping list,
16
+ // which are computed with the rounding rules of PriceCalculation - syncs out again afterwards.
17
+ message BusinessSyncInResponse {
18
+
19
+ // The highest update number the server assigned to the messages of the request - entity type
20
+ // Constants.MESSAGE_ENTITY_TYPE_ID. There is one field per entity type that
21
+ // BusinessSyncInRequest can carry, and messages are the only one.
22
+ int64 messageUpdateNumber = 1;
23
+ }
@@ -0,0 +1,100 @@
1
+ syntax = "proto3";
2
+ package com.merabills.storefront;
3
+ option java_multiple_files = true;
4
+ option java_package = "com.merabills.server.core.generated";
5
+
6
+ // A request to sync out everything a storefront needs of one business: the Business, its settings, its
7
+ // catalog and the messages of the customer. This is an incremental sync, so the request carries a
8
+ // cursor per entity type and the BusinessSyncOutResponse carries only what has changed since, flat,
9
+ // for the client to reassemble.
10
+ //
11
+ // This reads one business database, which is why there is no cursor for the User of the caller and no
12
+ // User in the response: a user lives in a profile database and is read by a ProfileSyncOutRequest, the
13
+ // way Java splits Service.businessSyncOut from Service.profileSyncOut.
14
+ //
15
+ // A Business is a profile database entity too, but it is carried here as well, because a client that
16
+ // has not signed in has no profile sync out to read it from and would otherwise not know the name or
17
+ // the country of the business it is showing. So businessUpdateNumber below and
18
+ // ProfileSyncOutRequest.businessUpdateNumber are cursors over the same entity type kept by two
19
+ // different calls: a client keeps one per call and must not carry a number from one over to the other.
20
+ //
21
+ // Who is asking is not part of this message: it is in the AuthTokens of the authorization header,
22
+ // whose linkToken is the BusinessLink.linkToken of the business named below.
23
+ //
24
+ // The store it is asking on behalf of is, in clientDatabaseId below. A storefront keeps a
25
+ // persistent store, so it is a database in the sync topology and has an id of its own, and the
26
+ // server needs that id to know which changes not to send back. This is the requestingDbId argument
27
+ // of Service.businessSyncOut, which the Java clients pass as the db-id query parameter
28
+ // (HttpQueryParameters.DATABASE_ID) rather than in the body; a storefront carries it here instead,
29
+ // so that one protobuf message says everything a sync out needs.
30
+ //
31
+ // Each cursor below is the highest Entity.updateNumber of that entity type that this client has
32
+ // already synced out. The server sends back the entities of that type whose updateNumber is
33
+ // greater, so a client stores the highest updateNumber it receives per type and sends it back on
34
+ // the next call. Zero, the default, means this client has nothing yet and asks for everything -
35
+ // a first sync therefore leaves every cursor unset.
36
+ //
37
+ // One field below is not a cursor: attachmentBaseUrlExpiry is a time, and it asks for a value rather
38
+ // than for entities. It is here because the files of the attachments of a business are read from a
39
+ // url that expires, and renewing it in this call costs nothing, where a call of its own would cost a
40
+ // round trip on every sync.
41
+ //
42
+ // Sync out is bounded: one call returns at most Constants.SYNC_OUT_LIMIT entities across all types
43
+ // together. On receiving that many, a client must call again with its updated cursors until it
44
+ // receives fewer.
45
+ //
46
+ // There is one cursor per entity type that has a table of its own, which is how updateNumbers are
47
+ // kept, and not one per class: the product categories, products, packages, price lists and prices
48
+ // of a catalog are all item entities and all share itemUpdateNumber. Update numbers are only
49
+ // comparable within one entity type, and only against the same server.
50
+ message BusinessSyncOutRequest {
51
+
52
+ // The business to sync out, named by its unique, lower case, url friendly id - the same
53
+ // Business.businessId that the storefront was reached by
54
+ // (Constants.BUSINESS_ID_MIN_LENGTH to Constants.BUSINESS_ID_MAX_LENGTH)
55
+ string businessId = 1;
56
+
57
+ // Id of the store this client keeps, which is what makes an incremental sync out incremental in
58
+ // both directions: the server compares it against the Entity.updateInfo of every candidate
59
+ // entity and leaves out the ones this client wrote itself, because it already has them.
60
+ //
61
+ // A client generates this once and keeps it for the life of its store. It is never
62
+ // Constants.MASTER_DB_ID, which is the server, and never a reserved id, so a client that sends
63
+ // zero is claiming to be the server and will be sent its own writes back on every sync.
64
+ //
65
+ // The same value goes into the Entity.updateInfo of everything this client pushes in a
66
+ // BusinessSyncInRequest. There is no such field on that request, because there the id arrives on
67
+ // each entity instead.
68
+ int64 clientDatabaseId = 2;
69
+
70
+ // The business - entity type Constants.BUSINESS_ENTITY_TYPE_ID
71
+ int64 businessUpdateNumber = 3;
72
+
73
+ // The photos of the business, its products and its packages - entity type
74
+ // Constants.ATTACHMENT_ENTITY_TYPE_ID
75
+ int64 attachmentUpdateNumber = 4;
76
+
77
+ // The expiry of the attachment base url and token this client is holding - the UrlAndToken.expiry
78
+ // of the last BusinessSyncOutResponse.attachmentBaseUrl it received, sent back unchanged. Zero,
79
+ // the default, means this client holds none and is asking for one, which is what a first sync
80
+ // does.
81
+ //
82
+ // The server answers with a new attachmentBaseUrl when this is zero, or within
83
+ // Constants.ATTACHMENT_BASE_URL_EXPIRY_MARGIN of the time it reads the request, and leaves it
84
+ // absent otherwise. This is a time and not an update number: it is not comparable with the cursors
85
+ // around it, it does not rise monotonically, and a client must never derive it from anything but
86
+ // the UrlAndToken it holds.
87
+ int64 attachmentBaseUrlExpiry = 5;
88
+
89
+ // The settings of the business, which are held in a configuration entity - entity type
90
+ // Constants.CONFIGURATION_ENTITY_TYPE_ID
91
+ int64 configurationUpdateNumber = 6;
92
+
93
+ // The orders of the customer and their shopping cart - entity type
94
+ // Constants.MESSAGE_ENTITY_TYPE_ID
95
+ int64 messageUpdateNumber = 7;
96
+
97
+ // The whole catalog: product categories, products, packages, price lists and prices, which are
98
+ // all item entities and share this one cursor - entity type Constants.ITEM_ENTITY_TYPE_ID
99
+ int64 itemUpdateNumber = 8;
100
+ }