@eventcatalog/create-eventcatalog 4.3.12 → 4.3.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/amazon-api-gateway/README-template.md +4 -0
- package/templates/asyncapi/README-template.md +4 -0
- package/templates/asyncapi/env +0 -5
- package/templates/confluent/README-template.md +4 -0
- package/templates/default/README-template.md +4 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/commands/CreateProduct/examples/index.mdx +194 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/commands/DeleteProduct/examples/index.mdx +161 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/commands/UpdateProduct/examples/index.mdx +182 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/events/ProductCreated/examples/index.mdx +227 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/events/ProductDeleted/examples/index.mdx +175 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/events/ProductUpdated/examples/index.mdx +205 -0
- package/templates/default/domains/Catalog/systems/product-catalog-system/services/ProductAPI/queries/GetProduct/examples/index.mdx +205 -0
- package/templates/default/domains/Catalog/systems/search-system/services/SearchAPI/queries/SearchProducts/examples/index.mdx +369 -0
- package/templates/default/domains/Customer/systems/customer-management-system/services/CustomerAPI/commands/RegisterCustomer/examples/index.mdx +168 -0
- package/templates/default/domains/Customer/systems/customer-management-system/services/CustomerAPI/commands/UpdateCustomer/examples/index.mdx +168 -0
- package/templates/default/domains/Customer/systems/customer-management-system/services/CustomerAPI/events/CustomerRegistered/examples/index.mdx +201 -0
- package/templates/default/domains/Customer/systems/customer-management-system/services/CustomerAPI/events/CustomerUpdated/examples/index.mdx +194 -0
- package/templates/default/domains/Customer/systems/customer-management-system/services/CustomerAPI/queries/GetCustomer/examples/index.mdx +194 -0
- package/templates/default/domains/Customer/systems/identity-provider/services/OAuthAPI/commands/AuthenticateCustomer/examples/index.mdx +198 -0
- package/templates/default/domains/Customer/systems/identity-provider/services/OAuthAPI/events/CustomerAuthenticated/examples/index.mdx +276 -0
- package/templates/default/domains/Fulfilment/systems/carrier/services/CarrierTrackingAPI/events/ShipmentCreated/examples/index.mdx +184 -0
- package/templates/default/domains/Fulfilment/systems/carrier/services/CarrierTrackingAPI/events/ShipmentDelivered/examples/index.mdx +173 -0
- package/templates/default/domains/Fulfilment/systems/carrier/services/CarrierTrackingAPI/events/ShipmentFailed/examples/index.mdx +265 -0
- package/templates/default/domains/Fulfilment/systems/inventory-system/services/InventoryService/commands/ReleaseInventory/examples/index.mdx +246 -0
- package/templates/default/domains/Fulfilment/systems/inventory-system/services/InventoryService/events/InventoryReserved/examples/index.mdx +227 -0
- package/templates/default/domains/Fulfilment/systems/inventory-system/services/InventoryService/events/InventoryUnavailable/examples/index.mdx +229 -0
- package/templates/default/domains/Fulfilment/systems/inventory-system/services/InventoryService/queries/GetStockLevel/examples/index.mdx +186 -0
- package/templates/default/domains/Fulfilment/systems/shipping-system/services/CarrierAdapter/commands/CreateShipment/examples/index.mdx +206 -0
- package/templates/default/domains/Fulfilment/systems/warehouse-system/services/PickingWorker/events/OrderPacked/examples/index.mdx +172 -0
- package/templates/default/domains/Fulfilment/systems/warehouse-system/services/WarehouseService/events/OrderReadyForShipping/examples/index.mdx +208 -0
- package/templates/default/domains/Ordering/systems/checkout-system/services/CheckoutOrchestrator/commands/AuthorizePayment/examples/index.mdx +179 -0
- package/templates/default/domains/Ordering/systems/checkout-system/services/CheckoutOrchestrator/commands/ReserveInventory/examples/index.mdx +215 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/commands/CancelOrder/examples/index.mdx +163 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/commands/CreateOrder/examples/index.mdx +246 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/events/OrderCancelled/examples/index.mdx +267 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/events/OrderCompleted/examples/index.mdx +171 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/events/OrderCreated/examples/index.mdx +190 -0
- package/templates/default/domains/Ordering/systems/order-management-system/services/OrderService/queries/GetOrder/examples/index.mdx +343 -0
- package/templates/default/domains/Payments/systems/fraud-detection/services/FraudAPI/events/FraudCheckFailed/examples/index.mdx +271 -0
- package/templates/default/domains/Payments/systems/fraud-detection/services/FraudAPI/events/FraudCheckPassed/examples/index.mdx +173 -0
- package/templates/default/domains/Payments/systems/payment-processing-system/services/PaymentWorker/events/PaymentRequested/examples/index.mdx +191 -0
- package/templates/default/domains/Payments/systems/payment-processing-system/services/PaymentWorker/events/RefundRequested/examples/index.mdx +194 -0
- package/templates/default/domains/Payments/systems/stripe/services/StripeWebhookEndpoint/events/PaymentFailed/examples/index.mdx +265 -0
- package/templates/default/domains/Payments/systems/stripe/services/StripeWebhookEndpoint/events/PaymentSucceeded/examples/index.mdx +190 -0
- package/templates/default/domains/Payments/systems/stripe/services/StripeWebhookEndpoint/events/RefundProcessed/examples/index.mdx +186 -0
- package/templates/default/domains/Reviews/services/RatingAggregator/events/rating-updated/examples/index.mdx +183 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/commands/flag-review/examples/index.mdx +183 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/commands/submit-review/examples/index.mdx +195 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/commands/vote-review-helpful/examples/index.mdx +178 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/events/review-flagged/examples/index.mdx +186 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/events/review-helpful-voted/examples/index.mdx +177 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/events/review-submitted/examples/index.mdx +194 -0
- package/templates/default/domains/Reviews/services/ReviewAPI/queries/get-product-reviews/examples/index.mdx +259 -0
- package/templates/default/domains/Reviews/services/ReviewModerationWorker/events/review-published/examples/index.mdx +183 -0
- package/templates/default/domains/Reviews/services/ReviewModerationWorker/events/review-rejected/examples/index.mdx +178 -0
- package/templates/default/domains/Shopping/systems/cart-system/services/CartAPI/commands/AddItemToCart/examples/index.mdx +171 -0
- package/templates/default/domains/Shopping/systems/cart-system/services/CartAPI/commands/CheckoutCart/examples/index.mdx +168 -0
- package/templates/default/domains/Shopping/systems/cart-system/services/CartAPI/commands/RemoveItemFromCart/examples/index.mdx +170 -0
- package/templates/default/domains/Shopping/systems/cart-system/services/CartAPI/events/CartCheckedOut/examples/index.mdx +275 -0
- package/templates/default/domains/Shopping/systems/promotion-system/services/PromotionService/commands/CalculateDiscount/examples/index.mdx +207 -0
- package/templates/default/domains/Shopping/systems/promotion-system/services/PromotionService/events/DiscountCalculated/examples/index.mdx +190 -0
- package/templates/default/env +0 -5
- package/templates/empty/README-template.md +4 -0
- package/templates/empty/env +0 -5
- package/templates/eventbridge/README-template.md +4 -0
- package/templates/graphql/README-template.md +4 -0
- package/templates/graphql/env +0 -5
- package/templates/openapi/README-template.md +4 -0
- package/templates/openapi/env +0 -5
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<Columns cols={2}>
|
|
2
|
+
|
|
3
|
+
<Column>
|
|
4
|
+
|
|
5
|
+
## 1. Publish a profile change
|
|
6
|
+
|
|
7
|
+
A customer changed their surname and email address in account settings. The Customer API publishes this event so systems such as order notifications and marketing can update their copy of the customer.
|
|
8
|
+
|
|
9
|
+
### Payload details
|
|
10
|
+
|
|
11
|
+
- `eventId` is a unique UUID for this event, and `occurredAt` is the ISO-8601 UTC time of the change.
|
|
12
|
+
- `customerId` identifies the customer that changed.
|
|
13
|
+
- `changes` holds only the fields that changed, with their new values: `email` and `name`.
|
|
14
|
+
- `status` is not in `changes`, so it did not change.
|
|
15
|
+
|
|
16
|
+
### Using this example
|
|
17
|
+
|
|
18
|
+
Use this to check that consumers apply only the fields present in `changes` and leave everything else as it was.
|
|
19
|
+
|
|
20
|
+
The examples use a **fictional Acme Events SDK** to publish a payload matching the CustomerUpdated schema. The package names and publish methods are illustrative.
|
|
21
|
+
|
|
22
|
+
</Column>
|
|
23
|
+
|
|
24
|
+
<Column>
|
|
25
|
+
|
|
26
|
+
<CodeGroup dropdown>
|
|
27
|
+
|
|
28
|
+
```typescript publish-customer-updated.ts
|
|
29
|
+
import { EventsClient } from '@acme/events';
|
|
30
|
+
import type { CustomerUpdated } from './schemas/customer-updated';
|
|
31
|
+
|
|
32
|
+
const client = new EventsClient({
|
|
33
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const event: CustomerUpdated = {
|
|
37
|
+
eventId: '7b9d2f4a-6c8e-4a1b-b3d5-9f1e3a5c7b20',
|
|
38
|
+
occurredAt: '2026-09-11T08:12:45Z',
|
|
39
|
+
customerId: '3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c',
|
|
40
|
+
changes: {
|
|
41
|
+
email: 'amelia.hart-jones@example.com',
|
|
42
|
+
name: 'Amelia Hart-Jones',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
await client.publish('CustomerUpdated', event);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```python publish_customer_updated.py
|
|
50
|
+
import os
|
|
51
|
+
from acme_events import EventsClient
|
|
52
|
+
|
|
53
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
54
|
+
|
|
55
|
+
event = {
|
|
56
|
+
"eventId": "7b9d2f4a-6c8e-4a1b-b3d5-9f1e3a5c7b20",
|
|
57
|
+
"occurredAt": "2026-09-11T08:12:45Z",
|
|
58
|
+
"customerId": "3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c",
|
|
59
|
+
"changes": {
|
|
60
|
+
"email": "amelia.hart-jones@example.com",
|
|
61
|
+
"name": "Amelia Hart-Jones",
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
client.publish("CustomerUpdated", event)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```java PublishCustomerUpdated.java
|
|
69
|
+
import com.acme.events.EventsClient;
|
|
70
|
+
import java.util.Map;
|
|
71
|
+
|
|
72
|
+
public class PublishCustomerUpdated {
|
|
73
|
+
public static void main(String[] args) {
|
|
74
|
+
var client = new EventsClient(
|
|
75
|
+
System.getenv("ACME_API_KEY")
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
var event = Map.of(
|
|
79
|
+
"eventId", "7b9d2f4a-6c8e-4a1b-b3d5-9f1e3a5c7b20",
|
|
80
|
+
"occurredAt", "2026-09-11T08:12:45Z",
|
|
81
|
+
"customerId", "3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c",
|
|
82
|
+
"changes", Map.of(
|
|
83
|
+
"email", "amelia.hart-jones@example.com",
|
|
84
|
+
"name", "Amelia Hart-Jones"
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
client.publish("CustomerUpdated", event);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
</CodeGroup>
|
|
94
|
+
|
|
95
|
+
</Column>
|
|
96
|
+
|
|
97
|
+
</Columns>
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
<Columns cols={2}>
|
|
102
|
+
|
|
103
|
+
<Column>
|
|
104
|
+
|
|
105
|
+
## 2. Publish a status change
|
|
106
|
+
|
|
107
|
+
The fraud team suspended an account after a chargeback. The event carries a single change, so consumers such as checkout and order fulfilment can stop processing new orders for this customer.
|
|
108
|
+
|
|
109
|
+
### Payload details
|
|
110
|
+
|
|
111
|
+
- `eventId` and `occurredAt` identify this event and when the account was suspended.
|
|
112
|
+
- `customerId` identifies the suspended customer.
|
|
113
|
+
- `changes.status` is `SUSPENDED`. The schema requires at least one field in `changes`, and here there is exactly one.
|
|
114
|
+
- `email` and `name` are not in `changes`, so they did not change.
|
|
115
|
+
|
|
116
|
+
### Using this example
|
|
117
|
+
|
|
118
|
+
Use this to check that consumers react to a `status` change on its own, for example by blocking checkout for `SUSPENDED` customers.
|
|
119
|
+
|
|
120
|
+
The examples use a **fictional Acme Events SDK** to publish a payload matching the CustomerUpdated schema. The package names and publish methods are illustrative.
|
|
121
|
+
|
|
122
|
+
</Column>
|
|
123
|
+
|
|
124
|
+
<Column>
|
|
125
|
+
|
|
126
|
+
<CodeGroup dropdown>
|
|
127
|
+
|
|
128
|
+
```typescript publish-customer-updated.ts
|
|
129
|
+
import { EventsClient } from '@acme/events';
|
|
130
|
+
import type { CustomerUpdated } from './schemas/customer-updated';
|
|
131
|
+
|
|
132
|
+
const client = new EventsClient({
|
|
133
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const event: CustomerUpdated = {
|
|
137
|
+
eventId: 'e4f6a8b0-3c5d-4e7f-9a1b-6c8d0e2f4a36',
|
|
138
|
+
occurredAt: '2026-09-15T14:03:19Z',
|
|
139
|
+
customerId: 'c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13',
|
|
140
|
+
changes: {
|
|
141
|
+
status: 'SUSPENDED',
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
await client.publish('CustomerUpdated', event);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```python publish_customer_updated.py
|
|
149
|
+
import os
|
|
150
|
+
from acme_events import EventsClient
|
|
151
|
+
|
|
152
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
153
|
+
|
|
154
|
+
event = {
|
|
155
|
+
"eventId": "e4f6a8b0-3c5d-4e7f-9a1b-6c8d0e2f4a36",
|
|
156
|
+
"occurredAt": "2026-09-15T14:03:19Z",
|
|
157
|
+
"customerId": "c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13",
|
|
158
|
+
"changes": {
|
|
159
|
+
"status": "SUSPENDED",
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
client.publish("CustomerUpdated", event)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```java PublishCustomerUpdated.java
|
|
167
|
+
import com.acme.events.EventsClient;
|
|
168
|
+
import java.util.Map;
|
|
169
|
+
|
|
170
|
+
public class PublishCustomerUpdated {
|
|
171
|
+
public static void main(String[] args) {
|
|
172
|
+
var client = new EventsClient(
|
|
173
|
+
System.getenv("ACME_API_KEY")
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
var event = Map.of(
|
|
177
|
+
"eventId", "e4f6a8b0-3c5d-4e7f-9a1b-6c8d0e2f4a36",
|
|
178
|
+
"occurredAt", "2026-09-15T14:03:19Z",
|
|
179
|
+
"customerId", "c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13",
|
|
180
|
+
"changes", Map.of(
|
|
181
|
+
"status", "SUSPENDED"
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
client.publish("CustomerUpdated", event);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
</CodeGroup>
|
|
191
|
+
|
|
192
|
+
</Column>
|
|
193
|
+
|
|
194
|
+
</Columns>
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<Columns cols={2}>
|
|
2
|
+
|
|
3
|
+
<Column>
|
|
4
|
+
|
|
5
|
+
## 1. Fetch an active customer's profile
|
|
6
|
+
|
|
7
|
+
The storefront account page asks the Customer API for the signed-in customer so it can show their name and email address. The Customer API reads the record from the customer database and returns it.
|
|
8
|
+
|
|
9
|
+
### Payload details
|
|
10
|
+
|
|
11
|
+
- `request.customerId` is the UUID of the customer to look up, taken from the customer's session.
|
|
12
|
+
- The response includes every field: `email`, `name` and `registeredAt` alongside the required `customerId` and `status`.
|
|
13
|
+
- `status` is `ACTIVE`, so the customer can browse, check out and manage their account as normal.
|
|
14
|
+
- `registeredAt` is an ISO-8601 UTC timestamp showing when the account was created.
|
|
15
|
+
|
|
16
|
+
### Example response
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"customerId": "3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c",
|
|
21
|
+
"email": "amelia.hart@example.com",
|
|
22
|
+
"name": "Amelia Hart",
|
|
23
|
+
"status": "ACTIVE",
|
|
24
|
+
"registeredAt": "2026-03-14T10:22:05Z"
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Using this example
|
|
29
|
+
|
|
30
|
+
Use this to check that the account page renders the customer's name and email, and that the returned `customerId` matches the one requested.
|
|
31
|
+
|
|
32
|
+
The examples use a **fictional Acme Events SDK** to query a payload matching the GetCustomer schema. The package names and query methods are illustrative.
|
|
33
|
+
|
|
34
|
+
</Column>
|
|
35
|
+
|
|
36
|
+
<Column>
|
|
37
|
+
|
|
38
|
+
<CodeGroup dropdown>
|
|
39
|
+
|
|
40
|
+
```typescript query-get-customer.ts
|
|
41
|
+
import { EventsClient } from '@acme/events';
|
|
42
|
+
import type { GetCustomerRequest, GetCustomerResponse } from './schemas/get-customer';
|
|
43
|
+
|
|
44
|
+
const client = new EventsClient({
|
|
45
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const request: GetCustomerRequest = {
|
|
49
|
+
customerId: '3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const customer: GetCustomerResponse = await client.query('GetCustomer', request);
|
|
53
|
+
|
|
54
|
+
console.log(customer.name, customer.email);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```python query_get_customer.py
|
|
58
|
+
import os
|
|
59
|
+
from acme_events import EventsClient
|
|
60
|
+
|
|
61
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
62
|
+
|
|
63
|
+
request = {
|
|
64
|
+
"customerId": "3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
customer = client.query("GetCustomer", request)
|
|
68
|
+
|
|
69
|
+
print(customer["name"], customer["email"])
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```java QueryGetCustomer.java
|
|
73
|
+
import com.acme.events.EventsClient;
|
|
74
|
+
import java.util.Map;
|
|
75
|
+
|
|
76
|
+
public class QueryGetCustomer {
|
|
77
|
+
public static void main(String[] args) {
|
|
78
|
+
var client = new EventsClient(
|
|
79
|
+
System.getenv("ACME_API_KEY")
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
var request = Map.of(
|
|
83
|
+
"customerId", "3f2b8c1e-7a4d-4e9b-9c21-5d8e6f0a1b2c"
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
var customer = client.query("GetCustomer", request);
|
|
87
|
+
|
|
88
|
+
System.out.println(customer.get("name") + " " + customer.get("email"));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
</CodeGroup>
|
|
94
|
+
|
|
95
|
+
</Column>
|
|
96
|
+
|
|
97
|
+
</Columns>
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
<Columns cols={2}>
|
|
102
|
+
|
|
103
|
+
<Column>
|
|
104
|
+
|
|
105
|
+
## 2. Check a suspended customer before checkout
|
|
106
|
+
|
|
107
|
+
Before accepting an order, the checkout flow queries the customer to confirm the account is in good standing. This customer has been suspended, so checkout should stop and point them to support.
|
|
108
|
+
|
|
109
|
+
### Payload details
|
|
110
|
+
|
|
111
|
+
- `request.customerId` identifies the customer placing the order.
|
|
112
|
+
- The response contains only the required fields: `customerId`, `email` and `status`. The optional `name` and `registeredAt` are omitted.
|
|
113
|
+
- `status` is `SUSPENDED`, which means the account exists but must not be allowed to place orders.
|
|
114
|
+
|
|
115
|
+
### Example response
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"customerId": "c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13",
|
|
120
|
+
"email": "tom.okafor@example.co.uk",
|
|
121
|
+
"status": "SUSPENDED"
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Using this example
|
|
126
|
+
|
|
127
|
+
Use this to check that callers cope with a response that has no `name` or `registeredAt`, and that checkout blocks any customer whose `status` is not `ACTIVE`.
|
|
128
|
+
|
|
129
|
+
The examples use a **fictional Acme Events SDK** to query a payload matching the GetCustomer schema. The package names and query methods are illustrative.
|
|
130
|
+
|
|
131
|
+
</Column>
|
|
132
|
+
|
|
133
|
+
<Column>
|
|
134
|
+
|
|
135
|
+
<CodeGroup dropdown>
|
|
136
|
+
|
|
137
|
+
```typescript query-get-customer.ts
|
|
138
|
+
import { EventsClient } from '@acme/events';
|
|
139
|
+
import type { GetCustomerRequest, GetCustomerResponse } from './schemas/get-customer';
|
|
140
|
+
|
|
141
|
+
const client = new EventsClient({
|
|
142
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const request: GetCustomerRequest = {
|
|
146
|
+
customerId: 'c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13',
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const customer: GetCustomerResponse = await client.query('GetCustomer', request);
|
|
150
|
+
|
|
151
|
+
console.log(customer.status, customer.email);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```python query_get_customer.py
|
|
155
|
+
import os
|
|
156
|
+
from acme_events import EventsClient
|
|
157
|
+
|
|
158
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
159
|
+
|
|
160
|
+
request = {
|
|
161
|
+
"customerId": "c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13",
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
customer = client.query("GetCustomer", request)
|
|
165
|
+
|
|
166
|
+
print(customer["status"], customer["email"])
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```java QueryGetCustomer.java
|
|
170
|
+
import com.acme.events.EventsClient;
|
|
171
|
+
import java.util.Map;
|
|
172
|
+
|
|
173
|
+
public class QueryGetCustomer {
|
|
174
|
+
public static void main(String[] args) {
|
|
175
|
+
var client = new EventsClient(
|
|
176
|
+
System.getenv("ACME_API_KEY")
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
var request = Map.of(
|
|
180
|
+
"customerId", "c9a4e2f7-1b3d-4c8e-a5f6-7d2e9b0c4a13"
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
var customer = client.query("GetCustomer", request);
|
|
184
|
+
|
|
185
|
+
System.out.println(customer.get("status") + " " + customer.get("email"));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
</CodeGroup>
|
|
191
|
+
|
|
192
|
+
</Column>
|
|
193
|
+
|
|
194
|
+
</Columns>
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
<Columns cols={2}>
|
|
2
|
+
|
|
3
|
+
<Column>
|
|
4
|
+
|
|
5
|
+
## 1. Sign a customer in from the storefront
|
|
6
|
+
|
|
7
|
+
A customer signs in on the web storefront to view their orders. The OAuth API checks the credentials against the user directory, returns an access token and publishes `CustomerAuthenticated`.
|
|
8
|
+
|
|
9
|
+
### Payload details
|
|
10
|
+
|
|
11
|
+
- `request.email` and `request.password` are the credentials the customer typed in.
|
|
12
|
+
- `response.accessToken` is the token the storefront sends with later API calls.
|
|
13
|
+
- `response.tokenType` is always `Bearer`.
|
|
14
|
+
- `response.expiresIn` is the token lifetime in seconds: **3,600 seconds (1 hour)**.
|
|
15
|
+
|
|
16
|
+
### Example response
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzZjJiOGMxZSJ9.kX9vQ2Lm",
|
|
21
|
+
"tokenType": "Bearer",
|
|
22
|
+
"expiresIn": 3600
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Using this example
|
|
27
|
+
|
|
28
|
+
Use this to check that a valid sign-in returns a `Bearer` token, and that the client refreshes or re-authenticates before `expiresIn` runs out.
|
|
29
|
+
|
|
30
|
+
The examples use a **fictional Acme Events SDK** to send a payload matching the AuthenticateCustomer schema. The package names and send methods are illustrative.
|
|
31
|
+
|
|
32
|
+
</Column>
|
|
33
|
+
|
|
34
|
+
<Column>
|
|
35
|
+
|
|
36
|
+
<CodeGroup dropdown>
|
|
37
|
+
|
|
38
|
+
```typescript send-authenticate-customer.ts
|
|
39
|
+
import { EventsClient } from '@acme/events';
|
|
40
|
+
import type { AuthenticateCustomerRequest, AuthenticateCustomerResponse } from './schemas/authenticate-customer';
|
|
41
|
+
|
|
42
|
+
const client = new EventsClient({
|
|
43
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const request: AuthenticateCustomerRequest = {
|
|
47
|
+
email: 'amelia.hart@example.com',
|
|
48
|
+
password: 'Blue-Tshirt-42!',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const token: AuthenticateCustomerResponse = await client.send('AuthenticateCustomer', request);
|
|
52
|
+
|
|
53
|
+
console.log(token.tokenType, token.expiresIn);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```python send_authenticate_customer.py
|
|
57
|
+
import os
|
|
58
|
+
from acme_events import EventsClient
|
|
59
|
+
|
|
60
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
61
|
+
|
|
62
|
+
request = {
|
|
63
|
+
"email": "amelia.hart@example.com",
|
|
64
|
+
"password": "Blue-Tshirt-42!",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
token = client.send("AuthenticateCustomer", request)
|
|
68
|
+
|
|
69
|
+
print(token["tokenType"], token["expiresIn"])
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```java SendAuthenticateCustomer.java
|
|
73
|
+
import com.acme.events.EventsClient;
|
|
74
|
+
import java.util.Map;
|
|
75
|
+
|
|
76
|
+
public class SendAuthenticateCustomer {
|
|
77
|
+
public static void main(String[] args) {
|
|
78
|
+
var client = new EventsClient(
|
|
79
|
+
System.getenv("ACME_API_KEY")
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
var request = Map.of(
|
|
83
|
+
"email", "amelia.hart@example.com",
|
|
84
|
+
"password", "Blue-Tshirt-42!"
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
var token = client.send("AuthenticateCustomer", request);
|
|
88
|
+
|
|
89
|
+
System.out.println(token.get("tokenType") + " " + token.get("expiresIn"));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
</CodeGroup>
|
|
95
|
+
|
|
96
|
+
</Column>
|
|
97
|
+
|
|
98
|
+
</Columns>
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
<Columns cols={2}>
|
|
103
|
+
|
|
104
|
+
<Column>
|
|
105
|
+
|
|
106
|
+
## 2. Sign a customer in during checkout
|
|
107
|
+
|
|
108
|
+
A returning customer signs in part-way through checking out a basket of caps. The OAuth API issues a short-lived token that only needs to last until the order is placed.
|
|
109
|
+
|
|
110
|
+
### Payload details
|
|
111
|
+
|
|
112
|
+
- `request.email` and `request.password` are the customer's credentials.
|
|
113
|
+
- `response.tokenType` is `Bearer`.
|
|
114
|
+
- `response.expiresIn` is **900 seconds (15 minutes)**, so the client must handle the token expiring and ask the customer to sign in again.
|
|
115
|
+
|
|
116
|
+
### Example response
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjOWE0ZTJmNyJ9.pR4tZ8Wn",
|
|
121
|
+
"tokenType": "Bearer",
|
|
122
|
+
"expiresIn": 900
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Using this example
|
|
127
|
+
|
|
128
|
+
Use this to check that the client reads `expiresIn` rather than assuming a fixed lifetime, and prompts for sign-in again once the token has expired.
|
|
129
|
+
|
|
130
|
+
The examples use a **fictional Acme Events SDK** to send a payload matching the AuthenticateCustomer schema. The package names and send methods are illustrative.
|
|
131
|
+
|
|
132
|
+
</Column>
|
|
133
|
+
|
|
134
|
+
<Column>
|
|
135
|
+
|
|
136
|
+
<CodeGroup dropdown>
|
|
137
|
+
|
|
138
|
+
```typescript send-authenticate-customer.ts
|
|
139
|
+
import { EventsClient } from '@acme/events';
|
|
140
|
+
import type { AuthenticateCustomerRequest, AuthenticateCustomerResponse } from './schemas/authenticate-customer';
|
|
141
|
+
|
|
142
|
+
const client = new EventsClient({
|
|
143
|
+
apiKey: process.env.ACME_API_KEY!,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const request: AuthenticateCustomerRequest = {
|
|
147
|
+
email: 'tom.okafor@example.co.uk',
|
|
148
|
+
password: 'Hoodie-Season-2026',
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const token: AuthenticateCustomerResponse = await client.send('AuthenticateCustomer', request);
|
|
152
|
+
|
|
153
|
+
console.log(token.tokenType, token.expiresIn);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```python send_authenticate_customer.py
|
|
157
|
+
import os
|
|
158
|
+
from acme_events import EventsClient
|
|
159
|
+
|
|
160
|
+
client = EventsClient(api_key=os.environ["ACME_API_KEY"])
|
|
161
|
+
|
|
162
|
+
request = {
|
|
163
|
+
"email": "tom.okafor@example.co.uk",
|
|
164
|
+
"password": "Hoodie-Season-2026",
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
token = client.send("AuthenticateCustomer", request)
|
|
168
|
+
|
|
169
|
+
print(token["tokenType"], token["expiresIn"])
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```java SendAuthenticateCustomer.java
|
|
173
|
+
import com.acme.events.EventsClient;
|
|
174
|
+
import java.util.Map;
|
|
175
|
+
|
|
176
|
+
public class SendAuthenticateCustomer {
|
|
177
|
+
public static void main(String[] args) {
|
|
178
|
+
var client = new EventsClient(
|
|
179
|
+
System.getenv("ACME_API_KEY")
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
var request = Map.of(
|
|
183
|
+
"email", "tom.okafor@example.co.uk",
|
|
184
|
+
"password", "Hoodie-Season-2026"
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
var token = client.send("AuthenticateCustomer", request);
|
|
188
|
+
|
|
189
|
+
System.out.println(token.get("tokenType") + " " + token.get("expiresIn"));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
</CodeGroup>
|
|
195
|
+
|
|
196
|
+
</Column>
|
|
197
|
+
|
|
198
|
+
</Columns>
|