@reventlessdev/online-shop-hybrid-ordering 1.0.0-alpha.100

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 (86) hide show
  1. package/CHANGELOG.md +904 -0
  2. package/LICENSE +202 -0
  3. package/__mocks__/emptyModule.js +1 -0
  4. package/package.json +57 -0
  5. package/rescript.json +37 -0
  6. package/src/CatalogProduct/StateChangeSlice/SyncCatalogProduct.res +29 -0
  7. package/src/CatalogProduct/StateChangeSlice/SyncCatalogProduct.res.mjs +71 -0
  8. package/src/CatalogProduct/StateChangeSlice/SyncCatalogProduct_Behavior.res +27 -0
  9. package/src/CatalogProduct/StateChangeSlice/SyncCatalogProduct_Behavior.res.mjs +73 -0
  10. package/src/CatalogProduct/StateViewSliceStream/AvailableProducts.res +15 -0
  11. package/src/CatalogProduct/StateViewSliceStream/AvailableProducts.res.mjs +69 -0
  12. package/src/CatalogProduct/StateViewSliceStream/AvailableProducts_Projection.res +8 -0
  13. package/src/CatalogProduct/StateViewSliceStream/AvailableProducts_Projection.res.mjs +38 -0
  14. package/src/Customer/Aggregate/Customer.res +24 -0
  15. package/src/Customer/Aggregate/Customer.res.mjs +64 -0
  16. package/src/Customer/Aggregate/Customer_Behavior.res +41 -0
  17. package/src/Customer/Aggregate/Customer_Behavior.res.mjs +143 -0
  18. package/src/Customer/ReadModelStream/Customers.res +15 -0
  19. package/src/Customer/ReadModelStream/Customers.res.mjs +44 -0
  20. package/src/Customer/ReadModelStream/Customers_Projections.res +78 -0
  21. package/src/Customer/ReadModelStream/Customers_Projections.res.mjs +153 -0
  22. package/src/Extension/Products_Extension.res +23 -0
  23. package/src/Extension/Products_Extension.res.mjs +43 -0
  24. package/src/ExtensionPoint/Orders_ExtensionPointMapping.res +33 -0
  25. package/src/ExtensionPoint/Orders_ExtensionPointMapping.res.mjs +82 -0
  26. package/src/Order/AutomationSlice/AutoShipOrder.res +19 -0
  27. package/src/Order/AutomationSlice/AutoShipOrder.res.mjs +42 -0
  28. package/src/Order/AutomationSlice/AutoShipOrder_Automation.res +37 -0
  29. package/src/Order/AutomationSlice/AutoShipOrder_Automation.res.mjs +101 -0
  30. package/src/Order/OutboundTranslationSlice/SendOrderConfirmation.res +22 -0
  31. package/src/Order/OutboundTranslationSlice/SendOrderConfirmation.res.mjs +45 -0
  32. package/src/Order/OutboundTranslationSlice/SendOrderConfirmation_Translation.res +24 -0
  33. package/src/Order/OutboundTranslationSlice/SendOrderConfirmation_Translation.res.mjs +46 -0
  34. package/src/Order/StateChangeSlice/CancelOrder.res +29 -0
  35. package/src/Order/StateChangeSlice/CancelOrder.res.mjs +75 -0
  36. package/src/Order/StateChangeSlice/CancelOrder_Behavior.res +35 -0
  37. package/src/Order/StateChangeSlice/CancelOrder_Behavior.res.mjs +110 -0
  38. package/src/Order/StateChangeSlice/PlaceOrder.res +28 -0
  39. package/src/Order/StateChangeSlice/PlaceOrder.res.mjs +63 -0
  40. package/src/Order/StateChangeSlice/PlaceOrder_Behavior.res +39 -0
  41. package/src/Order/StateChangeSlice/PlaceOrder_Behavior.res.mjs +70 -0
  42. package/src/Order/StateChangeSlice/RefundOrder.res +27 -0
  43. package/src/Order/StateChangeSlice/RefundOrder.res.mjs +59 -0
  44. package/src/Order/StateChangeSlice/RefundOrder_Behavior.res +26 -0
  45. package/src/Order/StateChangeSlice/RefundOrder_Behavior.res.mjs +77 -0
  46. package/src/Order/StateChangeSlice/ShipOrder.res +23 -0
  47. package/src/Order/StateChangeSlice/ShipOrder.res.mjs +56 -0
  48. package/src/Order/StateChangeSlice/ShipOrder_Behavior.res +26 -0
  49. package/src/Order/StateChangeSlice/ShipOrder_Behavior.res.mjs +73 -0
  50. package/src/Order/StateViewSliceStream/Orders.res +24 -0
  51. package/src/Order/StateViewSliceStream/Orders.res.mjs +80 -0
  52. package/src/Order/StateViewSliceStream/Orders_Projection.res +10 -0
  53. package/src/Order/StateViewSliceStream/Orders_Projection.res.mjs +52 -0
  54. package/src/Plugin.res +74 -0
  55. package/src/Plugin.res.mjs +304 -0
  56. package/src/Service/EmailService.res +3 -0
  57. package/src/Service/EmailService.res.mjs +11 -0
  58. package/src/plugin.json +1 -0
  59. package/tests/CatalogProduct/StateChangeSlice/SyncCatalogProduct_GWT.res +27 -0
  60. package/tests/CatalogProduct/StateChangeSlice/SyncCatalogProduct_GWT.res.mjs +109 -0
  61. package/tests/CatalogProduct/StateViewSliceStream/AvailableProducts_GWT.res +15 -0
  62. package/tests/CatalogProduct/StateViewSliceStream/AvailableProducts_GWT.res.mjs +93 -0
  63. package/tests/Customer/Aggregate/Customer_GWT.res +63 -0
  64. package/tests/Customer/Aggregate/Customer_GWT.res.mjs +153 -0
  65. package/tests/Customer/ReadModelStream/Customers_GWT.res +84 -0
  66. package/tests/Customer/ReadModelStream/Customers_GWT.res.mjs +90 -0
  67. package/tests/Extension/Products_Extension_GWT.res +23 -0
  68. package/tests/Extension/Products_Extension_GWT.res.mjs +108 -0
  69. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +23 -0
  70. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +139 -0
  71. package/tests/Flow/OrderingFlow_GWT.res +69 -0
  72. package/tests/Flow/OrderingFlow_GWT.res.mjs +184 -0
  73. package/tests/Order/AutomationSlice/AutoShipOrder_GWT.res +55 -0
  74. package/tests/Order/AutomationSlice/AutoShipOrder_GWT.res.mjs +133 -0
  75. package/tests/Order/OutboundTranslationSlice/SendOrderConfirmation_GWT.res +30 -0
  76. package/tests/Order/OutboundTranslationSlice/SendOrderConfirmation_GWT.res.mjs +102 -0
  77. package/tests/Order/StateChangeSlice/CancelOrder_GWT.res +45 -0
  78. package/tests/Order/StateChangeSlice/CancelOrder_GWT.res.mjs +131 -0
  79. package/tests/Order/StateChangeSlice/PlaceOrder_GWT.res +33 -0
  80. package/tests/Order/StateChangeSlice/PlaceOrder_GWT.res.mjs +139 -0
  81. package/tests/Order/StateChangeSlice/RefundOrder_GWT.res +31 -0
  82. package/tests/Order/StateChangeSlice/RefundOrder_GWT.res.mjs +100 -0
  83. package/tests/Order/StateChangeSlice/ShipOrder_GWT.res +27 -0
  84. package/tests/Order/StateChangeSlice/ShipOrder_GWT.res.mjs +91 -0
  85. package/tests/Order/StateViewSliceStream/Orders_GWT.res +36 -0
  86. package/tests/Order/StateViewSliceStream/Orders_GWT.res.mjs +114 -0
@@ -0,0 +1,82 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+
6
+ let eventSchema = S.union([
7
+ S.schema(s => ({
8
+ TAG: "OrderPlaced",
9
+ orderId: s.m(DcbTag$Reventless.string),
10
+ customerId: s.m(DcbTag$Reventless.string),
11
+ productIds: s.m(S.array(DcbTag$Reventless.stringForKey("productId")))
12
+ })),
13
+ S.schema(s => ({
14
+ TAG: "OrderCancelled",
15
+ orderId: s.m(DcbTag$Reventless.string),
16
+ productIds: s.m(S.array(DcbTag$Reventless.stringForKey("productId")))
17
+ }))
18
+ ]);
19
+
20
+ function commandAuthorization(param) {
21
+ return "AllowAuthenticated";
22
+ }
23
+
24
+ let Delegate = {
25
+ Id: undefined,
26
+ commandSchema: S.unit,
27
+ name: "OrderingDcbEventLog",
28
+ eventSchema: eventSchema,
29
+ errorSchema: S.unit,
30
+ moduleUrl: "@reventlessdev/online-shop-hybrid-ordering/src/ExtensionPoint/Orders_ExtensionPointMapping.res.mjs",
31
+ commandAuthorization: commandAuthorization
32
+ };
33
+
34
+ function mapIncomingCommand(_id, _command, _meta) {
35
+ return [];
36
+ }
37
+
38
+ let mapOutgoingEvent = (_id, event, _meta, _queryEngine) => {
39
+ if (event.TAG === "OrderPlaced") {
40
+ let customerId = event.customerId;
41
+ let orderId = event.orderId;
42
+ return event.productIds.map(pid => ({
43
+ TAG: "PublishEvent",
44
+ _0: pid,
45
+ _1: {
46
+ TAG: "ItemOrdered",
47
+ productId: pid,
48
+ orderId: orderId,
49
+ customerId: customerId
50
+ }
51
+ }));
52
+ }
53
+ let orderId$1 = event.orderId;
54
+ return event.productIds.map(pid => ({
55
+ TAG: "PublishEvent",
56
+ _0: pid,
57
+ _1: {
58
+ TAG: "ItemOrderCancelled",
59
+ productId: pid,
60
+ orderId: orderId$1
61
+ }
62
+ }));
63
+ };
64
+
65
+ let name = "Orders";
66
+
67
+ let Id;
68
+
69
+ let ExtensionPoint;
70
+
71
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/ExtensionPoint/Orders_ExtensionPointMapping.res.mjs";
72
+
73
+ export {
74
+ name,
75
+ Id,
76
+ ExtensionPoint,
77
+ Delegate,
78
+ mapIncomingCommand,
79
+ mapOutgoingEvent,
80
+ moduleUrl,
81
+ }
82
+ /* eventSchema Not a pure module */
@@ -0,0 +1,19 @@
1
+ // AutoShipOrder AutomationSlice.
2
+ // When OrderPlaced is emitted, automatically issue a ShipOrder command.
3
+ // Resolved when OrderShipped arrives.
4
+ //
5
+ // Consumed events come from per-source `Mapping.Make` modules in the sibling
6
+ // `_Automation.res`. The framework derives the consumed-event set from each
7
+ // mapping's `sourceEventSchema` — no manual union here.
8
+
9
+ @@reventless.spec
10
+
11
+ @schema
12
+ type todoItem = {orderId: string}
13
+
14
+ @schema
15
+ type command = ShipOrder({orderId: string})
16
+
17
+ let maxRetries = 3
18
+ let heartbeatInterval = 60
19
+ let targetName = "ShipOrder"
@@ -0,0 +1,42 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+
6
+ let todoItemSchema = S.schema(s => ({
7
+ orderId: s.m(S.string)
8
+ }));
9
+
10
+ let commandSchema = S.schema(s => ({
11
+ TAG: "ShipOrder",
12
+ orderId: s.m(DcbTag$Reventless.string)
13
+ }));
14
+
15
+ function commandAuthorization(param) {
16
+ return "AllowAuthenticated";
17
+ }
18
+
19
+ let name = "AutoShipOrder";
20
+
21
+ let Id;
22
+
23
+ let maxRetries = 3;
24
+
25
+ let heartbeatInterval = 60;
26
+
27
+ let targetName = "ShipOrder";
28
+
29
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/AutomationSlice/AutoShipOrder.res.mjs";
30
+
31
+ export {
32
+ name,
33
+ Id,
34
+ todoItemSchema,
35
+ commandSchema,
36
+ maxRetries,
37
+ heartbeatInterval,
38
+ targetName,
39
+ moduleUrl,
40
+ commandAuthorization,
41
+ }
42
+ /* todoItemSchema Not a pure module */
@@ -0,0 +1,37 @@
1
+ @@reventless.automation
2
+
3
+ // Single DCB source — events from the ordering plugin's own event log.
4
+ // `name` MUST equal `<pluginName>DcbEventLog` so the dispatch in
5
+ // `AutomationSlice_Callback` resolves it to the topic key `Plugin_Builder`
6
+ // registers under.
7
+ module OrderingDcbSource = {
8
+ let name = "OrderingDcbEventLog"
9
+ @schema
10
+ type event =
11
+ | OrderPlaced({orderId: string})
12
+ | OrderShipped({orderId: string})
13
+ }
14
+
15
+ module FromOrderingDcb = Mapping.Make(
16
+ OrderingDcbSource,
17
+ AutoShipOrder,
18
+ {
19
+ open OrderingDcbSource
20
+
21
+ let collect = (event, _ctx) =>
22
+ switch event {
23
+ | OrderPlaced({orderId}) => [(orderId, ({orderId: orderId}: AutoShipOrder.todoItem))]
24
+ | OrderShipped(_) => []
25
+ }
26
+
27
+ let resolve = event =>
28
+ switch event {
29
+ | OrderShipped({orderId}) => Some(orderId)
30
+ | OrderPlaced(_) => None
31
+ }
32
+ },
33
+ )
34
+
35
+ let mappings: array<module(Mapping)> = [module(FromOrderingDcb)]
36
+
37
+ let process = (id, _item) => Some((id, ShipOrder({orderId: id})))
@@ -0,0 +1,101 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
5
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
6
+ import * as AutomationSlice$Reventless from "@reventlessdev/reventless-spec/src/components/AutomationSlice.res.mjs";
7
+ import * as AutoShipOrder$OrderingPlugin from "./AutoShipOrder.res.mjs";
8
+
9
+ let M = AutomationSlice$Reventless.Mappings.Make({
10
+ name: AutoShipOrder$OrderingPlugin.name,
11
+ moduleUrl: AutoShipOrder$OrderingPlugin.moduleUrl,
12
+ todoItemSchema: AutoShipOrder$OrderingPlugin.todoItemSchema,
13
+ commandSchema: AutoShipOrder$OrderingPlugin.commandSchema,
14
+ maxRetries: AutoShipOrder$OrderingPlugin.maxRetries,
15
+ heartbeatInterval: AutoShipOrder$OrderingPlugin.heartbeatInterval,
16
+ targetName: AutoShipOrder$OrderingPlugin.targetName
17
+ });
18
+
19
+ let name = "OrderingDcbEventLog";
20
+
21
+ let eventSchema = S.union([
22
+ S.schema(s => ({
23
+ TAG: "OrderPlaced",
24
+ orderId: s.m(DcbTag$Reventless.string)
25
+ })),
26
+ S.schema(s => ({
27
+ TAG: "OrderShipped",
28
+ orderId: s.m(DcbTag$Reventless.string)
29
+ }))
30
+ ]);
31
+
32
+ let OrderingDcbSource = {
33
+ Id: undefined,
34
+ name: name,
35
+ eventSchema: eventSchema
36
+ };
37
+
38
+ function collect(event, _ctx) {
39
+ if (event.TAG !== "OrderPlaced") {
40
+ return [];
41
+ }
42
+ let orderId = event.orderId;
43
+ return [[
44
+ orderId,
45
+ {
46
+ orderId: orderId
47
+ }
48
+ ]];
49
+ }
50
+
51
+ function resolve(event) {
52
+ if (event.TAG === "OrderPlaced") {
53
+ return;
54
+ } else {
55
+ return event.orderId;
56
+ }
57
+ }
58
+
59
+ let FromOrderingDcb = AutomationSlice$Reventless.Mapping.Make({
60
+ Id: Id$Reventless.$$String,
61
+ name: name,
62
+ eventSchema: eventSchema
63
+ })({
64
+ name: AutoShipOrder$OrderingPlugin.name,
65
+ moduleUrl: AutoShipOrder$OrderingPlugin.moduleUrl,
66
+ todoItemSchema: AutoShipOrder$OrderingPlugin.todoItemSchema,
67
+ commandSchema: AutoShipOrder$OrderingPlugin.commandSchema,
68
+ maxRetries: AutoShipOrder$OrderingPlugin.maxRetries,
69
+ heartbeatInterval: AutoShipOrder$OrderingPlugin.heartbeatInterval,
70
+ targetName: AutoShipOrder$OrderingPlugin.targetName
71
+ })({
72
+ collect: collect,
73
+ resolve: resolve
74
+ });
75
+
76
+ let mappings = [FromOrderingDcb];
77
+
78
+ function process(id, _item) {
79
+ return [
80
+ id,
81
+ {
82
+ TAG: "ShipOrder",
83
+ orderId: id
84
+ }
85
+ ];
86
+ }
87
+
88
+ let Spec;
89
+
90
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/AutomationSlice/AutoShipOrder_Automation.res.mjs";
91
+
92
+ export {
93
+ Spec,
94
+ M,
95
+ OrderingDcbSource,
96
+ FromOrderingDcb,
97
+ mappings,
98
+ process,
99
+ moduleUrl,
100
+ }
101
+ /* M Not a pure module */
@@ -0,0 +1,22 @@
1
+ // SendOrderConfirmation OutboundTranslationSlice.
2
+ // When OrderPlaced is emitted, sends a confirmation email via EmailService.
3
+ // Fire-and-forget pattern (no inbound command).
4
+
5
+ @@reventless.spec
6
+
7
+ @schema
8
+ type consumedEvent =
9
+ | OrderPlaced({orderId: string, customerId: string})
10
+
11
+ @schema
12
+ type outboundItem = {orderId: string, customerId: string}
13
+
14
+ @schema
15
+ type inboundCommand = unit
16
+
17
+ let maxRetries = 3
18
+ let heartbeatInterval = 60
19
+ let targetName = None
20
+ // Foreign system this anti-corruption slice publishes confirmations to — drawn as an
21
+ // external box outside the Ordering plugin in the Event Graph.
22
+ let externalSystem = Some("EmailService")
@@ -0,0 +1,45 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+
6
+ let consumedEventSchema = S.schema(s => ({
7
+ TAG: "OrderPlaced",
8
+ orderId: s.m(DcbTag$Reventless.string),
9
+ customerId: s.m(DcbTag$Reventless.string)
10
+ }));
11
+
12
+ let outboundItemSchema = S.schema(s => ({
13
+ orderId: s.m(S.string),
14
+ customerId: s.m(S.string)
15
+ }));
16
+
17
+ let name = "SendOrderConfirmation";
18
+
19
+ let Id;
20
+
21
+ let inboundCommandSchema = S.unit;
22
+
23
+ let maxRetries = 3;
24
+
25
+ let heartbeatInterval = 60;
26
+
27
+ let targetName;
28
+
29
+ let externalSystem = "EmailService";
30
+
31
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/OutboundTranslationSlice/SendOrderConfirmation.res.mjs";
32
+
33
+ export {
34
+ name,
35
+ Id,
36
+ consumedEventSchema,
37
+ outboundItemSchema,
38
+ inboundCommandSchema,
39
+ maxRetries,
40
+ heartbeatInterval,
41
+ targetName,
42
+ externalSystem,
43
+ moduleUrl,
44
+ }
45
+ /* consumedEventSchema Not a pure module */
@@ -0,0 +1,24 @@
1
+ @@reventless.translation
2
+
3
+ let collect = event =>
4
+ switch event {
5
+ | OrderPlaced({orderId, customerId}) => [(orderId, {orderId, customerId})]
6
+ }
7
+
8
+ let translate = async (_id, item) => {
9
+ try {
10
+ await EmailService.sendOrderConfirmation(
11
+ ~email=item.customerId,
12
+ ~orderId=item.orderId,
13
+ )
14
+ Ok(None)
15
+ } catch {
16
+ | exn =>
17
+ let msg =
18
+ exn
19
+ ->JsExn.fromException
20
+ ->Option.flatMap(JsExn.message)
21
+ ->Option.getOr("email send failed")
22
+ Error(msg)
23
+ }
24
+ }
@@ -0,0 +1,46 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
4
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
+ import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
6
+ import * as EmailService$OrderingPlugin from "../../Service/EmailService.res.mjs";
7
+
8
+ function collect(event) {
9
+ let orderId = event.orderId;
10
+ return [[
11
+ orderId,
12
+ {
13
+ orderId: orderId,
14
+ customerId: event.customerId
15
+ }
16
+ ]];
17
+ }
18
+
19
+ async function translate(_id, item) {
20
+ try {
21
+ await EmailService$OrderingPlugin.sendOrderConfirmation(item.customerId, item.orderId);
22
+ return {
23
+ TAG: "Ok",
24
+ _0: undefined
25
+ };
26
+ } catch (raw_exn) {
27
+ let exn = Primitive_exceptions.internalToException(raw_exn);
28
+ let msg = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_JsExn.fromException(exn), Stdlib_JsExn.message), "email send failed");
29
+ return {
30
+ TAG: "Error",
31
+ _0: msg
32
+ };
33
+ }
34
+ }
35
+
36
+ let Spec;
37
+
38
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/OutboundTranslationSlice/SendOrderConfirmation_Translation.res.mjs";
39
+
40
+ export {
41
+ Spec,
42
+ collect,
43
+ translate,
44
+ moduleUrl,
45
+ }
46
+ /* Stdlib_JsExn Not a pure module */
@@ -0,0 +1,29 @@
1
+ // CancelOrder StateChangeSlice.
2
+ // Requires order to exist and not be shipped; idempotent if already cancelled.
3
+
4
+ @@reventless.spec
5
+
6
+ @schema
7
+ type consumedEvent =
8
+ | OrderPlaced({productIds: array<string>})
9
+ | OrderShipped
10
+ | OrderCancelled
11
+ | OrderReopened
12
+
13
+ @schema
14
+ type command =
15
+ | @allowedStates([Orders.Placed]) CancelOrder({orderId: string})
16
+ | @noApi ReopenOrder({orderId: string}) // Internal: admin/automation only
17
+
18
+ @schema
19
+ type error =
20
+ | OrderNotFound
21
+ | OrderAlreadyShipped
22
+
23
+ @schema
24
+ type event =
25
+ | OrderCancelled({
26
+ orderId: string,
27
+ productIds: array<string>,
28
+ })
29
+ | OrderReopened({orderId: string})
@@ -0,0 +1,75 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+ import * as Api$ReventlessInfra from "@reventlessdev/reventless-infra/src/components/Api.res.mjs";
6
+
7
+ let consumedEventSchema = S.union([
8
+ S.schema(s => ({
9
+ TAG: "OrderPlaced",
10
+ productIds: s.m(S.array(DcbTag$Reventless.stringForKey("productId")))
11
+ })),
12
+ S.literal("OrderShipped"),
13
+ S.literal("OrderCancelled"),
14
+ S.literal("OrderReopened")
15
+ ]);
16
+
17
+ let commandSchema = S.union([
18
+ S.schema(s => ({
19
+ TAG: "CancelOrder",
20
+ orderId: s.m(DcbTag$Reventless.string)
21
+ })),
22
+ S.schema(s => ({
23
+ TAG: "ReopenOrder",
24
+ orderId: s.m(DcbTag$Reventless.string)
25
+ }))
26
+ ]);
27
+
28
+ let errorSchema = S.union([
29
+ S.literal("OrderNotFound"),
30
+ S.literal("OrderAlreadyShipped")
31
+ ]);
32
+
33
+ let eventSchema = S.union([
34
+ S.schema(s => ({
35
+ TAG: "OrderCancelled",
36
+ orderId: s.m(DcbTag$Reventless.string),
37
+ productIds: s.m(S.array(DcbTag$Reventless.stringForKey("productId")))
38
+ })),
39
+ S.schema(s => ({
40
+ TAG: "OrderReopened",
41
+ orderId: s.m(DcbTag$Reventless.string)
42
+ }))
43
+ ]);
44
+
45
+ let commandSchema$1 = Api$ReventlessInfra.markNoApiVariants(commandSchema, ["ReopenOrder"]);
46
+
47
+ let commandSchema$2 = Api$ReventlessInfra.markAllowedStates(commandSchema$1, [[
48
+ "CancelOrder",
49
+ ["Placed"]
50
+ ]]);
51
+
52
+ function commandAuthorization(param) {
53
+ return "AllowAuthenticated";
54
+ }
55
+
56
+ let name = "CancelOrder";
57
+
58
+ let Id;
59
+
60
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/StateChangeSlice/CancelOrder.res.mjs";
61
+
62
+ let readConsistency = "EscalateOnRetry";
63
+
64
+ export {
65
+ name,
66
+ Id,
67
+ consumedEventSchema,
68
+ errorSchema,
69
+ eventSchema,
70
+ commandSchema$2 as commandSchema,
71
+ moduleUrl,
72
+ commandAuthorization,
73
+ readConsistency,
74
+ }
75
+ /* consumedEventSchema Not a pure module */
@@ -0,0 +1,35 @@
1
+ @@reventless.behavior
2
+
3
+ type state = {exists: bool, shipped: bool, cancelled: bool, productIds: array<string>}
4
+
5
+ let initialState = {exists: false, shipped: false, cancelled: false, productIds: []}
6
+
7
+ let evolve = (state, event) =>
8
+ switch event {
9
+ | OrderPlaced({productIds}) => {exists: true, shipped: false, cancelled: false, productIds}
10
+ | OrderShipped => {...state, shipped: true}
11
+ | OrderCancelled => {...state, cancelled: true}
12
+ | OrderReopened => {...state, cancelled: false}
13
+ }
14
+
15
+ let decide = (state, command) =>
16
+ switch command {
17
+ | CancelOrder({orderId: theId}) =>
18
+ if !state.exists {
19
+ Error(OrderNotFound)
20
+ } else if state.shipped {
21
+ Error(OrderAlreadyShipped)
22
+ } else if state.cancelled {
23
+ Ok([]) // idempotent — already cancelled
24
+ } else {
25
+ Ok([OrderCancelled({orderId: theId, productIds: state.productIds})])
26
+ }
27
+ | ReopenOrder({orderId: theId}) =>
28
+ if !state.exists {
29
+ Error(OrderNotFound)
30
+ } else if !state.cancelled {
31
+ Ok([]) // idempotent — not cancelled
32
+ } else {
33
+ Ok([OrderReopened({orderId: theId})])
34
+ }
35
+ }
@@ -0,0 +1,110 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ let initialState_productIds = [];
5
+
6
+ let initialState = {
7
+ exists: false,
8
+ shipped: false,
9
+ cancelled: false,
10
+ productIds: initialState_productIds
11
+ };
12
+
13
+ function evolve(state, event) {
14
+ if (typeof event === "object") {
15
+ return {
16
+ exists: true,
17
+ shipped: false,
18
+ cancelled: false,
19
+ productIds: event.productIds
20
+ };
21
+ }
22
+ switch (event) {
23
+ case "OrderShipped" :
24
+ return {
25
+ exists: state.exists,
26
+ shipped: true,
27
+ cancelled: state.cancelled,
28
+ productIds: state.productIds
29
+ };
30
+ case "OrderCancelled" :
31
+ return {
32
+ exists: state.exists,
33
+ shipped: state.shipped,
34
+ cancelled: true,
35
+ productIds: state.productIds
36
+ };
37
+ case "OrderReopened" :
38
+ return {
39
+ exists: state.exists,
40
+ shipped: state.shipped,
41
+ cancelled: false,
42
+ productIds: state.productIds
43
+ };
44
+ }
45
+ }
46
+
47
+ function decide(state, command) {
48
+ if (command.TAG === "CancelOrder") {
49
+ if (state.exists) {
50
+ if (state.shipped) {
51
+ return {
52
+ TAG: "Error",
53
+ _0: "OrderAlreadyShipped"
54
+ };
55
+ } else if (state.cancelled) {
56
+ return {
57
+ TAG: "Ok",
58
+ _0: []
59
+ };
60
+ } else {
61
+ return {
62
+ TAG: "Ok",
63
+ _0: [{
64
+ TAG: "OrderCancelled",
65
+ orderId: command.orderId,
66
+ productIds: state.productIds
67
+ }]
68
+ };
69
+ }
70
+ } else {
71
+ return {
72
+ TAG: "Error",
73
+ _0: "OrderNotFound"
74
+ };
75
+ }
76
+ } else if (state.exists) {
77
+ if (state.cancelled) {
78
+ return {
79
+ TAG: "Ok",
80
+ _0: [{
81
+ TAG: "OrderReopened",
82
+ orderId: command.orderId
83
+ }]
84
+ };
85
+ } else {
86
+ return {
87
+ TAG: "Ok",
88
+ _0: []
89
+ };
90
+ }
91
+ } else {
92
+ return {
93
+ TAG: "Error",
94
+ _0: "OrderNotFound"
95
+ };
96
+ }
97
+ }
98
+
99
+ let Spec;
100
+
101
+ let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Order/StateChangeSlice/CancelOrder_Behavior.res.mjs";
102
+
103
+ export {
104
+ Spec,
105
+ initialState,
106
+ evolve,
107
+ decide,
108
+ moduleUrl,
109
+ }
110
+ /* No side effect */