@reventlessdev/online-shop-hybrid-ordering 1.0.0-alpha.286 → 1.0.0-alpha.288

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
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.288 (2026-10-25)
7
+
8
+ * refactor!: internal results and tool records whose parts may be absent are optional fields ([7009ddf](https://github.com/ReventlessDev/reventless-core/commit/7009ddf5d522f39ec9946a3b5cd062ceae889bbf))
9
+ * refactor(aws)!: deploy and runtime configuration a function may lack are optional fields ([de80a54](https://github.com/ReventlessDev/reventless-core/commit/de80a546501a97b39cbe71200120f062bb260da4))
10
+ ### Features
11
+
12
+ * a plugin declares per role how a person is admitted, and the local platform honors the self-service and provisioned halves ([9c37bf5](https://github.com/ReventlessDev/reventless-core/commit/9c37bf50f15cac1703bf2c351713518121a56211))
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * code that builds these records drops `name: None` and
17
+ writes `name: x` for `name: Some(x)`; a destructure of one of them binds a
18
+ field that may be absent with `?name`.
19
+ * code that builds these records drops `name: None` and
20
+ writes `name: x` for `name: Some(x)`.
21
+
22
+
23
+
24
+ # 1.0.0-alpha.287 (2026-10-23)
25
+
26
+ **Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
27
+
28
+
29
+
30
+
31
+
6
32
  # 1.0.0-alpha.286 (2026-10-22)
7
33
 
8
34
  **Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/online-shop-hybrid-ordering",
3
- "version": "1.0.0-alpha.286",
3
+ "version": "1.0.0-alpha.288",
4
4
  "description": "Online Shop Hybrid example — Ordering plugin (Customer aggregate + Order/CatalogProduct DCB)",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -21,15 +21,15 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "sury": "11.0.0",
24
- "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.172",
24
+ "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.173",
25
+ "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.172",
26
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.256",
25
27
  "@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
26
- "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.171",
27
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.254",
28
- "@reventlessdev/reventless-infra": "3.0.0-alpha.203",
29
- "@reventlessdev/reventless-spec": "3.0.0-alpha.175",
30
- "@reventlessdev/reventless-local": "3.0.0-alpha.297",
31
- "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.56",
32
- "@reventlessdev/trait-notification": "1.0.0-alpha.56"
28
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.205",
29
+ "@reventlessdev/reventless-local": "3.0.0-alpha.299",
30
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.176",
31
+ "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.58",
32
+ "@reventlessdev/trait-notification": "1.0.0-alpha.58"
33
33
  },
34
34
  "devDependencies": {
35
35
  "rescript": "12.3.1",
@@ -68,7 +68,7 @@ type state = {
68
68
  decidedAt: Reventless.DateTime.t,
69
69
  // Absent while the row is still open. A decision that has not settled has no
70
70
  // settlement time, and `""` said that with a value the instant grammar rejects.
71
- settledAt: option<Reventless.DateTime.t>,
71
+ settledAt?: Reventless.DateTime.t,
72
72
  }
73
73
 
74
74
  // `address` is on the published event and is not read here — a consumed variant
@@ -43,7 +43,6 @@ let project = ({event, meta}) =>
43
43
  origin: originName(origin),
44
44
  detail: "",
45
45
  decidedAt: meta.time,
46
- settledAt: None,
47
46
  },
48
47
  ),
49
48
  ]
@@ -64,7 +63,7 @@ let project = ({event, meta}) =>
64
63
  origin: originName(origin),
65
64
  detail: "the recipient is not subscribed to this notification",
66
65
  decidedAt: meta.time,
67
- settledAt: Some(meta.time),
66
+ settledAt: meta.time,
68
67
  },
69
68
  ),
70
69
  ]
@@ -89,7 +88,7 @@ let project = ({event, meta}) =>
89
88
  origin: originName(origin),
90
89
  detail: "no address on file for a channel the recipient wants",
91
90
  decidedAt: meta.time,
92
- settledAt: Some(meta.time),
91
+ settledAt: meta.time,
93
92
  },
94
93
  ),
95
94
  ]
@@ -100,7 +99,7 @@ let project = ({event, meta}) =>
100
99
  ...state,
101
100
  outcome: Delivered,
102
101
  detail: providerRef,
103
- settledAt: Some(meta.time),
102
+ settledAt: meta.time,
104
103
  },
105
104
  ),
106
105
  ]
@@ -111,7 +110,7 @@ let project = ({event, meta}) =>
111
110
  ...state,
112
111
  outcome: Failed,
113
112
  detail: reason,
114
- settledAt: Some(meta.time),
113
+ settledAt: meta.time,
115
114
  },
116
115
  ),
117
116
  ]
@@ -39,8 +39,7 @@ function project(param) {
39
39
  subjectRef: event.subjectRef,
40
40
  origin: originName(event.origin),
41
41
  detail: "",
42
- decidedAt: meta.time,
43
- settledAt: undefined
42
+ decidedAt: meta.time
44
43
  }
45
44
  }];
46
45
  case "NotificationSuppressed" :
@@ -86,38 +85,26 @@ function project(param) {
86
85
  return [{
87
86
  TAG: "Update",
88
87
  _0: event.reference,
89
- _1: state => ({
90
- reference: state.reference,
91
- recipientId: state.recipientId,
92
- category: state.category,
93
- outcome: "Delivered",
94
- channel: state.channel,
95
- subjectType: state.subjectType,
96
- subjectRef: state.subjectRef,
97
- origin: state.origin,
98
- detail: providerRef,
99
- decidedAt: state.decidedAt,
100
- settledAt: meta.time
101
- })
88
+ _1: state => {
89
+ let newrecord = {...state};
90
+ newrecord.settledAt = meta.time;
91
+ newrecord.detail = providerRef;
92
+ newrecord.outcome = "Delivered";
93
+ return newrecord;
94
+ }
102
95
  }];
103
96
  case "NotificationFailed" :
104
97
  let reason = event.reason;
105
98
  return [{
106
99
  TAG: "Update",
107
100
  _0: event.reference,
108
- _1: state => ({
109
- reference: state.reference,
110
- recipientId: state.recipientId,
111
- category: state.category,
112
- outcome: "Failed",
113
- channel: state.channel,
114
- subjectType: state.subjectType,
115
- subjectRef: state.subjectRef,
116
- origin: state.origin,
117
- detail: reason,
118
- decidedAt: state.decidedAt,
119
- settledAt: meta.time
120
- })
101
+ _1: state => {
102
+ let newrecord = {...state};
103
+ newrecord.settledAt = meta.time;
104
+ newrecord.detail = reason;
105
+ newrecord.outcome = "Failed";
106
+ return newrecord;
107
+ }
121
108
  }];
122
109
  }
123
110
  }
@@ -89,10 +89,10 @@ type state = {
89
89
  shippingMethod: shippingMethod,
90
90
  // The requested slot as one declared span, so a scheduler lays a bar out from
91
91
  // it directly instead of guessing the pair from field names.
92
- deliveryWindow: option<Reventless.DateRange.t>,
92
+ deliveryWindow?: Reventless.DateRange.t,
93
93
  // Carried on the event rather than read from the catalog — see `PlaceOrder`.
94
94
  // Absent on orders placed before it was recorded.
95
- firstProductName: option<string>,
95
+ firstProductName?: string,
96
96
  // The picture the order recorded, resolved as this row's own. Schema written
97
97
  // out because the store is Catalog's — see `catalogProductImage` above.
98
98
  firstProductImage: @s.matches(S.option(catalogProductImage)) option<Reventless.UploadableImage.t>,
@@ -30,8 +30,8 @@ let project = ({event, meta}) =>
30
30
  // Opened by the machinery from this envelope's time, like every later
31
31
  // entry — the projection never appends to it by hand.
32
32
  trail: [],
33
- deliveryWindow,
34
- // Copied straight through. The event is the record of what was bought;
33
+ ?deliveryWindow,
34
+ ?// Copied straight through. The event is the record of what was bought;
35
35
  // this view does not go and ask the catalog what the product is called
36
36
  // now, which is the whole point of freezing it at placement.
37
37
  firstProductName,
package/src/Plugin.res CHANGED
@@ -237,10 +237,10 @@ module Make = (Platform: ReventlessInfra.Platform.T) => {
237
237
  ],
238
238
  ~pluginStructure,
239
239
  ~componentRuntime=Dict.fromArray([
240
- ("Customers", {ReventlessInfra.RuntimeHints.memorySize: Some(2048), timeout: None}),
241
- ("Customer", {ReventlessInfra.RuntimeHints.memorySize: Some(1536), timeout: None}),
242
- ("PlaceOrder", {ReventlessInfra.RuntimeHints.memorySize: Some(768), timeout: Some(60)}),
243
- ("Orders", {ReventlessInfra.RuntimeHints.memorySize: Some(1024), timeout: None}),
240
+ ("Customers", {ReventlessInfra.RuntimeHints.memorySize: 2048}),
241
+ ("Customer", {ReventlessInfra.RuntimeHints.memorySize: 1536}),
242
+ ("PlaceOrder", {ReventlessInfra.RuntimeHints.memorySize: 768, timeout: 60}),
243
+ ("Orders", {ReventlessInfra.RuntimeHints.memorySize: 1024}),
244
244
  ]),
245
245
  ~uiFragments=?uiBundleUrl->Option.map(url =>
246
246
  Platform.Plugin.makeAutoUIManifest(
@@ -642,7 +642,7 @@ function Make(Platform) {
642
642
  ]), LifecycleModel$OrderingPlugin.model, [
643
643
  CustomerId$OrderingPlugin.key,
644
644
  OrderId$OrderingPlugin.key
645
- ]);
645
+ ], undefined, undefined);
646
646
  let make = () => Platform.Plugin.make("Ordering", 5, [Orders_ExtensionPoint], [Products_Extension], [CustomerAggregate], [CustomersReadModel], undefined, [
647
647
  CancelOrderSlice,
648
648
  EmailVerificationChallengesSlice,
@@ -670,15 +670,13 @@ function Make(Platform) {
670
670
  [
671
671
  "Customers",
672
672
  {
673
- memorySize: 2048,
674
- timeout: undefined
673
+ memorySize: 2048
675
674
  }
676
675
  ],
677
676
  [
678
677
  "Customer",
679
678
  {
680
- memorySize: 1536,
681
- timeout: undefined
679
+ memorySize: 1536
682
680
  }
683
681
  ],
684
682
  [
@@ -691,8 +689,7 @@ function Make(Platform) {
691
689
  [
692
690
  "Orders",
693
691
  {
694
- memorySize: 1024,
695
- timeout: undefined
692
+ memorySize: 1024
696
693
  }
697
694
  ]
698
695
  ]), Stdlib_Option.map(process.env.ORDERING_UI_BUNDLE_URL, url => Platform.Plugin.makeAutoUIManifest(url, "Ordering", pluginStructure, ["platform-summary"], ["resource-detail"])), pluginStructure, undefined);
@@ -51,7 +51,7 @@ describe("GeocodeCustomerAddress OutboundTranslationSlice", () => {
51
51
  {
52
52
  label: "Stephansplatz 1, Vienna",
53
53
  point: vienna,
54
- relevance: Some(0.995),
54
+ relevance: 0.995,
55
55
  },
56
56
  ]),
57
57
  ),
@@ -71,12 +71,12 @@ describe("GeocodeCustomerAddress OutboundTranslationSlice", () => {
71
71
  {
72
72
  label: "Springfield, IL",
73
73
  point: vienna,
74
- relevance: Some(0.99),
74
+ relevance: 0.99,
75
75
  },
76
76
  {
77
77
  label: "Springfield, MA",
78
78
  point: vienna,
79
- relevance: Some(0.985),
79
+ relevance: 0.985,
80
80
  },
81
81
  ]),
82
82
  ),
@@ -53,7 +53,7 @@ let vienna = {
53
53
  };
54
54
 
55
55
  function geocoder(answer) {
56
- return fakes(async param => answer, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
56
+ return fakes(async param => answer, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
57
57
  }
58
58
 
59
59
  describe("GeocodeCustomerAddress OutboundTranslationSlice", () => {
@@ -56,11 +56,11 @@ let item = {
56
56
  };
57
57
 
58
58
  function withSecrets(send, param) {
59
- return fakes(undefined, send, ["Email"], undefined, undefined, "known-secret", t => `hashed:` + t, undefined, undefined);
59
+ return fakes(undefined, send, ["Email"], undefined, undefined, "known-secret", t => `hashed:` + t, undefined, undefined, undefined, undefined);
60
60
  }
61
61
 
62
62
  function withoutSecrets() {
63
- return fakes(undefined, undefined, ["Email"], undefined, undefined, undefined, undefined, Secrets$Reventless.unavailable("none provisioned"), undefined);
63
+ return fakes(undefined, undefined, ["Email"], undefined, undefined, undefined, undefined, Secrets$Reventless.unavailable("none provisioned"), undefined, undefined, undefined);
64
64
  }
65
65
 
66
66
  function refuses(failure) {
@@ -115,8 +115,8 @@ describe("Ordering flow — place → auto-ship → confirm", () => {
115
115
  {state: Placed, at: "1970-01-01T00:00:00Z"},
116
116
  {state: Shipped, at: "1970-01-01T00:00:00Z"},
117
117
  ],
118
- deliveryWindow: Some(window),
119
- firstProductName: Some("Book"),
118
+ deliveryWindow: window,
119
+ firstProductName: "Book",
120
120
  firstProductImage: None,
121
121
  },
122
122
  )
@@ -58,7 +58,7 @@ let item = {
58
58
  };
59
59
 
60
60
  function provider(answer) {
61
- return fakes(undefined, async (param, param$1) => answer, ["Email"], undefined, undefined, undefined, undefined, undefined, undefined);
61
+ return fakes(undefined, async (param, param$1) => answer, ["Email"], undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
62
62
  }
63
63
 
64
64
  describe("SendNotification OutboundTranslationSlice", () => {
@@ -34,7 +34,7 @@ let row = (category, reference, outcome, detail, settledAt): state => {
34
34
  origin: "Default",
35
35
  detail,
36
36
  decidedAt: "1970-01-01T00:00:00Z",
37
- settledAt,
37
+ ?settledAt,
38
38
  }
39
39
 
40
40
  describe("NotificationDeliveries StateViewSliceStream", () => {
@@ -60,8 +60,6 @@ describe("Orders StateViewSlice", () => {
60
60
  shippingMethod: Standard,
61
61
  placedAt: epoch,
62
62
  trail: trail([Placed]),
63
- deliveryWindow: None,
64
- firstProductName: None,
65
63
  firstProductImage: None,
66
64
  },
67
65
  )
@@ -104,8 +102,7 @@ describe("Orders StateViewSlice", () => {
104
102
  shippingMethod: Standard,
105
103
  placedAt: epoch,
106
104
  trail: trail([Placed]),
107
- deliveryWindow: Some(window),
108
- firstProductName: None,
105
+ deliveryWindow: window,
109
106
  firstProductImage: None,
110
107
  },
111
108
  )
@@ -140,8 +137,6 @@ describe("Orders StateViewSlice", () => {
140
137
  shippingMethod: Pickup,
141
138
  placedAt: epoch,
142
139
  trail: trail([Placed]),
143
- deliveryWindow: None,
144
- firstProductName: None,
145
140
  firstProductImage: None,
146
141
  },
147
142
  )
@@ -176,8 +171,6 @@ describe("Orders StateViewSlice", () => {
176
171
  shippingMethod: Express,
177
172
  placedAt: epoch,
178
173
  trail: trail([Placed, Shipped]),
179
- deliveryWindow: None,
180
- firstProductName: None,
181
174
  firstProductImage: None,
182
175
  },
183
176
  )
@@ -212,8 +205,6 @@ describe("Orders StateViewSlice", () => {
212
205
  shippingMethod: Standard,
213
206
  placedAt: epoch,
214
207
  trail: trail([Placed, Cancelled]),
215
- deliveryWindow: None,
216
- firstProductName: None,
217
208
  firstProductImage: None,
218
209
  },
219
210
  )
@@ -254,8 +245,6 @@ describe("Orders StateViewSlice", () => {
254
245
  shippingMethod: Standard,
255
246
  placedAt: epoch,
256
247
  trail: trail([Placed, Cancelled, Placed]),
257
- deliveryWindow: None,
258
- firstProductName: None,
259
248
  firstProductImage: None,
260
249
  },
261
250
  )
@@ -95,8 +95,6 @@ describe("Orders StateViewSlice", () => {
95
95
  itemCount: 3,
96
96
  lifecycle: "Placed",
97
97
  shippingMethod: "Standard",
98
- deliveryWindow: undefined,
99
- firstProductName: undefined,
100
98
  firstProductImage: undefined
101
99
  }));
102
100
  test("a requested delivery window lands on the row", undefined, () => {
@@ -124,7 +122,6 @@ describe("Orders StateViewSlice", () => {
124
122
  lifecycle: "Placed",
125
123
  shippingMethod: "Standard",
126
124
  deliveryWindow: window,
127
- firstProductName: undefined,
128
125
  firstProductImage: undefined
129
126
  });
130
127
  });
@@ -150,8 +147,6 @@ describe("Orders StateViewSlice", () => {
150
147
  itemCount: 1,
151
148
  lifecycle: "Placed",
152
149
  shippingMethod: "Pickup",
153
- deliveryWindow: undefined,
154
- firstProductName: undefined,
155
150
  firstProductImage: undefined
156
151
  }));
157
152
  test("OrderShipped updates status to Shipped", undefined, () => thenStateWithId(whenEvent(givenEvents([{
@@ -182,8 +177,6 @@ describe("Orders StateViewSlice", () => {
182
177
  itemCount: 1,
183
178
  lifecycle: "Shipped",
184
179
  shippingMethod: "Express",
185
- deliveryWindow: undefined,
186
- firstProductName: undefined,
187
180
  firstProductImage: undefined
188
181
  }));
189
182
  test("OrderCancelled updates status to Cancelled", undefined, () => thenStateWithId(whenEvent(givenEvents([{
@@ -214,8 +207,6 @@ describe("Orders StateViewSlice", () => {
214
207
  itemCount: 1,
215
208
  lifecycle: "Cancelled",
216
209
  shippingMethod: "Standard",
217
- deliveryWindow: undefined,
218
- firstProductName: undefined,
219
210
  firstProductImage: undefined
220
211
  }));
221
212
  test("OrderReopened puts a cancelled order back to Placed", undefined, () => thenStateWithId(whenEvent(givenEvents([
@@ -253,8 +244,6 @@ describe("Orders StateViewSlice", () => {
253
244
  itemCount: 1,
254
245
  lifecycle: "Placed",
255
246
  shippingMethod: "Standard",
256
- deliveryWindow: undefined,
257
- firstProductName: undefined,
258
247
  firstProductImage: undefined
259
248
  }));
260
249
  });