@reventlessdev/online-shop-hybrid-ordering 1.0.0-alpha.244 → 1.0.0-alpha.246

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 (72) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +14 -14
  3. package/src/CatalogProduct/StateChange/SyncCatalogProduct.res +18 -10
  4. package/src/CatalogProduct/StateChange/SyncCatalogProduct.res.mjs +11 -10
  5. package/src/CatalogProduct/StateViewStream/AvailableProducts.res +16 -5
  6. package/src/CatalogProduct/StateViewStream/AvailableProducts.res.mjs +7 -6
  7. package/src/Customer/Aggregate/Customer.res +2 -0
  8. package/src/Customer/CustomerId.res +4 -0
  9. package/src/Customer/CustomerId.res.mjs +29 -0
  10. package/src/Customer/OutboundTranslation/VerifyCustomerEmail.res +1 -1
  11. package/src/Customer/OutboundTranslation/VerifyCustomerEmail.res.mjs +2 -1
  12. package/src/Customer/OutboundTranslation/VerifyCustomerEmail_Translation.res +1 -1
  13. package/src/Customer/OutboundTranslation/VerifyCustomerEmail_Translation.res.mjs +2 -1
  14. package/src/Customer/ReadModelStream/Customers.res +3 -1
  15. package/src/Customer/ReadModelStream/Customers.res.mjs +4 -3
  16. package/src/Customer/ReadModelStream/Customers_Projections.res +3 -3
  17. package/src/Customer/ReadModelStream/Customers_Projections.res.mjs +10 -8
  18. package/src/Customer/StateChange/EmailVerificationChallenges.res +13 -8
  19. package/src/Customer/StateChange/EmailVerificationChallenges.res.mjs +9 -8
  20. package/src/ExtensionPoint/Orders_ExtensionPointMapping.res +29 -10
  21. package/src/ExtensionPoint/Orders_ExtensionPointMapping.res.mjs +32 -23
  22. package/src/Notification/Automation/NotificationIntake.res +1 -1
  23. package/src/Notification/Automation/NotificationIntake.res.mjs +2 -1
  24. package/src/Notification/Automation/NotificationIntake_Automation.res +13 -4
  25. package/src/Notification/Automation/NotificationIntake_Automation.res.mjs +8 -6
  26. package/src/Notification/StateViewStream/NotificationSubscriptions.res.mjs +2 -2
  27. package/src/Order/Automation/AutoShipOrder.res +2 -2
  28. package/src/Order/Automation/AutoShipOrder.res.mjs +3 -2
  29. package/src/Order/Automation/AutoShipOrder_Automation.res +6 -5
  30. package/src/Order/Automation/AutoShipOrder_Automation.res.mjs +7 -6
  31. package/src/Order/OrderId.res +4 -0
  32. package/src/Order/OrderId.res.mjs +29 -0
  33. package/src/Order/StateChange/CancelOrder.res +5 -5
  34. package/src/Order/StateChange/CancelOrder.res.mjs +8 -6
  35. package/src/Order/StateChange/CancelOrder_Behavior.res +1 -1
  36. package/src/Order/StateChange/PlaceOrder.res +29 -16
  37. package/src/Order/StateChange/PlaceOrder.res.mjs +21 -18
  38. package/src/Order/StateChange/PlaceOrder_Behavior.res +4 -4
  39. package/src/Order/StateChange/PlaceOrder_Behavior.res.mjs +4 -3
  40. package/src/Order/StateChange/ShipOrder.res +3 -3
  41. package/src/Order/StateChange/ShipOrder.res.mjs +8 -5
  42. package/src/Order/StateChange/ShipOrder_Behavior.res +2 -2
  43. package/src/Order/StateChange/ShipOrder_Behavior.res.mjs +9 -6
  44. package/src/Order/StateViewStream/Orders.res +13 -10
  45. package/src/Order/StateViewStream/Orders.res.mjs +16 -13
  46. package/src/Plugin.res.mjs +8 -17
  47. package/tests/CatalogProduct/StateChange/SyncCatalogProduct_GWT.res +17 -15
  48. package/tests/CatalogProduct/StateChange/SyncCatalogProduct_GWT.res.mjs +19 -15
  49. package/tests/CatalogProduct/StateViewStream/AvailableProducts_GWT.res +13 -11
  50. package/tests/CatalogProduct/StateViewStream/AvailableProducts_GWT.res.mjs +16 -19
  51. package/tests/Customer/ReadModelStream/Customers_GWT.res +16 -13
  52. package/tests/Customer/ReadModelStream/Customers_GWT.res.mjs +24 -16
  53. package/tests/Customer/StateChange/EmailVerificationChallenges_GWT.res +23 -17
  54. package/tests/Customer/StateChange/EmailVerificationChallenges_GWT.res.mjs +23 -17
  55. package/tests/Extension/Products_Extension_GWT.res +6 -4
  56. package/tests/Extension/Products_Extension_GWT.res.mjs +8 -4
  57. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +10 -2
  58. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +19 -7
  59. package/tests/Flow/OrderingFlow_GWT.res +27 -19
  60. package/tests/Flow/OrderingFlow_GWT.res.mjs +33 -28
  61. package/tests/Notification/Automation/NotificationIntake_GWT.res +11 -8
  62. package/tests/Notification/Automation/NotificationIntake_GWT.res.mjs +18 -10
  63. package/tests/Order/Automation/AutoShipOrder_GWT.res +11 -9
  64. package/tests/Order/Automation/AutoShipOrder_GWT.res.mjs +13 -9
  65. package/tests/Order/StateChange/CancelOrder_GWT.res +19 -16
  66. package/tests/Order/StateChange/CancelOrder_GWT.res.mjs +27 -19
  67. package/tests/Order/StateChange/PlaceOrder_GWT.res +131 -119
  68. package/tests/Order/StateChange/PlaceOrder_GWT.res.mjs +459 -615
  69. package/tests/Order/StateChange/ShipOrder_GWT.res +15 -11
  70. package/tests/Order/StateChange/ShipOrder_GWT.res.mjs +29 -17
  71. package/tests/Order/StateViewStream/Orders_GWT.res +46 -42
  72. package/tests/Order/StateViewStream/Orders_GWT.res.mjs +61 -52
package/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 1.0.0-alpha.246 (2026-09-21)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **deps:** update rescript to 12.3.1 ([ea1ce37](https://github.com/ReventlessDev/reventless-core/commit/ea1ce377297640f6d0d360e6c84c778d59ecbcc5))
11
+ * **deps:** update sury to 11.0.0 ([8715b22](https://github.com/ReventlessDev/reventless-core/commit/8715b22b33856c46ba57518aad151065c123a995))
12
+
13
+
14
+ # 1.0.0-alpha.245 (2026-09-21)
15
+
16
+ ### Features
17
+
18
+ * **examples:** the hybrid example types its ids ([e7a88a9](https://github.com/ReventlessDev/reventless-core/commit/e7a88a9883e04f41ff39c7fb5f709a14e9005772))
19
+
20
+
6
21
  # 1.0.0-alpha.244 (2026-09-21)
7
22
 
8
23
  * feat(spec)!: typed projection keys ([fc6a018](https://github.com/ReventlessDev/reventless-core/commit/fc6a01811ba788f3289e84a435a09f77fa627e1a))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/online-shop-hybrid-ordering",
3
- "version": "1.0.0-alpha.244",
3
+ "version": "1.0.0-alpha.246",
4
4
  "description": "Online Shop Hybrid example — Ordering plugin (Customer aggregate + Order/CatalogProduct DCB)",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -20,24 +20,24 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "sury": "11.0.0-rc.2",
24
- "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.136",
25
- "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.21",
26
- "@reventlessdev/reventless-infra": "3.0.0-alpha.168",
27
- "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.136",
28
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.214",
29
- "@reventlessdev/reventless-local": "3.0.0-alpha.257",
30
- "@reventlessdev/reventless-spec": "3.0.0-alpha.140",
31
- "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.16",
32
- "@reventlessdev/trait-notification": "1.0.0-alpha.16"
23
+ "sury": "11.0.0",
24
+ "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.138",
25
+ "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
26
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.216",
27
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.169",
28
+ "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.137",
29
+ "@reventlessdev/reventless-local": "3.0.0-alpha.259",
30
+ "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.18",
31
+ "@reventlessdev/trait-notification": "1.0.0-alpha.18",
32
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.141"
33
33
  },
34
34
  "devDependencies": {
35
- "rescript": "12.3.0",
36
- "sury-ppx": "11.0.0-rc.2",
35
+ "rescript": "12.3.1",
36
+ "sury-ppx": "11.0.0",
37
37
  "@reventlessdev/reventless-ppx": "1.0.0-alpha.81"
38
38
  },
39
39
  "peerDependencies": {
40
- "rescript": "12.3.0"
40
+ "rescript": "^12.3.1"
41
41
  },
42
42
  "publishConfig": {
43
43
  "registry": "https://registry.npmjs.org"
@@ -13,20 +13,20 @@ type consumedEvent =
13
13
 
14
14
  @schema
15
15
  type command =
16
- | SyncNewProduct({productId: string, name: string, price: Reventless.Money.t})
17
- | ChangeSyncedPrice({productId: string, price: Reventless.Money.t})
16
+ | SyncNewProduct({productId: CatalogSpec.ProductId.t, name: string, price: Reventless.Money.t})
17
+ | ChangeSyncedPrice({productId: CatalogSpec.ProductId.t, price: Reventless.Money.t})
18
18
  // The withdrawal and the way back. Both carry only the id: the shadow this
19
19
  // slice maintains already holds the name and price, and it survives the read
20
20
  // model's delete — which is what lets a relist restore availability from state
21
21
  // Ordering owns rather than asking Catalog to re-send facts it already has.
22
- | WithdrawSyncedProduct({productId: string})
23
- | RelistSyncedProduct({productId: string})
22
+ | WithdrawSyncedProduct({productId: CatalogSpec.ProductId.t})
23
+ | RelistSyncedProduct({productId: CatalogSpec.ProductId.t})
24
24
  // The picture Catalog says to show. Carried as the ref Catalog's store minted,
25
25
  // so Ordering stores a path it can hand to a reader without knowing where the
26
26
  // bytes live or being able to write there — which is why the store is named
27
27
  // rather than derived: the field's own name would declare an Ordering store.
28
28
  | ChangeSyncedProductImage({
29
- productId: string,
29
+ productId: CatalogSpec.ProductId.t,
30
30
  @storageRef("Catalog.productImages") productImage?: Reventless.UploadableImage.t,
31
31
  })
32
32
 
@@ -35,15 +35,23 @@ type error = unit // always succeeds — sync is idempotent
35
35
 
36
36
  @schema
37
37
  type event =
38
- | CatalogProductSynced({productId: string, name: string, price: Reventless.Money.t})
39
- | CatalogProductPriceChanged({productId: string, price: Reventless.Money.t})
40
- | CatalogProductWithdrawn({productId: string})
38
+ | CatalogProductSynced({
39
+ productId: CatalogSpec.ProductId.t,
40
+ name: string,
41
+ price: Reventless.Money.t,
42
+ })
43
+ | CatalogProductPriceChanged({productId: CatalogSpec.ProductId.t, price: Reventless.Money.t})
44
+ | CatalogProductWithdrawn({productId: CatalogSpec.ProductId.t})
41
45
  // Carries the shadow's name and price so the projection can restore the row
42
46
  // without a second read: the fold has them in hand at exactly the moment the
43
47
  // decision is made, and an event that states what it caused is what makes the
44
48
  // projection a pure mapping.
45
- | CatalogProductRelisted({productId: string, name: string, price: Reventless.Money.t})
49
+ | CatalogProductRelisted({
50
+ productId: CatalogSpec.ProductId.t,
51
+ name: string,
52
+ price: Reventless.Money.t,
53
+ })
46
54
  | CatalogProductImageChanged({
47
- productId: string,
55
+ productId: CatalogSpec.ProductId.t,
48
56
  @storageRef("Catalog.productImages") productImage?: Reventless.UploadableImage.t,
49
57
  })
@@ -3,6 +3,7 @@
3
3
  import * as Sury from "sury";
4
4
  import * as Money$Reventless from "@reventlessdev/reventless-spec/src/semantic/Money.res.mjs";
5
5
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
6
+ import * as ProductId$CatalogSpec from "@reventlessdev/online-shop-hybrid-catalog-spec/src/ProductId.res.mjs";
6
7
  import * as UploadableImage$Reventless from "@reventlessdev/reventless-spec/src/semantic/UploadableImage.res.mjs";
7
8
 
8
9
  let consumedEventSchema = Sury.union([
@@ -26,26 +27,26 @@ let consumedEventSchema = Sury.union([
26
27
  let commandSchema = Sury.union([
27
28
  Sury.$schema(s => ({
28
29
  TAG: "SyncNewProduct",
29
- productId: s.m(DcbTag$Reventless.string),
30
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
30
31
  name: s.m(Sury.string),
31
32
  price: s.m(Money$Reventless.schema)
32
33
  })),
33
34
  Sury.$schema(s => ({
34
35
  TAG: "ChangeSyncedPrice",
35
- productId: s.m(DcbTag$Reventless.string),
36
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
36
37
  price: s.m(Money$Reventless.schema)
37
38
  })),
38
39
  Sury.$schema(s => ({
39
40
  TAG: "WithdrawSyncedProduct",
40
- productId: s.m(DcbTag$Reventless.string)
41
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema))
41
42
  })),
42
43
  Sury.$schema(s => ({
43
44
  TAG: "RelistSyncedProduct",
44
- productId: s.m(DcbTag$Reventless.string)
45
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema))
45
46
  })),
46
47
  Sury.$schema(s => ({
47
48
  TAG: "ChangeSyncedProductImage",
48
- productId: s.m(DcbTag$Reventless.string),
49
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
49
50
  productImage: s.m(Sury.$option(UploadableImage$Reventless.forField("Catalog", "productImages")))
50
51
  }))
51
52
  ]);
@@ -55,28 +56,28 @@ let errorSchema = Sury.$unit;
55
56
  let eventSchema = Sury.union([
56
57
  Sury.$schema(s => ({
57
58
  TAG: "CatalogProductSynced",
58
- productId: s.m(DcbTag$Reventless.string),
59
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
59
60
  name: s.m(Sury.string),
60
61
  price: s.m(Money$Reventless.schema)
61
62
  })),
62
63
  Sury.$schema(s => ({
63
64
  TAG: "CatalogProductPriceChanged",
64
- productId: s.m(DcbTag$Reventless.string),
65
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
65
66
  price: s.m(Money$Reventless.schema)
66
67
  })),
67
68
  Sury.$schema(s => ({
68
69
  TAG: "CatalogProductWithdrawn",
69
- productId: s.m(DcbTag$Reventless.string)
70
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema))
70
71
  })),
71
72
  Sury.$schema(s => ({
72
73
  TAG: "CatalogProductRelisted",
73
- productId: s.m(DcbTag$Reventless.string),
74
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
74
75
  name: s.m(Sury.string),
75
76
  price: s.m(Money$Reventless.schema)
76
77
  })),
77
78
  Sury.$schema(s => ({
78
79
  TAG: "CatalogProductImageChanged",
79
- productId: s.m(DcbTag$Reventless.string),
80
+ productId: s.m(DcbTag$Reventless.mark(ProductId$CatalogSpec.schema)),
80
81
  productImage: s.m(Sury.$option(UploadableImage$Reventless.forField("Catalog", "productImages")))
81
82
  }))
82
83
  ]);
@@ -4,14 +4,25 @@
4
4
  // this denormalised mirror exists purely as an Ordering-side lookup target.
5
5
 
6
6
  @@reventless.spec
7
+
8
+ // Rows are keyed by this identity.
9
+ module Key = CatalogSpec.ProductId
7
10
  @@reventless.visibility(Internal)
8
11
 
9
12
  @schema
10
13
  type consumedEvent =
11
- | CatalogProductSynced({productId: string, name: string, price: Reventless.Money.t})
12
- | CatalogProductPriceChanged({productId: string, price: Reventless.Money.t})
13
- | CatalogProductWithdrawn({productId: string})
14
- | CatalogProductRelisted({productId: string, name: string, price: Reventless.Money.t})
14
+ | CatalogProductSynced({
15
+ productId: CatalogSpec.ProductId.t,
16
+ name: string,
17
+ price: Reventless.Money.t,
18
+ })
19
+ | CatalogProductPriceChanged({productId: CatalogSpec.ProductId.t, price: Reventless.Money.t})
20
+ | CatalogProductWithdrawn({productId: CatalogSpec.ProductId.t})
21
+ | CatalogProductRelisted({
22
+ productId: CatalogSpec.ProductId.t,
23
+ name: string,
24
+ price: Reventless.Money.t,
25
+ })
15
26
 
16
27
  @schema
17
- type state = {productId: string, name: string, price: Reventless.Money.t}
28
+ type state = {productId: CatalogSpec.ProductId.t, name: string, price: Reventless.Money.t}
@@ -3,34 +3,35 @@
3
3
  import * as Sury from "sury";
4
4
  import * as Money$Reventless from "@reventlessdev/reventless-spec/src/semantic/Money.res.mjs";
5
5
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
6
+ import * as ProductId$CatalogSpec from "@reventlessdev/online-shop-hybrid-catalog-spec/src/ProductId.res.mjs";
6
7
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
7
8
 
8
9
  let consumedEventSchema = Sury.union([
9
10
  Sury.$schema(s => ({
10
11
  TAG: "CatalogProductSynced",
11
- productId: s.m(Sury.string),
12
+ productId: s.m(ProductId$CatalogSpec.schema),
12
13
  name: s.m(Sury.string),
13
14
  price: s.m(Money$Reventless.schema)
14
15
  })),
15
16
  Sury.$schema(s => ({
16
17
  TAG: "CatalogProductPriceChanged",
17
- productId: s.m(Sury.string),
18
+ productId: s.m(ProductId$CatalogSpec.schema),
18
19
  price: s.m(Money$Reventless.schema)
19
20
  })),
20
21
  Sury.$schema(s => ({
21
22
  TAG: "CatalogProductWithdrawn",
22
- productId: s.m(Sury.string)
23
+ productId: s.m(ProductId$CatalogSpec.schema)
23
24
  })),
24
25
  Sury.$schema(s => ({
25
26
  TAG: "CatalogProductRelisted",
26
- productId: s.m(Sury.string),
27
+ productId: s.m(ProductId$CatalogSpec.schema),
27
28
  name: s.m(Sury.string),
28
29
  price: s.m(Money$Reventless.schema)
29
30
  }))
30
31
  ]);
31
32
 
32
33
  let stateSchema = Sury.$schema(s => ({
33
- productId: s.m(Sury.string),
34
+ productId: s.m(ProductId$CatalogSpec.schema),
34
35
  name: s.m(Sury.string),
35
36
  price: s.m(Money$Reventless.schema)
36
37
  }));
@@ -77,9 +78,9 @@ let visibility = "Internal";
77
78
  export {
78
79
  name,
79
80
  Id,
81
+ Key,
80
82
  consumedEventSchema,
81
83
  config,
82
- Key,
83
84
  subIdConfig,
84
85
  stateSchema$1 as stateSchema,
85
86
  moduleUrl,
@@ -3,6 +3,8 @@
3
3
 
4
4
  @@reventless.spec
5
5
 
6
+ module Id = CustomerId
7
+
6
8
  // A map coordinate carried by location commands/events. `GeoPoint.t` rather than
7
9
  // a local `{lat, lng}` record: the wire shape is identical — so every event
8
10
  // already stored decodes unchanged — and the declaration buys the range checks
@@ -0,0 +1,4 @@
1
+ // A customer's id: the partition its slices decide about, and an order's buyer.
2
+ include Reventless.Id.Make({
3
+ let key = "customerId"
4
+ })
@@ -0,0 +1,29 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
+
5
+ let include = Id$Reventless.Make({
6
+ key: "customerId"
7
+ });
8
+
9
+ let schema = include.schema;
10
+
11
+ let make = include.make;
12
+
13
+ let makeFromString = include.makeFromString;
14
+
15
+ let toString = include.toString;
16
+
17
+ let cmp = include.cmp;
18
+
19
+ let key = include.key;
20
+
21
+ export {
22
+ schema,
23
+ make,
24
+ makeFromString,
25
+ toString,
26
+ cmp,
27
+ key,
28
+ }
29
+ /* include Not a pure module */
@@ -22,7 +22,7 @@ type outboundItem = {customerId: string, email: string}
22
22
  @schema
23
23
  type inboundCommand =
24
24
  | IssueEmailChallenge({
25
- customerId: string,
25
+ customerId: CustomerId.t,
26
26
  email: string,
27
27
  purpose: string,
28
28
  proofHash: string,
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Sury from "sury";
4
4
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+ import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
5
6
 
6
7
  let consumedEventSchema = Sury.union([
7
8
  Sury.$schema(s => ({
@@ -22,7 +23,7 @@ let outboundItemSchema = Sury.$schema(s => ({
22
23
 
23
24
  let inboundCommandSchema = Sury.$schema(s => ({
24
25
  TAG: "IssueEmailChallenge",
25
- customerId: s.m(DcbTag$Reventless.string),
26
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
26
27
  email: s.m(Sury.string),
27
28
  purpose: s.m(Sury.string),
28
29
  proofHash: s.m(Sury.string),
@@ -50,7 +50,7 @@ let translate = async (_id, item: outboundItem, ~capabilities: Reventless.Capabi
50
50
  Some((
51
51
  item.customerId,
52
52
  IssueEmailChallenge({
53
- customerId: item.customerId,
53
+ customerId: CustomerId.makeFromString(item.customerId),
54
54
  email: item.email,
55
55
  purpose: "ContactChange",
56
56
  proofHash,
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Duration$Reventless from "@reventlessdev/reventless-spec/src/semantic/Duration.res.mjs";
4
4
  import * as Messaging$Reventless from "@reventlessdev/reventless-spec/src/semantic/Messaging.res.mjs";
5
+ import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
5
6
  import * as ContactVerification$OrderingPlugin from "../../ContactVerification.res.mjs";
6
7
 
7
8
  function collect(event, sourceId) {
@@ -60,7 +61,7 @@ async function translate(_id, item, capabilities) {
60
61
  item.customerId,
61
62
  {
62
63
  TAG: "IssueEmailChallenge",
63
- customerId: item.customerId,
64
+ customerId: CustomerId$OrderingPlugin.makeFromString(item.customerId),
64
65
  email: item.email,
65
66
  purpose: "ContactChange",
66
67
  proofHash: proofHash._0,
@@ -3,6 +3,8 @@
3
3
 
4
4
  @@reventless.spec
5
5
 
6
+ module Id = CustomerId
7
+
6
8
  // Operator surface: everyone's profile, so operator-only. A shopper reads their
7
9
  // own orders instead.
8
10
  @@reventless.authorize(AllowGroups(["Admin", "Fulfilment"]))
@@ -20,7 +22,7 @@ type accountStatus =
20
22
  // needed — the name matches the component.
21
23
  @schema
22
24
  type state = {
23
- customerId: string,
25
+ customerId: CustomerId.t,
24
26
  @displayName email: string,
25
27
  address: string,
26
28
  // The map pin is drawn from the `Located` arm's declared point. Not the
@@ -4,6 +4,7 @@ import * as Sury from "sury";
4
4
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
5
5
  import * as DisplayName$Reventless from "@reventlessdev/reventless-spec/src/components/DisplayName.res.mjs";
6
6
  import * as Geolocation$Reventless from "@reventlessdev/reventless-spec/src/semantic/Geolocation.res.mjs";
7
+ import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
7
8
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
8
9
 
9
10
  let accountStatusSchema = Sury.union([
@@ -12,13 +13,13 @@ let accountStatusSchema = Sury.union([
12
13
  ]);
13
14
 
14
15
  let stateSchema = Sury.$schema(s => ({
15
- customerId: s.m(Sury.string),
16
+ customerId: s.m(CustomerId$OrderingPlugin.schema),
16
17
  email: s.m(Sury.string),
17
18
  address: s.m(Sury.string),
18
19
  geolocation: s.m(Geolocation$Reventless.schema),
19
20
  accountStatus: s.m(accountStatusSchema),
20
- emailVerified: s.m(Sury.bool),
21
- orderCount: s.m(Sury.int),
21
+ emailVerified: s.m(Sury.boolean),
22
+ orderCount: s.m(Sury.int32),
22
23
  displayName: s.m(Sury.$option(Sury.string))
23
24
  }));
24
25
 
@@ -15,7 +15,7 @@ module OrderEvents = {
15
15
  let name = "OrderingDcbEventLog"
16
16
 
17
17
  @schema
18
- type event = OrderPlaced({orderId: string, customerId: string})
18
+ type event = OrderPlaced({orderId: OrderId.t, customerId: CustomerId.t})
19
19
  }
20
20
 
21
21
  // Source 1 — Customer aggregate (profile)
@@ -31,7 +31,7 @@ module CustomerMapping = Mapping.Make(
31
31
  UpdateWithDefault(
32
32
  id,
33
33
  {
34
- Customers.customerId: id->Customer.Id.toString,
34
+ Customers.customerId: id,
35
35
  email,
36
36
  address,
37
37
  geolocation: Pending({requestedFor: address}),
@@ -74,7 +74,7 @@ module CustomerOrdersMapping = Mapping.Make(
74
74
  switch event {
75
75
  | OrderPlaced({customerId}) =>
76
76
  UpdateWithDefault(
77
- Customers.Id.makeFromString(customerId),
77
+ customerId,
78
78
  {
79
79
  Customers.customerId,
80
80
  email: "",
@@ -4,11 +4,13 @@ import * as Sury from "sury";
4
4
  import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
5
5
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
6
6
  import * as Projection$Reventless from "@reventlessdev/reventless-spec/src/types/Projection.res.mjs";
7
+ import * as OrderId$OrderingPlugin from "../../Order/OrderId.res.mjs";
7
8
  import * as Customer$OrderingPlugin from "../Aggregate/Customer.res.mjs";
8
9
  import * as Customers$OrderingPlugin from "./Customers.res.mjs";
10
+ import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
9
11
 
10
12
  let M = Projection$Reventless.Mappings.Make({
11
- Id: Id$Reventless.$$String,
13
+ Id: CustomerId$OrderingPlugin,
12
14
  name: Customers$OrderingPlugin.name,
13
15
  stateSchema: Customers$OrderingPlugin.stateSchema,
14
16
  subIdConfig: undefined
@@ -18,8 +20,8 @@ let name = "OrderingDcbEventLog";
18
20
 
19
21
  let eventSchema = Sury.$schema(s => ({
20
22
  TAG: "OrderPlaced",
21
- orderId: s.m(DcbTag$Reventless.string),
22
- customerId: s.m(DcbTag$Reventless.string)
23
+ orderId: s.m(DcbTag$Reventless.mark(OrderId$OrderingPlugin.schema)),
24
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema))
23
25
  }));
24
26
 
25
27
  let OrderEvents = {
@@ -62,7 +64,7 @@ function project(param) {
62
64
  TAG: "UpdateWithDefault",
63
65
  _0: id,
64
66
  _1: {
65
- customerId: Id$Reventless.$$String.toString(id),
67
+ customerId: id,
66
68
  email: email,
67
69
  address: address,
68
70
  geolocation: {
@@ -166,11 +168,11 @@ function project(param) {
166
168
  }
167
169
 
168
170
  let CustomerMapping = Projection$Reventless.Mapping.Make({
169
- Id: Id$Reventless.$$String,
171
+ Id: CustomerId$OrderingPlugin,
170
172
  name: Customer$OrderingPlugin.name,
171
173
  eventSchema: Customer$OrderingPlugin.eventSchema
172
174
  })({
173
- Id: Id$Reventless.$$String,
175
+ Id: CustomerId$OrderingPlugin,
174
176
  name: Customers$OrderingPlugin.name,
175
177
  stateSchema: Customers$OrderingPlugin.stateSchema,
176
178
  subIdConfig: undefined
@@ -182,7 +184,7 @@ function project$1(param) {
182
184
  let customerId = param.event.customerId;
183
185
  return {
184
186
  TAG: "UpdateWithDefault",
185
- _0: Id$Reventless.$$String.makeFromString(customerId),
187
+ _0: customerId,
186
188
  _1: {
187
189
  customerId: customerId,
188
190
  email: "",
@@ -208,7 +210,7 @@ let CustomerOrdersMapping = Projection$Reventless.Mapping.Make({
208
210
  name: name,
209
211
  eventSchema: eventSchema
210
212
  })({
211
- Id: Id$Reventless.$$String,
213
+ Id: CustomerId$OrderingPlugin,
212
214
  name: Customers$OrderingPlugin.name,
213
215
  stateSchema: Customers$OrderingPlugin.stateSchema,
214
216
  subIdConfig: undefined
@@ -22,14 +22,14 @@
22
22
  @schema
23
23
  type consumedEvent =
24
24
  | EmailChallengeIssued({
25
- customerId: string,
25
+ customerId: CustomerId.t,
26
26
  email: string,
27
27
  purpose: string,
28
28
  proofHash: string,
29
29
  issuedAt: string,
30
30
  })
31
- | EmailProofAccepted({customerId: string, email: string})
32
- | EmailProofRefused({customerId: string, email: string, reason: string})
31
+ | EmailProofAccepted({customerId: CustomerId.t, email: string})
32
+ | EmailProofRefused({customerId: CustomerId.t, email: string, reason: string})
33
33
 
34
34
  @schema
35
35
  type command =
@@ -37,7 +37,7 @@ type command =
37
37
  // caller who could issue challenges could send mail to any address they liked.
38
38
  | @noApi
39
39
  IssueEmailChallenge({
40
- customerId: string,
40
+ customerId: CustomerId.t,
41
41
  email: string,
42
42
  purpose: string,
43
43
  proofHash: string,
@@ -50,7 +50,12 @@ type command =
50
50
  // authorization fits. Registration is the case that does not: the caller is
51
51
  // trying to *become* someone, and a component that brings a door cannot yet
52
52
  // declare that the door is open to the unauthenticated.
53
- | SubmitEmailProof({customerId: string, email: string, proofHash: string, presentedAt: string})
53
+ | SubmitEmailProof({
54
+ customerId: CustomerId.t,
55
+ email: string,
56
+ proofHash: string,
57
+ presentedAt: string,
58
+ })
54
59
 
55
60
  @schema
56
61
  type error =
@@ -63,11 +68,11 @@ type error =
63
68
  @schema
64
69
  type event =
65
70
  | EmailChallengeIssued({
66
- customerId: string,
71
+ customerId: CustomerId.t,
67
72
  email: string,
68
73
  purpose: string,
69
74
  proofHash: string,
70
75
  issuedAt: string,
71
76
  })
72
- | EmailProofAccepted({customerId: string, email: string})
73
- | EmailProofRefused({customerId: string, email: string, reason: string})
77
+ | EmailProofAccepted({customerId: CustomerId.t, email: string})
78
+ | EmailProofRefused({customerId: CustomerId.t, email: string, reason: string})
@@ -3,11 +3,12 @@
3
3
  import * as Sury from "sury";
4
4
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
5
  import * as Api$ReventlessInfra from "@reventlessdev/reventless-infra/src/components/Api.res.mjs";
6
+ import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
6
7
 
7
8
  let consumedEventSchema = Sury.union([
8
9
  Sury.$schema(s => ({
9
10
  TAG: "EmailChallengeIssued",
10
- customerId: s.m(DcbTag$Reventless.string),
11
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
11
12
  email: s.m(Sury.string),
12
13
  purpose: s.m(Sury.string),
13
14
  proofHash: s.m(Sury.string),
@@ -15,12 +16,12 @@ let consumedEventSchema = Sury.union([
15
16
  })),
16
17
  Sury.$schema(s => ({
17
18
  TAG: "EmailProofAccepted",
18
- customerId: s.m(DcbTag$Reventless.string),
19
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
19
20
  email: s.m(Sury.string)
20
21
  })),
21
22
  Sury.$schema(s => ({
22
23
  TAG: "EmailProofRefused",
23
- customerId: s.m(DcbTag$Reventless.string),
24
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
24
25
  email: s.m(Sury.string),
25
26
  reason: s.m(Sury.string)
26
27
  }))
@@ -29,7 +30,7 @@ let consumedEventSchema = Sury.union([
29
30
  let commandSchema = Sury.union([
30
31
  Sury.$schema(s => ({
31
32
  TAG: "IssueEmailChallenge",
32
- customerId: s.m(DcbTag$Reventless.string),
33
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
33
34
  email: s.m(Sury.string),
34
35
  purpose: s.m(Sury.string),
35
36
  proofHash: s.m(Sury.string),
@@ -37,7 +38,7 @@ let commandSchema = Sury.union([
37
38
  })),
38
39
  Sury.$schema(s => ({
39
40
  TAG: "SubmitEmailProof",
40
- customerId: s.m(DcbTag$Reventless.string),
41
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
41
42
  email: s.m(Sury.string),
42
43
  proofHash: s.m(Sury.string),
43
44
  presentedAt: s.m(Sury.string)
@@ -49,7 +50,7 @@ let errorSchema = Sury.literal("NoChallengeOutstanding");
49
50
  let eventSchema = Sury.union([
50
51
  Sury.$schema(s => ({
51
52
  TAG: "EmailChallengeIssued",
52
- customerId: s.m(DcbTag$Reventless.string),
53
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
53
54
  email: s.m(Sury.string),
54
55
  purpose: s.m(Sury.string),
55
56
  proofHash: s.m(Sury.string),
@@ -57,12 +58,12 @@ let eventSchema = Sury.union([
57
58
  })),
58
59
  Sury.$schema(s => ({
59
60
  TAG: "EmailProofAccepted",
60
- customerId: s.m(DcbTag$Reventless.string),
61
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
61
62
  email: s.m(Sury.string)
62
63
  })),
63
64
  Sury.$schema(s => ({
64
65
  TAG: "EmailProofRefused",
65
- customerId: s.m(DcbTag$Reventless.string),
66
+ customerId: s.m(DcbTag$Reventless.mark(CustomerId$OrderingPlugin.schema)),
66
67
  email: s.m(Sury.string),
67
68
  reason: s.m(Sury.string)
68
69
  }))