@reventlessdev/online-shop-aggregates-ordering 3.0.0-alpha.249 → 3.0.0-alpha.251

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 (165) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/lib/bs/.compiler.log +2 -2
  3. package/lib/bs/OrderingPlugin.cmi +0 -0
  4. package/lib/bs/OrderingPlugin.cmt +0 -0
  5. package/lib/bs/OrderingPlugin.mlmap +1 -0
  6. package/lib/bs/compiler-info.json +1 -1
  7. package/lib/bs/src/CatalogProduct/Aggregate/CatalogProduct_Behavior-OrderingPlugin.cmi +0 -0
  8. package/lib/bs/src/CatalogProduct/Aggregate/CatalogProduct_Behavior-OrderingPlugin.cmt +0 -0
  9. package/lib/bs/src/Customer/Aggregate/Customer_Behavior-OrderingPlugin.cmi +0 -0
  10. package/lib/bs/src/Customer/Aggregate/Customer_Behavior-OrderingPlugin.cmt +0 -0
  11. package/lib/bs/src/Customer/ReadModel/Customers_Projections-OrderingPlugin.cmi +0 -0
  12. package/lib/bs/src/Customer/ReadModel/Customers_Projections-OrderingPlugin.cmt +0 -0
  13. package/lib/bs/src/Extension/Products_Extension-OrderingPlugin.cmi +0 -0
  14. package/lib/bs/src/Extension/Products_Extension-OrderingPlugin.cmt +0 -0
  15. package/lib/bs/src/ExtensionPoint/Orders_ExtensionPointMapping-OrderingPlugin.cmi +0 -0
  16. package/lib/bs/src/ExtensionPoint/Orders_ExtensionPointMapping-OrderingPlugin.cmt +0 -0
  17. package/lib/bs/src/Order/Aggregate/Order-OrderingPlugin.cmi +0 -0
  18. package/lib/bs/src/Order/Aggregate/Order-OrderingPlugin.cmt +0 -0
  19. package/lib/bs/src/Order/Aggregate/Order_Behavior-OrderingPlugin.cmi +0 -0
  20. package/lib/bs/src/Order/Aggregate/Order_Behavior-OrderingPlugin.cmt +0 -0
  21. package/lib/bs/src/Order/Aggregate/Order_Mappings-OrderingPlugin.cmi +0 -0
  22. package/lib/bs/src/Order/Aggregate/Order_Mappings-OrderingPlugin.cmt +0 -0
  23. package/lib/bs/src/Order/ReadModel/Orders_Projections-OrderingPlugin.cmi +0 -0
  24. package/lib/bs/src/Order/ReadModel/Orders_Projections-OrderingPlugin.cmt +0 -0
  25. package/lib/bs/src/Order/SideEffect/Order_EmailNotification-OrderingPlugin.cmi +0 -0
  26. package/lib/bs/src/Order/SideEffect/Order_EmailNotification-OrderingPlugin.cmt +0 -0
  27. package/lib/bs/src/Plugin-OrderingPlugin.cmi +0 -0
  28. package/lib/bs/src/Plugin-OrderingPlugin.cmt +0 -0
  29. package/lib/bs/src/Task/OrderNotifications-OrderingPlugin.cmi +0 -0
  30. package/lib/bs/src/Task/OrderNotifications-OrderingPlugin.cmt +0 -0
  31. package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT-OrderingPlugin.cmi +0 -0
  32. package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT-OrderingPlugin.cmt +0 -0
  33. package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.ast +0 -0
  34. package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res +11 -5
  35. package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res.mjs +6 -5
  36. package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT-OrderingPlugin.cmt +0 -0
  37. package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.ast +0 -0
  38. package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.res +2 -0
  39. package/lib/bs/tests/Customer/Aggregate/Customer_GWT-OrderingPlugin.cmi +0 -0
  40. package/lib/bs/tests/Customer/Aggregate/Customer_GWT-OrderingPlugin.cmt +0 -0
  41. package/lib/bs/tests/Customer/Aggregate/Customer_GWT.ast +0 -0
  42. package/lib/bs/tests/Customer/Aggregate/Customer_GWT.res +32 -17
  43. package/lib/bs/tests/Customer/Aggregate/Customer_GWT.res.mjs +31 -30
  44. package/lib/bs/tests/Customer/ReadModel/Customers_GWT-OrderingPlugin.cmi +0 -0
  45. package/lib/bs/tests/Customer/ReadModel/Customers_GWT-OrderingPlugin.cmt +0 -0
  46. package/lib/bs/tests/Customer/ReadModel/Customers_GWT.ast +0 -0
  47. package/lib/bs/tests/Customer/ReadModel/Customers_GWT.res +4 -0
  48. package/lib/bs/tests/Extension/Products_Extension_GWT-OrderingPlugin.cmi +0 -0
  49. package/lib/bs/tests/Extension/Products_Extension_GWT-OrderingPlugin.cmt +0 -0
  50. package/lib/bs/tests/Extension/Products_Extension_GWT.ast +0 -0
  51. package/lib/bs/tests/Extension/Products_Extension_GWT.res +3 -2
  52. package/lib/bs/tests/Extension/Products_Extension_GWT.res.mjs +3 -5
  53. package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmi +0 -0
  54. package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmt +0 -0
  55. package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.ast +0 -0
  56. package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +5 -3
  57. package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +6 -16
  58. package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT-OrderingPlugin.cmi +0 -0
  59. package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT-OrderingPlugin.cmt +0 -0
  60. package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT.ast +0 -0
  61. package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT.res +4 -0
  62. package/lib/bs/tests/Order/Aggregate/Order_GWT-OrderingPlugin.cmi +0 -0
  63. package/lib/bs/tests/Order/Aggregate/Order_GWT-OrderingPlugin.cmt +0 -0
  64. package/lib/bs/tests/Order/Aggregate/Order_GWT.ast +0 -0
  65. package/lib/bs/tests/Order/Aggregate/Order_GWT.res +24 -5
  66. package/lib/bs/tests/Order/Aggregate/Order_GWT.res.mjs +6 -5
  67. package/lib/bs/tests/Order/ReadModel/Orders_GWT-OrderingPlugin.cmi +0 -0
  68. package/lib/bs/tests/Order/ReadModel/Orders_GWT-OrderingPlugin.cmt +0 -0
  69. package/lib/bs/tests/Order/ReadModel/Orders_GWT.ast +0 -0
  70. package/lib/bs/tests/Order/ReadModel/Orders_GWT.res +4 -0
  71. package/lib/bs/tests/Order/SideEffect/Order_EmailNotification_GWT-OrderingPlugin.cmi +0 -0
  72. package/lib/bs/tests/Order/SideEffect/Order_EmailNotification_GWT-OrderingPlugin.cmt +0 -0
  73. package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmi +0 -0
  74. package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmj +0 -0
  75. package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmt +0 -0
  76. package/lib/bs/tests/Ordering_Examples.ast +0 -0
  77. package/lib/bs/tests/Ordering_Examples.res +13 -0
  78. package/lib/bs/tests/Ordering_Examples.res.mjs +35 -0
  79. package/lib/ocaml/.compiler.log +2 -2
  80. package/lib/ocaml/AvailableProducts_GWT-OrderingPlugin.cmt +0 -0
  81. package/lib/ocaml/AvailableProducts_GWT.ast +0 -0
  82. package/lib/ocaml/AvailableProducts_GWT.res +2 -0
  83. package/lib/ocaml/CatalogProduct_Behavior-OrderingPlugin.cmi +0 -0
  84. package/lib/ocaml/CatalogProduct_Behavior-OrderingPlugin.cmt +0 -0
  85. package/lib/ocaml/CatalogProduct_GWT-OrderingPlugin.cmi +0 -0
  86. package/lib/ocaml/CatalogProduct_GWT-OrderingPlugin.cmt +0 -0
  87. package/lib/ocaml/CatalogProduct_GWT.ast +0 -0
  88. package/lib/ocaml/CatalogProduct_GWT.res +11 -5
  89. package/lib/ocaml/Customer_Behavior-OrderingPlugin.cmi +0 -0
  90. package/lib/ocaml/Customer_Behavior-OrderingPlugin.cmt +0 -0
  91. package/lib/ocaml/Customer_GWT-OrderingPlugin.cmi +0 -0
  92. package/lib/ocaml/Customer_GWT-OrderingPlugin.cmt +0 -0
  93. package/lib/ocaml/Customer_GWT.ast +0 -0
  94. package/lib/ocaml/Customer_GWT.res +32 -17
  95. package/lib/ocaml/Customers_GWT-OrderingPlugin.cmi +0 -0
  96. package/lib/ocaml/Customers_GWT-OrderingPlugin.cmt +0 -0
  97. package/lib/ocaml/Customers_GWT.ast +0 -0
  98. package/lib/ocaml/Customers_GWT.res +4 -0
  99. package/lib/ocaml/Customers_Projections-OrderingPlugin.cmi +0 -0
  100. package/lib/ocaml/Customers_Projections-OrderingPlugin.cmt +0 -0
  101. package/lib/ocaml/Order-OrderingPlugin.cmi +0 -0
  102. package/lib/ocaml/Order-OrderingPlugin.cmt +0 -0
  103. package/lib/ocaml/OrderMappings_GWT-OrderingPlugin.cmi +0 -0
  104. package/lib/ocaml/OrderMappings_GWT-OrderingPlugin.cmt +0 -0
  105. package/lib/ocaml/OrderMappings_GWT.ast +0 -0
  106. package/lib/ocaml/OrderMappings_GWT.res +4 -0
  107. package/lib/ocaml/OrderNotifications-OrderingPlugin.cmi +0 -0
  108. package/lib/ocaml/OrderNotifications-OrderingPlugin.cmt +0 -0
  109. package/lib/ocaml/Order_Behavior-OrderingPlugin.cmi +0 -0
  110. package/lib/ocaml/Order_Behavior-OrderingPlugin.cmt +0 -0
  111. package/lib/ocaml/Order_EmailNotification-OrderingPlugin.cmi +0 -0
  112. package/lib/ocaml/Order_EmailNotification-OrderingPlugin.cmt +0 -0
  113. package/lib/ocaml/Order_EmailNotification_GWT-OrderingPlugin.cmi +0 -0
  114. package/lib/ocaml/Order_EmailNotification_GWT-OrderingPlugin.cmt +0 -0
  115. package/lib/ocaml/Order_GWT-OrderingPlugin.cmi +0 -0
  116. package/lib/ocaml/Order_GWT-OrderingPlugin.cmt +0 -0
  117. package/lib/ocaml/Order_GWT.ast +0 -0
  118. package/lib/ocaml/Order_GWT.res +24 -5
  119. package/lib/ocaml/Order_Mappings-OrderingPlugin.cmi +0 -0
  120. package/lib/ocaml/Order_Mappings-OrderingPlugin.cmt +0 -0
  121. package/lib/ocaml/OrderingPlugin.cmi +0 -0
  122. package/lib/ocaml/OrderingPlugin.cmt +0 -0
  123. package/lib/ocaml/OrderingPlugin.mlmap +1 -0
  124. package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmi +0 -0
  125. package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmj +0 -0
  126. package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmt +0 -0
  127. package/lib/ocaml/Ordering_Examples.ast +0 -0
  128. package/lib/ocaml/Ordering_Examples.res +13 -0
  129. package/lib/ocaml/Orders_ExtensionPointMapping-OrderingPlugin.cmi +0 -0
  130. package/lib/ocaml/Orders_ExtensionPointMapping-OrderingPlugin.cmt +0 -0
  131. package/lib/ocaml/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmi +0 -0
  132. package/lib/ocaml/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmt +0 -0
  133. package/lib/ocaml/Orders_ExtensionPointMapping_GWT.ast +0 -0
  134. package/lib/ocaml/Orders_ExtensionPointMapping_GWT.res +5 -3
  135. package/lib/ocaml/Orders_GWT-OrderingPlugin.cmi +0 -0
  136. package/lib/ocaml/Orders_GWT-OrderingPlugin.cmt +0 -0
  137. package/lib/ocaml/Orders_GWT.ast +0 -0
  138. package/lib/ocaml/Orders_GWT.res +4 -0
  139. package/lib/ocaml/Orders_Projections-OrderingPlugin.cmi +0 -0
  140. package/lib/ocaml/Orders_Projections-OrderingPlugin.cmt +0 -0
  141. package/lib/ocaml/Plugin-OrderingPlugin.cmi +0 -0
  142. package/lib/ocaml/Plugin-OrderingPlugin.cmt +0 -0
  143. package/lib/ocaml/Products_Extension-OrderingPlugin.cmi +0 -0
  144. package/lib/ocaml/Products_Extension-OrderingPlugin.cmt +0 -0
  145. package/lib/ocaml/Products_Extension_GWT-OrderingPlugin.cmi +0 -0
  146. package/lib/ocaml/Products_Extension_GWT-OrderingPlugin.cmt +0 -0
  147. package/lib/ocaml/Products_Extension_GWT.ast +0 -0
  148. package/lib/ocaml/Products_Extension_GWT.res +3 -2
  149. package/package.json +8 -8
  150. package/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res +11 -5
  151. package/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res.mjs +6 -5
  152. package/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.res +2 -0
  153. package/tests/Customer/Aggregate/Customer_GWT.res +32 -17
  154. package/tests/Customer/Aggregate/Customer_GWT.res.mjs +31 -30
  155. package/tests/Customer/ReadModel/Customers_GWT.res +4 -0
  156. package/tests/Extension/Products_Extension_GWT.res +3 -2
  157. package/tests/Extension/Products_Extension_GWT.res.mjs +3 -5
  158. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +5 -3
  159. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +6 -16
  160. package/tests/Order/Aggregate/OrderMappings_GWT.res +4 -0
  161. package/tests/Order/Aggregate/Order_GWT.res +24 -5
  162. package/tests/Order/Aggregate/Order_GWT.res.mjs +6 -5
  163. package/tests/Order/ReadModel/Orders_GWT.res +4 -0
  164. package/tests/Ordering_Examples.res +13 -0
  165. package/tests/Ordering_Examples.res.mjs +35 -0
Binary file
@@ -22,6 +22,7 @@ let prod1 = CatalogSpec.ProductId.make("prod-1")
22
22
  let placedEvent = Order.Placed({customerId: cust1, productIds: [prod1]})
23
23
 
24
24
  describe("Order auto-ship mapping (Placed → Ship)", () => {
25
+ // scenario-id: 2fd227c7-248e-47be-939a-467bceeb8796
25
26
  test("Place → AutoShipMapping issues Ship → target emits Shipped", () =>
26
27
  givenSourceEvents([])
27
28
  ->andTargetEvents([("order-1", [placedEvent])])
@@ -29,6 +30,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
29
30
  ->thenTargetEvent("order-1", Order.Shipped)
30
31
  )
31
32
 
33
+ // scenario-id: 366966a9-f65a-44cf-9bd2-4df7ef7bced4
32
34
  test("Ship command does not fire the mapping (only Placed events do)", () =>
33
35
  givenSourceEvents([placedEvent])
34
36
  ->andTargetEvents([("order-1", [placedEvent])])
@@ -36,6 +38,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
36
38
  ->thenNoTargetEvent
37
39
  )
38
40
 
41
+ // scenario-id: c6203367-d2ff-4903-b1a2-8cc259ec62ee
39
42
  test("Cancel command does not fire the mapping", () =>
40
43
  givenSourceEvents([placedEvent])
41
44
  ->andTargetEvents([("order-1", [placedEvent])])
@@ -43,6 +46,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
43
46
  ->thenNoTargetEvent
44
47
  )
45
48
 
49
+ // scenario-id: d20d610d-7ec8-4767-8d88-4556c1bf7059
46
50
  test("Refund command does not fire the mapping (only Placed events do)", () =>
47
51
  givenSourceEvents([placedEvent, Order.Cancelled({productIds: [prod1]})])
48
52
  ->andTargetEvents([("order-1", [placedEvent, Order.Cancelled({productIds: [prod1]})])])
Binary file
@@ -1,29 +1,35 @@
1
1
  @@reventless.gwt
2
2
 
3
+ open Ordering_Examples
4
+
3
5
  // Ids are typed; the literals are made once, here.
4
6
  let cust1 = CustomerId.make("cust-1")
5
7
  let prod1 = CatalogSpec.ProductId.make("prod-1")
6
8
  let prod2 = CatalogSpec.ProductId.make("prod-2")
7
9
 
8
10
  describe("Order Behavior", () => {
11
+ // scenario-id: 4f723805-10e2-4b72-b40a-6cf71e91c375
9
12
  test("Place on new aggregate produces Placed", () =>
10
13
  givenEvents([])
11
14
  ->whenCmd(Place({customerId: cust1, productIds: [prod1, prod2]}))
12
15
  ->thenEvent(Placed({customerId: cust1, productIds: [prod1, prod2]}))
13
16
  )
14
17
 
18
+ // scenario-id: 061fb189-7195-474f-8010-0a0339d7cf11
15
19
  test("Place on existing order returns OrderAlreadyPlaced", () =>
16
20
  givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
17
21
  ->whenCmd(Place({customerId: cust1, productIds: [prod1]}))
18
22
  ->thenError(OrderAlreadyPlaced)
19
23
  )
20
24
 
25
+ // scenario-id: 3cb519a2-53ba-4f66-938f-2d5e4a3b736b
21
26
  test("Place on shipped order returns OrderAlreadyShipped", () =>
22
27
  givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
23
28
  ->whenCmd(Place({customerId: cust1, productIds: [prod1]}))
24
29
  ->thenError(OrderAlreadyShipped)
25
30
  )
26
31
 
32
+ // scenario-id: e74bad7c-abe6-4313-9290-b20f75897285
27
33
  test("Place on cancelled order returns OrderAlreadyCancelled", () =>
28
34
  givenEvents([
29
35
  Placed({customerId: cust1, productIds: [prod1]}),
@@ -33,24 +39,28 @@ describe("Order Behavior", () => {
33
39
  ->thenError(OrderAlreadyCancelled)
34
40
  )
35
41
 
42
+ // scenario-id: 1e97733f-32dd-473a-86e9-6c2cfec8f813
36
43
  test("Ship on non-existent order returns OrderNotFound", () =>
37
44
  givenEvents([])
38
45
  ->whenCmd(Ship)
39
46
  ->thenError(OrderNotFound)
40
47
  )
41
48
 
49
+ // scenario-id: 54073db7-f835-4d89-a648-71b6dc4869c2
42
50
  test("Ship on placed order produces Shipped", () =>
43
51
  givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
44
52
  ->whenCmd(Ship)
45
53
  ->thenEvent(Shipped)
46
54
  )
47
55
 
56
+ // scenario-id: 2d4c200e-ece6-40c4-a67d-460f5beca59e
48
57
  test("Ship on shipped order produces no events (idempotent)", () =>
49
58
  givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
50
59
  ->whenCmd(Ship)
51
60
  ->thenNoEvent
52
61
  )
53
62
 
63
+ // scenario-id: 08783980-65d7-4114-b4ef-f0f95b0b3fc5
54
64
  test("Ship on cancelled order returns OrderAlreadyCancelled", () =>
55
65
  givenEvents([
56
66
  Placed({customerId: cust1, productIds: [prod1]}),
@@ -60,24 +70,28 @@ describe("Order Behavior", () => {
60
70
  ->thenError(OrderAlreadyCancelled)
61
71
  )
62
72
 
73
+ // scenario-id: 2104ec68-2de0-464b-b8f8-379f47b03db9
63
74
  test("Cancel on non-existent order returns OrderNotFound", () =>
64
75
  givenEvents([])
65
76
  ->whenCmd(Cancel)
66
77
  ->thenError(OrderNotFound)
67
78
  )
68
79
 
80
+ // scenario-id: 3d974a23-5eb6-4463-9824-e61b0fa5a278
69
81
  test("Cancel on placed order produces Cancelled", () =>
70
82
  givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
71
83
  ->whenCmd(Cancel)
72
84
  ->thenEvent(Cancelled({productIds: [prod1]}))
73
85
  )
74
86
 
87
+ // scenario-id: 6144fcb7-d768-4237-9e67-e530c736210d
75
88
  test("Cancel on shipped order returns OrderAlreadyShipped", () =>
76
89
  givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
77
90
  ->whenCmd(Cancel)
78
91
  ->thenError(OrderAlreadyShipped)
79
92
  )
80
93
 
94
+ // scenario-id: 07679806-2e68-4cdb-b8c0-8cc67bd65fa7
81
95
  test("Cancel on cancelled order produces no events (idempotent)", () =>
82
96
  givenEvents([
83
97
  Placed({customerId: cust1, productIds: [prod1]}),
@@ -87,40 +101,45 @@ describe("Order Behavior", () => {
87
101
  ->thenNoEvent
88
102
  )
89
103
 
104
+ // scenario-id: aa624dbf-659b-4685-8695-4203e23a855f
90
105
  test("Refund on non-existent order returns OrderNotFound", () =>
91
106
  givenEvents([])
92
107
  ->whenCmd(Refund({reason: "lost-in-transit"}))
93
108
  ->thenError(OrderNotFound)
94
109
  )
95
110
 
111
+ // scenario-id: cf56897b-1cf0-4768-8ada-eae11c069d95
96
112
  test("Refund on placed order returns OrderNotCancelled", () =>
97
113
  givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
98
- ->whenCmd(Refund({reason: "customer-changed-mind"}))
114
+ ->whenCmd(Refund({reason: changedMind}))
99
115
  ->thenError(OrderNotCancelled)
100
116
  )
101
117
 
118
+ // scenario-id: 802fb4a7-3768-4c6d-8a54-444f44891515
102
119
  test("Refund on shipped order returns OrderNotCancelled", () =>
103
120
  givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
104
121
  ->whenCmd(Refund({reason: "delivered-damaged"}))
105
122
  ->thenError(OrderNotCancelled)
106
123
  )
107
124
 
125
+ // scenario-id: d9f7692d-4d64-41d9-b845-f5958fe95bc0
108
126
  test("Refund on cancelled order produces Refunded", () =>
109
127
  givenEvents([
110
128
  Placed({customerId: cust1, productIds: [prod1]}),
111
129
  Cancelled({productIds: [prod1]}),
112
130
  ])
113
- ->whenCmd(Refund({reason: "customer-changed-mind"}))
114
- ->thenEvent(Refunded({reason: "customer-changed-mind"}))
131
+ ->whenCmd(Refund({reason: changedMind}))
132
+ ->thenEvent(Refunded({reason: changedMind}))
115
133
  )
116
134
 
135
+ // scenario-id: 4ced8701-2214-4f05-89ed-057b130979ad
117
136
  test("Refund on already-refunded order produces no events (idempotent)", () =>
118
137
  givenEvents([
119
138
  Placed({customerId: cust1, productIds: [prod1]}),
120
139
  Cancelled({productIds: [prod1]}),
121
- Refunded({reason: "customer-changed-mind"}),
140
+ Refunded({reason: changedMind}),
122
141
  ])
123
- ->whenCmd(Refund({reason: "customer-changed-mind"}))
142
+ ->whenCmd(Refund({reason: changedMind}))
124
143
  ->thenNoEvent
125
144
  )
126
145
  })
Binary file
Binary file
@@ -24,6 +24,7 @@ Order_EmailNotification
24
24
  Order_EmailNotification_GWT
25
25
  Order_GWT
26
26
  Order_Mappings
27
+ Ordering_Examples
27
28
  Orders
28
29
  Orders_ExtensionPointMapping
29
30
  Orders_ExtensionPointMapping_GWT
Binary file
@@ -0,0 +1,13 @@
1
+ @@reventless.examples
2
+
3
+ let p1: CatalogSpec.ProductId.t = CatalogSpec.ProductId.makeFromString("p1")
4
+ let p2: CatalogSpec.ProductId.t = CatalogSpec.ProductId.makeFromString("p2")
5
+
6
+ let c1: CustomerId.t = CustomerId.makeFromString("c1")
7
+
8
+ let aliceEmail: string = "alice@example.com"
9
+ let bobEmail: string = "bob@example.com"
10
+ let changedMind: string = "customer-changed-mind"
11
+ let laptop: string = "Laptop"
12
+ let mainStreet: string = "123 Main St"
13
+ let oakAvenue: string = "456 Oak Ave"
@@ -2,11 +2,10 @@
2
2
  // into one public per-product event each (one-to-many fan-out).
3
3
  @@reventless.gwt
4
4
 
5
- let c1 = CustomerId.make("c1")
6
- let p1 = CatalogSpec.ProductId.make("p1")
7
- let p2 = CatalogSpec.ProductId.make("p2")
5
+ open Ordering_Examples
8
6
 
9
7
  describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
8
+ // scenario-id: b3fe53fe-84bd-4bb7-aca3-a0f9db5a186f
10
9
  test("Placed fans out to one ItemOrdered per product", () =>
11
10
  whenDelegateEvent(
12
11
  Delegate.Placed({customerId: c1, productIds: [p1, p2]}),
@@ -16,6 +15,7 @@ describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
16
15
  ])
17
16
  )
18
17
 
18
+ // scenario-id: c916b814-2006-4d62-9fff-60bb99ddcfd3
19
19
  test("Cancelled fans out to one ItemOrderCancelled per product", () =>
20
20
  whenDelegateEvent(Delegate.Cancelled({productIds: [p1, p2]}))->thenPublishesEvents([
21
21
  ("p1", ExtensionPoint.ItemOrderCancelled({productId: "p1", orderId: "gwt-id"})),
@@ -23,8 +23,10 @@ describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
23
23
  ])
24
24
  )
25
25
 
26
+ // scenario-id: 3647a0be-51ed-4d6d-83b3-9fa53a596e49
26
27
  test("Shipped publishes nothing", () => whenDelegateEvent(Delegate.Shipped)->thenPublishesNothing)
27
28
 
29
+ // scenario-id: 0ac71311-60e6-4373-b078-96cfaf91724d
28
30
  test("Refunded publishes nothing", () =>
29
31
  whenDelegateEvent(Delegate.Refunded({reason: "customer-changed-mind"}))->thenPublishesNothing
30
32
  )
Binary file
@@ -6,6 +6,7 @@ let prod1 = CatalogSpec.ProductId.make("prod-1")
6
6
  let prod2 = CatalogSpec.ProductId.make("prod-2")
7
7
 
8
8
  describe("Orders ReadModel ← Order", () => {
9
+ // scenario-id: 94f5938c-adf9-42c2-8986-1204e0aa0710
9
10
  test("Placed sets initial read model state", () =>
10
11
  givenEvents([])
11
12
  ->whenEvent(Order.Placed({customerId: cust1, productIds: [prod1, prod2]}))
@@ -16,6 +17,7 @@ describe("Orders ReadModel ← Order", () => {
16
17
  })
17
18
  )
18
19
 
20
+ // scenario-id: 4b7e916e-e7db-4c00-9337-9e2fe4104c93
19
21
  test("Shipped updates status", () =>
20
22
  givenEvents([Order.Placed({customerId: cust1, productIds: [prod1]})])
21
23
  ->whenEvent(Order.Shipped)
@@ -26,6 +28,7 @@ describe("Orders ReadModel ← Order", () => {
26
28
  })
27
29
  )
28
30
 
31
+ // scenario-id: a56314fa-907f-425a-80e6-a7ea1a27d6c9
29
32
  test("Cancelled updates status", () =>
30
33
  givenEvents([Order.Placed({customerId: cust1, productIds: [prod1]})])
31
34
  ->whenEvent(Order.Cancelled({productIds: [prod1]}))
@@ -36,6 +39,7 @@ describe("Orders ReadModel ← Order", () => {
36
39
  })
37
40
  )
38
41
 
42
+ // scenario-id: 96902cd1-2eae-4a35-b5c6-6d28dc9acda7
39
43
  test("Refunded updates status", () =>
40
44
  givenEvents([
41
45
  Order.Placed({customerId: cust1, productIds: [prod1]}),
Binary file
Binary file
@@ -5,16 +5,17 @@
5
5
  // `Mapping` is brought into scope by the PPX `open Products_Extension`; opening
6
6
  // it surfaces the extension point's events and the delegate's commands.
7
7
  open Mapping
8
-
9
- let p1 = CatalogSpec.ProductId.make("p1")
8
+ open Ordering_Examples
10
9
 
11
10
  describe("Products Extension delegate", () => {
11
+ // scenario-id: 4c14eb06-02b8-41ae-b0b8-cf33ef430e93
12
12
  test("ProductBecameAvailable issues Sync", () =>
13
13
  whenIncomingEvent(
14
14
  ExtensionPoint.ProductBecameAvailable({productId: p1, name: "Book", price: 9.99}),
15
15
  )->thenPublishesAggregateCommand("p1", Delegate.Sync({name: "Book", price: 9.99}))
16
16
  )
17
17
 
18
+ // scenario-id: d3760e9e-c4f6-4a2f-bb5a-8e57a965ba68
18
19
  test("ProductPriceChanged issues UpdatePrice", () =>
19
20
  whenIncomingEvent(
20
21
  ExtensionPoint.ProductPriceChanged({productId: p1, price: 7.5}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/online-shop-aggregates-ordering",
3
- "version": "3.0.0-alpha.249",
3
+ "version": "3.0.0-alpha.251",
4
4
  "description": "Online Shop example — Ordering plugin (Customer & Order aggregates)",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -21,18 +21,18 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "sury": "11.0.0",
24
- "@reventlessdev/online-shop-aggregates-ordering-spec": "3.0.0-alpha.141",
25
- "@reventlessdev/online-shop-aggregates-catalog-spec": "3.0.0-alpha.141",
26
24
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
27
- "@reventlessdev/reventless-infra": "3.0.0-alpha.170",
28
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.217",
29
- "@reventlessdev/reventless-local": "3.0.0-alpha.260",
30
- "@reventlessdev/reventless-spec": "3.0.0-alpha.142"
25
+ "@reventlessdev/online-shop-aggregates-catalog-spec": "3.0.0-alpha.142",
26
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.218",
27
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.171",
28
+ "@reventlessdev/online-shop-aggregates-ordering-spec": "3.0.0-alpha.142",
29
+ "@reventlessdev/reventless-local": "3.0.0-alpha.261",
30
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.143"
31
31
  },
32
32
  "devDependencies": {
33
33
  "rescript": "12.3.1",
34
34
  "sury-ppx": "11.0.0",
35
- "@reventlessdev/reventless-ppx": "1.0.0-alpha.83"
35
+ "@reventlessdev/reventless-ppx": "1.0.0-alpha.89"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "rescript": "^12.3.1"
@@ -1,26 +1,32 @@
1
1
  @@reventless.gwt
2
2
 
3
+ open Ordering_Examples
4
+
3
5
  describe("CatalogProduct Behavior", () => {
6
+ // scenario-id: e0d3dd62-1687-4920-a1ad-d61733936926
4
7
  test("Sync on new aggregate produces Synced", () =>
5
8
  givenEvents([])
6
- ->whenCmd(Sync({name: "Laptop", price: 999.99}))
7
- ->thenEvent(Synced({name: "Laptop", price: 999.99}))
9
+ ->whenCmd(Sync({name: laptop, price: 999.99}))
10
+ ->thenEvent(Synced({name: laptop, price: 999.99}))
8
11
  )
9
12
 
13
+ // scenario-id: aa7ebc46-2b74-440d-92b1-d5b6262de254
10
14
  test("Sync on already-synced aggregate produces no events (idempotent)", () =>
11
- givenEvents([Synced({name: "Laptop", price: 999.99})])
12
- ->whenCmd(Sync({name: "Laptop", price: 999.99}))
15
+ givenEvents([Synced({name: laptop, price: 999.99})])
16
+ ->whenCmd(Sync({name: laptop, price: 999.99}))
13
17
  ->thenNoEvent
14
18
  )
15
19
 
20
+ // scenario-id: 69fe9b40-3a62-497d-b39b-098173ef8cd5
16
21
  test("UpdatePrice on never-synced aggregate produces no events (idempotent)", () =>
17
22
  givenEvents([])
18
23
  ->whenCmd(UpdatePrice({price: 1.0}))
19
24
  ->thenNoEvent
20
25
  )
21
26
 
27
+ // scenario-id: fef61ceb-02a6-4d0c-a1e9-297c99a4d7d9
22
28
  test("UpdatePrice on synced aggregate produces PriceUpdated", () =>
23
- givenEvents([Synced({name: "Laptop", price: 999.99})])
29
+ givenEvents([Synced({name: laptop, price: 999.99})])
24
30
  ->whenCmd(UpdatePrice({price: 899.99}))
25
31
  ->thenEvent(PriceUpdated({price: 899.99}))
26
32
  )
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Behavior_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Behavior_GWT.res.mjs";
4
4
  import * as CatalogProduct$OrderingPlugin from "../../../src/CatalogProduct/Aggregate/CatalogProduct.res.mjs";
5
+ import * as Ordering_Examples$OrderingPlugin from "../../Ordering_Examples.res.mjs";
5
6
  import * as CatalogProduct_Behavior$OrderingPlugin from "../../../src/CatalogProduct/Aggregate/CatalogProduct_Behavior.res.mjs";
6
7
 
7
8
  let include = Behavior_GWT$ReventlessGwt.MakeFromAggregate({
@@ -38,20 +39,20 @@ let thenNoEvent = include.thenNoEvent;
38
39
  describe("CatalogProduct Behavior", () => {
39
40
  test("Sync on new aggregate produces Synced", () => thenEvent(whenCmd(givenEvents([]), {
40
41
  TAG: "Sync",
41
- name: "Laptop",
42
+ name: Ordering_Examples$OrderingPlugin.laptop,
42
43
  price: 999.99
43
44
  }), {
44
45
  TAG: "Synced",
45
- name: "Laptop",
46
+ name: Ordering_Examples$OrderingPlugin.laptop,
46
47
  price: 999.99
47
48
  }));
48
49
  test("Sync on already-synced aggregate produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([{
49
50
  TAG: "Synced",
50
- name: "Laptop",
51
+ name: Ordering_Examples$OrderingPlugin.laptop,
51
52
  price: 999.99
52
53
  }]), {
53
54
  TAG: "Sync",
54
- name: "Laptop",
55
+ name: Ordering_Examples$OrderingPlugin.laptop,
55
56
  price: 999.99
56
57
  })));
57
58
  test("UpdatePrice on never-synced aggregate produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([]), {
@@ -60,7 +61,7 @@ describe("CatalogProduct Behavior", () => {
60
61
  })));
61
62
  test("UpdatePrice on synced aggregate produces PriceUpdated", () => thenEvent(whenCmd(givenEvents([{
62
63
  TAG: "Synced",
63
- name: "Laptop",
64
+ name: Ordering_Examples$OrderingPlugin.laptop,
64
65
  price: 999.99
65
66
  }]), {
66
67
  TAG: "UpdatePrice",
@@ -1,12 +1,14 @@
1
1
  @@reventless.gwt(AvailableProducts_Projections.CatalogProductMapping)
2
2
 
3
3
  describe("AvailableProducts ReadModel ← CatalogProduct", () => {
4
+ // scenario-id: 845f7b2c-e29b-469f-a497-654927750d09
4
5
  test("Synced sets initial read model state", () =>
5
6
  givenEvents([])
6
7
  ->whenEvent(CatalogProduct.Synced({name: "Laptop", price: 999.99}))
7
8
  ->thenState({AvailableProducts.name: "Laptop", price: 999.99})
8
9
  )
9
10
 
11
+ // scenario-id: 272d70a8-20d7-4f33-bca1-ec101bd5f702
10
12
  test("PriceUpdated updates the price", () =>
11
13
  givenEvents([CatalogProduct.Synced({name: "Laptop", price: 999.99})])
12
14
  ->whenEvent(CatalogProduct.PriceUpdated({price: 899.99}))
@@ -1,80 +1,95 @@
1
1
  @@reventless.gwt
2
2
 
3
+ open Ordering_Examples
4
+
3
5
  describe("Customer Behavior", () => {
6
+ // scenario-id: 5936d064-3500-474f-ac41-619765828d32
4
7
  test("Register on new aggregate produces Registered", () =>
5
8
  givenEvents([])
6
- ->whenCmd(Register({email: "alice@example.com", address: "123 Main St"}))
7
- ->thenEvent(Registered({email: "alice@example.com", address: "123 Main St"}))
9
+ ->whenCmd(Register({email: aliceEmail, address: mainStreet}))
10
+ ->thenEvent(Registered({email: aliceEmail, address: mainStreet}))
8
11
  )
9
12
 
13
+ // scenario-id: 93201f16-17d6-4f94-a096-2dbec3c4306c
10
14
  test("Register on existing aggregate returns CustomerAlreadyRegistered", () =>
11
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
12
- ->whenCmd(Register({email: "bob@example.com", address: "456 Oak Ave"}))
15
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
16
+ ->whenCmd(Register({email: bobEmail, address: oakAvenue}))
13
17
  ->thenError(CustomerAlreadyRegistered)
14
18
  )
15
19
 
20
+ // scenario-id: fcbc5972-10f0-43ae-a402-21fa7e398e2b
16
21
  test("Register on deactivated aggregate returns CustomerAlreadyDeactivated", () =>
17
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"}), Deactivated])
18
- ->whenCmd(Register({email: "bob@example.com", address: "456 Oak Ave"}))
22
+ givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
23
+ ->whenCmd(Register({email: bobEmail, address: oakAvenue}))
19
24
  ->thenError(CustomerAlreadyDeactivated)
20
25
  )
21
26
 
27
+ // scenario-id: eb52c72f-448a-47f6-b6dc-1454fb0976a6
22
28
  test("UpdateEmail on non-existent aggregate returns CustomerNotFound", () =>
23
29
  givenEvents([])
24
- ->whenCmd(UpdateEmail({email: "bob@example.com"}))
30
+ ->whenCmd(UpdateEmail({email: bobEmail}))
25
31
  ->thenError(CustomerNotFound)
26
32
  )
27
33
 
34
+ // scenario-id: 0da39fef-7112-4f6b-93d6-f1479d8d384b
28
35
  test("UpdateEmail on active customer produces EmailUpdated", () =>
29
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
36
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
30
37
  ->whenCmd(UpdateEmail({email: "alice2@example.com"}))
31
38
  ->thenEvent(EmailUpdated({email: "alice2@example.com"}))
32
39
  )
33
40
 
41
+ // scenario-id: 27d8e526-daa8-4b11-be68-c1107394f75d
34
42
  test("UpdateEmail to same email produces no events (idempotent)", () =>
35
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
36
- ->whenCmd(UpdateEmail({email: "alice@example.com"}))
43
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
44
+ ->whenCmd(UpdateEmail({email: aliceEmail}))
37
45
  ->thenNoEvent
38
46
  )
39
47
 
48
+ // scenario-id: f95d0cde-1011-4566-975b-ef086015d811
40
49
  test("UpdateEmail on deactivated customer returns CustomerAlreadyDeactivated", () =>
41
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"}), Deactivated])
42
- ->whenCmd(UpdateEmail({email: "bob@example.com"}))
50
+ givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
51
+ ->whenCmd(UpdateEmail({email: bobEmail}))
43
52
  ->thenError(CustomerAlreadyDeactivated)
44
53
  )
45
54
 
55
+ // scenario-id: 856f318e-b0da-4ae8-98bd-0a27c32cfb68
46
56
  test("UpdateAddress on non-existent aggregate returns CustomerNotFound", () =>
47
57
  givenEvents([])
48
58
  ->whenCmd(UpdateAddress({address: "x"}))
49
59
  ->thenError(CustomerNotFound)
50
60
  )
51
61
 
62
+ // scenario-id: 2f4959d6-b687-4659-b5a6-282a6463d1d8
52
63
  test("UpdateAddress on active customer produces AddressUpdated", () =>
53
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
64
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
54
65
  ->whenCmd(UpdateAddress({address: "789 Pine Rd"}))
55
66
  ->thenEvent(AddressUpdated({address: "789 Pine Rd"}))
56
67
  )
57
68
 
69
+ // scenario-id: 004ce506-1231-43d7-a659-263af800b815
58
70
  test("UpdateAddress to same address produces no events (idempotent)", () =>
59
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
60
- ->whenCmd(UpdateAddress({address: "123 Main St"}))
71
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
72
+ ->whenCmd(UpdateAddress({address: mainStreet}))
61
73
  ->thenNoEvent
62
74
  )
63
75
 
76
+ // scenario-id: 8c84e2c8-e77c-497d-bad0-70db6643c3de
64
77
  test("Deactivate on non-existent aggregate returns CustomerNotFound", () =>
65
78
  givenEvents([])
66
79
  ->whenCmd(Deactivate)
67
80
  ->thenError(CustomerNotFound)
68
81
  )
69
82
 
83
+ // scenario-id: 54c0ec8c-f937-41b7-bed0-963c54702564
70
84
  test("Deactivate on active customer produces Deactivated", () =>
71
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"})])
85
+ givenEvents([Registered({email: aliceEmail, address: mainStreet})])
72
86
  ->whenCmd(Deactivate)
73
87
  ->thenEvent(Deactivated)
74
88
  )
75
89
 
90
+ // scenario-id: 083c8024-7e68-44d6-b9ff-61a3250202bf
76
91
  test("Deactivate on deactivated customer produces no events (idempotent)", () =>
77
- givenEvents([Registered({email: "alice@example.com", address: "123 Main St"}), Deactivated])
92
+ givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
78
93
  ->whenCmd(Deactivate)
79
94
  ->thenNoEvent
80
95
  )