@tuongaz/seeflow 0.1.25 → 0.1.27
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/dist/web/assets/index-BotEftAD.css +1 -0
- package/dist/web/assets/{index-BJ7xSozm.js → index-CdNWAi1U.js} +4 -4
- package/dist/web/assets/{index.es-B3xFOWmE.js → index.es-CPyvUCV3.js} +1 -1
- package/dist/web/assets/{jspdf.es.min-Dh_oxn-h.js → jspdf.es.min-Dkq0NSxE.js} +3 -3
- package/dist/web/index.html +2 -2
- package/examples/ecommerce-platform/.seeflow/{seeflow.json → architecture.json} +14 -77
- package/examples/ecommerce-platform/.seeflow/details/api-gateway.md +14 -0
- package/examples/ecommerce-platform/.seeflow/details/auth-service.md +9 -0
- package/examples/ecommerce-platform/.seeflow/details/cart-service.md +10 -0
- package/examples/ecommerce-platform/.seeflow/details/notification-service.md +13 -0
- package/examples/ecommerce-platform/.seeflow/details/order-service.md +16 -0
- package/examples/ecommerce-platform/.seeflow/details/payment-service.md +16 -0
- package/examples/ecommerce-platform/.seeflow/details/product-service.md +10 -0
- package/examples/ecommerce-platform/.seeflow/style.json +85 -0
- package/examples/order-pipeline/.seeflow/architecture.json +93 -0
- package/examples/order-pipeline/.seeflow/details/fulfillment-service.md +21 -0
- package/examples/order-pipeline/.seeflow/details/inventory-service.md +23 -0
- package/examples/order-pipeline/.seeflow/details/payment-service.md +23 -0
- package/examples/order-pipeline/.seeflow/details/post-orders.md +19 -0
- package/examples/order-pipeline/.seeflow/scripts/play.ts +2 -2
- package/examples/order-pipeline/.seeflow/style.json +42 -0
- package/package.json +1 -1
- package/src/api.ts +118 -118
- package/src/cli.ts +13 -13
- package/src/demo.ts +6 -6
- package/src/diagram.ts +4 -4
- package/src/events.ts +14 -14
- package/src/file-ref.ts +79 -0
- package/src/mcp.ts +117 -89
- package/src/merge.ts +190 -0
- package/src/operations.ts +415 -416
- package/src/proxy.ts +31 -31
- package/src/registry.ts +32 -20
- package/src/schema.ts +252 -8
- package/src/sdk-template.ts +2 -2
- package/src/sdk-writer.ts +2 -2
- package/src/server.ts +2 -2
- package/src/status-runner.ts +34 -38
- package/src/watcher.ts +165 -114
- package/dist/web/assets/index-Dwa7Bp5j.css +0 -1
- package/examples/order-pipeline/.seeflow/seeflow.json +0 -123
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 2,
|
|
3
3
|
"name": "E-Commerce Platform",
|
|
4
4
|
"nodes": [
|
|
5
5
|
{
|
|
6
6
|
"id": "client",
|
|
7
7
|
"type": "shapeNode",
|
|
8
|
-
"position": {
|
|
9
|
-
"x": 80,
|
|
10
|
-
"y": 215.5
|
|
11
|
-
},
|
|
12
8
|
"data": {
|
|
13
9
|
"shape": "user",
|
|
14
10
|
"name": "Customer",
|
|
15
|
-
"description": "Web / Mobile / Partner"
|
|
16
|
-
"fontSize": 15,
|
|
17
|
-
"borderColor": "green",
|
|
18
|
-
"borderSize": 1
|
|
11
|
+
"description": "Web / Mobile / Partner"
|
|
19
12
|
}
|
|
20
13
|
},
|
|
21
14
|
{
|
|
22
15
|
"id": "api-gateway",
|
|
23
16
|
"type": "playNode",
|
|
24
|
-
"position": {
|
|
25
|
-
"x": 320,
|
|
26
|
-
"y": 227
|
|
27
|
-
},
|
|
28
17
|
"data": {
|
|
29
18
|
"name": "API Gateway",
|
|
30
19
|
"kind": "gateway",
|
|
@@ -32,7 +21,7 @@
|
|
|
32
21
|
"kind": "request"
|
|
33
22
|
},
|
|
34
23
|
"description": "Auth, rate-limiting, routing.",
|
|
35
|
-
"detail": "
|
|
24
|
+
"detail": "file://details/api-gateway.md",
|
|
36
25
|
"playAction": {
|
|
37
26
|
"kind": "script",
|
|
38
27
|
"interpreter": "bun",
|
|
@@ -40,19 +29,12 @@
|
|
|
40
29
|
"run"
|
|
41
30
|
],
|
|
42
31
|
"scriptPath": "scripts/play.ts"
|
|
43
|
-
}
|
|
44
|
-
"fontSize": 15,
|
|
45
|
-
"borderColor": "green",
|
|
46
|
-
"borderSize": 1
|
|
32
|
+
}
|
|
47
33
|
}
|
|
48
34
|
},
|
|
49
35
|
{
|
|
50
36
|
"id": "auth-service",
|
|
51
37
|
"type": "stateNode",
|
|
52
|
-
"position": {
|
|
53
|
-
"x": 660,
|
|
54
|
-
"y": 50
|
|
55
|
-
},
|
|
56
38
|
"data": {
|
|
57
39
|
"name": "Auth Service",
|
|
58
40
|
"kind": "service",
|
|
@@ -60,19 +42,12 @@
|
|
|
60
42
|
"kind": "request"
|
|
61
43
|
},
|
|
62
44
|
"description": "JWT issuance + OAuth2 / OIDC.",
|
|
63
|
-
"detail": "
|
|
64
|
-
"fontSize": 15,
|
|
65
|
-
"borderColor": "green",
|
|
66
|
-
"borderSize": 1
|
|
45
|
+
"detail": "file://details/auth-service.md"
|
|
67
46
|
}
|
|
68
47
|
},
|
|
69
48
|
{
|
|
70
49
|
"id": "product-service",
|
|
71
50
|
"type": "stateNode",
|
|
72
|
-
"position": {
|
|
73
|
-
"x": 660,
|
|
74
|
-
"y": 218
|
|
75
|
-
},
|
|
76
51
|
"data": {
|
|
77
52
|
"name": "Product Catalog",
|
|
78
53
|
"kind": "service",
|
|
@@ -80,19 +55,12 @@
|
|
|
80
55
|
"kind": "request"
|
|
81
56
|
},
|
|
82
57
|
"description": "SKUs, variants, pricing, full-text search.",
|
|
83
|
-
"detail": "
|
|
84
|
-
"fontSize": 15,
|
|
85
|
-
"borderColor": "green",
|
|
86
|
-
"borderSize": 1
|
|
58
|
+
"detail": "file://details/product-service.md"
|
|
87
59
|
}
|
|
88
60
|
},
|
|
89
61
|
{
|
|
90
62
|
"id": "cart-service",
|
|
91
63
|
"type": "playNode",
|
|
92
|
-
"position": {
|
|
93
|
-
"x": 660,
|
|
94
|
-
"y": 413
|
|
95
|
-
},
|
|
96
64
|
"data": {
|
|
97
65
|
"name": "Cart Service",
|
|
98
66
|
"kind": "service",
|
|
@@ -100,7 +68,7 @@
|
|
|
100
68
|
"kind": "request"
|
|
101
69
|
},
|
|
102
70
|
"description": "Add/remove items, apply coupons, checkout.",
|
|
103
|
-
"detail": "
|
|
71
|
+
"detail": "file://details/cart-service.md",
|
|
104
72
|
"playAction": {
|
|
105
73
|
"kind": "script",
|
|
106
74
|
"interpreter": "bun",
|
|
@@ -108,27 +76,20 @@
|
|
|
108
76
|
"run"
|
|
109
77
|
],
|
|
110
78
|
"scriptPath": "scripts/play.ts"
|
|
111
|
-
}
|
|
112
|
-
"fontSize": 15,
|
|
113
|
-
"borderColor": "green",
|
|
114
|
-
"borderSize": 1
|
|
79
|
+
}
|
|
115
80
|
}
|
|
116
81
|
},
|
|
117
82
|
{
|
|
118
83
|
"id": "order-service",
|
|
119
84
|
"type": "playNode",
|
|
120
|
-
"position": {
|
|
121
|
-
"x": 1000,
|
|
122
|
-
"y": 413
|
|
123
|
-
},
|
|
124
85
|
"data": {
|
|
125
86
|
"name": "Order Service",
|
|
126
87
|
"kind": "worker",
|
|
127
88
|
"stateSource": {
|
|
128
89
|
"kind": "event"
|
|
129
90
|
},
|
|
130
|
-
"description": "pending
|
|
131
|
-
"detail": "
|
|
91
|
+
"description": "pending \u2192 confirmed \u2192 shipped \u2192 delivered.",
|
|
92
|
+
"detail": "file://details/order-service.md",
|
|
132
93
|
"playAction": {
|
|
133
94
|
"kind": "script",
|
|
134
95
|
"interpreter": "bun",
|
|
@@ -136,19 +97,12 @@
|
|
|
136
97
|
"run"
|
|
137
98
|
],
|
|
138
99
|
"scriptPath": "scripts/play.ts"
|
|
139
|
-
}
|
|
140
|
-
"fontSize": 15,
|
|
141
|
-
"borderColor": "green",
|
|
142
|
-
"borderSize": 1
|
|
100
|
+
}
|
|
143
101
|
}
|
|
144
102
|
},
|
|
145
103
|
{
|
|
146
104
|
"id": "payment-service",
|
|
147
105
|
"type": "stateNode",
|
|
148
|
-
"position": {
|
|
149
|
-
"x": 1340,
|
|
150
|
-
"y": 349
|
|
151
|
-
},
|
|
152
106
|
"data": {
|
|
153
107
|
"name": "Payment Service",
|
|
154
108
|
"kind": "worker",
|
|
@@ -156,19 +110,12 @@
|
|
|
156
110
|
"kind": "event"
|
|
157
111
|
},
|
|
158
112
|
"description": "Stripe + PayPal gateway integration.",
|
|
159
|
-
"detail": "
|
|
160
|
-
"fontSize": 15,
|
|
161
|
-
"borderColor": "green",
|
|
162
|
-
"borderSize": 1
|
|
113
|
+
"detail": "file://details/payment-service.md"
|
|
163
114
|
}
|
|
164
115
|
},
|
|
165
116
|
{
|
|
166
117
|
"id": "notification-service",
|
|
167
118
|
"type": "stateNode",
|
|
168
|
-
"position": {
|
|
169
|
-
"x": 1680,
|
|
170
|
-
"y": 339
|
|
171
|
-
},
|
|
172
119
|
"data": {
|
|
173
120
|
"name": "Notification Service",
|
|
174
121
|
"kind": "worker",
|
|
@@ -176,26 +123,16 @@
|
|
|
176
123
|
"kind": "event"
|
|
177
124
|
},
|
|
178
125
|
"description": "Email + SMS + push via AWS SES / SNS.",
|
|
179
|
-
"detail": "
|
|
180
|
-
"fontSize": 15,
|
|
181
|
-
"borderColor": "green",
|
|
182
|
-
"borderSize": 1
|
|
126
|
+
"detail": "file://details/notification-service.md"
|
|
183
127
|
}
|
|
184
128
|
},
|
|
185
129
|
{
|
|
186
130
|
"id": "postgresql",
|
|
187
131
|
"type": "shapeNode",
|
|
188
|
-
"position": {
|
|
189
|
-
"x": 1720,
|
|
190
|
-
"y": 507
|
|
191
|
-
},
|
|
192
132
|
"data": {
|
|
193
133
|
"shape": "database",
|
|
194
134
|
"name": "PostgreSQL",
|
|
195
|
-
"description": "Orders, users, products
|
|
196
|
-
"fontSize": 15,
|
|
197
|
-
"borderColor": "green",
|
|
198
|
-
"borderSize": 1
|
|
135
|
+
"description": "Orders, users, products \u2014 primary OLTP store"
|
|
199
136
|
}
|
|
200
137
|
}
|
|
201
138
|
],
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## API Gateway
|
|
2
|
+
|
|
3
|
+
Central ingress for every client.
|
|
4
|
+
|
|
5
|
+
- JWT validation before forwarding
|
|
6
|
+
- Token-bucket rate limiting per user and IP
|
|
7
|
+
- Path-based routing to downstream services
|
|
8
|
+
- OpenTelemetry spans for every request
|
|
9
|
+
|
|
10
|
+
### Routes
|
|
11
|
+
- `POST /auth/*` → Auth Service
|
|
12
|
+
- `GET /products/*` → Product Catalog
|
|
13
|
+
- `POST /cart/*` → Cart Service
|
|
14
|
+
- `POST /orders` → Order Service
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Cart Service
|
|
2
|
+
|
|
3
|
+
Per-user cart stored in Redis.
|
|
4
|
+
|
|
5
|
+
- `addItem(sku, qty)` — validates stock, adds line item
|
|
6
|
+
- `applyCoupon(code)` — validates and applies discount
|
|
7
|
+
- `checkout()` — freezes cart, emits `cart.checkout`
|
|
8
|
+
|
|
9
|
+
### Events Emitted
|
|
10
|
+
- `cart.checkout` → Order Service
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Notification Service
|
|
2
|
+
|
|
3
|
+
Delivers transactional messages.
|
|
4
|
+
|
|
5
|
+
### Channels
|
|
6
|
+
- **Email** — AWS SES with DKIM/DMARC
|
|
7
|
+
- **SMS** — Twilio for OTP and shipping alerts
|
|
8
|
+
- **Push** — Firebase Cloud Messaging
|
|
9
|
+
|
|
10
|
+
### Triggered by
|
|
11
|
+
- `payment.captured` — order confirmation
|
|
12
|
+
- `payment.failed` — retry prompt
|
|
13
|
+
- `order.cancelled` — refund notification
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Order Service
|
|
2
|
+
|
|
3
|
+
Owns the order record and drives the downstream pipeline.
|
|
4
|
+
|
|
5
|
+
### State Machine
|
|
6
|
+
```
|
|
7
|
+
pending → confirmed → processing → shipped → delivered
|
|
8
|
+
↘ cancelled
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Triggered by
|
|
12
|
+
- `cart.checkout` event
|
|
13
|
+
|
|
14
|
+
### Events Emitted
|
|
15
|
+
- `order.created` → Payment Service
|
|
16
|
+
- `order.cancelled` → Notification Service
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Payment Service
|
|
2
|
+
|
|
3
|
+
Charges the customer and records the transaction.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `order.created`
|
|
7
|
+
|
|
8
|
+
### Steps
|
|
9
|
+
1. Retrieve saved payment method
|
|
10
|
+
2. Authorise charge via Stripe
|
|
11
|
+
3. Capture funds
|
|
12
|
+
4. Persist charge record
|
|
13
|
+
|
|
14
|
+
### Events Emitted
|
|
15
|
+
- `payment.captured` → Notification Service
|
|
16
|
+
- `payment.failed` → Notification Service
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Product Catalog
|
|
2
|
+
|
|
3
|
+
Single source of truth for products and search.
|
|
4
|
+
|
|
5
|
+
- Products, variants, tiered pricing (B2B / B2C / promo)
|
|
6
|
+
- Elasticsearch full-text search with BM25 ranking
|
|
7
|
+
- Faceted filtering (brand, price, rating, availability)
|
|
8
|
+
|
|
9
|
+
### Events
|
|
10
|
+
- `product.updated` → re-indexes search
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodes": {
|
|
3
|
+
"client": {
|
|
4
|
+
"position": {
|
|
5
|
+
"x": 80,
|
|
6
|
+
"y": 215.5
|
|
7
|
+
},
|
|
8
|
+
"fontSize": 15,
|
|
9
|
+
"borderColor": "green",
|
|
10
|
+
"borderSize": 1
|
|
11
|
+
},
|
|
12
|
+
"api-gateway": {
|
|
13
|
+
"position": {
|
|
14
|
+
"x": 320,
|
|
15
|
+
"y": 227
|
|
16
|
+
},
|
|
17
|
+
"fontSize": 15,
|
|
18
|
+
"borderColor": "green",
|
|
19
|
+
"borderSize": 1
|
|
20
|
+
},
|
|
21
|
+
"auth-service": {
|
|
22
|
+
"position": {
|
|
23
|
+
"x": 660,
|
|
24
|
+
"y": 50
|
|
25
|
+
},
|
|
26
|
+
"fontSize": 15,
|
|
27
|
+
"borderColor": "green",
|
|
28
|
+
"borderSize": 1
|
|
29
|
+
},
|
|
30
|
+
"product-service": {
|
|
31
|
+
"position": {
|
|
32
|
+
"x": 660,
|
|
33
|
+
"y": 218
|
|
34
|
+
},
|
|
35
|
+
"fontSize": 15,
|
|
36
|
+
"borderColor": "green",
|
|
37
|
+
"borderSize": 1
|
|
38
|
+
},
|
|
39
|
+
"cart-service": {
|
|
40
|
+
"position": {
|
|
41
|
+
"x": 660,
|
|
42
|
+
"y": 413
|
|
43
|
+
},
|
|
44
|
+
"fontSize": 15,
|
|
45
|
+
"borderColor": "green",
|
|
46
|
+
"borderSize": 1
|
|
47
|
+
},
|
|
48
|
+
"order-service": {
|
|
49
|
+
"position": {
|
|
50
|
+
"x": 1000,
|
|
51
|
+
"y": 413
|
|
52
|
+
},
|
|
53
|
+
"fontSize": 15,
|
|
54
|
+
"borderColor": "green",
|
|
55
|
+
"borderSize": 1
|
|
56
|
+
},
|
|
57
|
+
"payment-service": {
|
|
58
|
+
"position": {
|
|
59
|
+
"x": 1340,
|
|
60
|
+
"y": 349
|
|
61
|
+
},
|
|
62
|
+
"fontSize": 15,
|
|
63
|
+
"borderColor": "green",
|
|
64
|
+
"borderSize": 1
|
|
65
|
+
},
|
|
66
|
+
"notification-service": {
|
|
67
|
+
"position": {
|
|
68
|
+
"x": 1680,
|
|
69
|
+
"y": 339
|
|
70
|
+
},
|
|
71
|
+
"fontSize": 15,
|
|
72
|
+
"borderColor": "green",
|
|
73
|
+
"borderSize": 1
|
|
74
|
+
},
|
|
75
|
+
"postgresql": {
|
|
76
|
+
"position": {
|
|
77
|
+
"x": 1720,
|
|
78
|
+
"y": 507
|
|
79
|
+
},
|
|
80
|
+
"fontSize": 15,
|
|
81
|
+
"borderColor": "green",
|
|
82
|
+
"borderSize": 1
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"name": "Order Pipeline",
|
|
4
|
+
"nodes": [
|
|
5
|
+
{
|
|
6
|
+
"id": "post-orders",
|
|
7
|
+
"type": "playNode",
|
|
8
|
+
"data": {
|
|
9
|
+
"name": "POST /orders",
|
|
10
|
+
"kind": "service",
|
|
11
|
+
"stateSource": {
|
|
12
|
+
"kind": "request"
|
|
13
|
+
},
|
|
14
|
+
"description": "Creates order, kicks off the pipeline.",
|
|
15
|
+
"detail": "file://details/post-orders.md",
|
|
16
|
+
"playAction": {
|
|
17
|
+
"kind": "script",
|
|
18
|
+
"interpreter": "bun",
|
|
19
|
+
"args": [
|
|
20
|
+
"run"
|
|
21
|
+
],
|
|
22
|
+
"scriptPath": "scripts/play.ts"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "inventory-service",
|
|
28
|
+
"type": "stateNode",
|
|
29
|
+
"data": {
|
|
30
|
+
"name": "Inventory Service",
|
|
31
|
+
"kind": "worker",
|
|
32
|
+
"stateSource": {
|
|
33
|
+
"kind": "event"
|
|
34
|
+
},
|
|
35
|
+
"description": "Reserves stock.",
|
|
36
|
+
"detail": "file://details/inventory-service.md",
|
|
37
|
+
"icon": "a-arrow-down-icon"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "payment-service",
|
|
42
|
+
"type": "stateNode",
|
|
43
|
+
"data": {
|
|
44
|
+
"name": "Payment Service",
|
|
45
|
+
"kind": "worker",
|
|
46
|
+
"stateSource": {
|
|
47
|
+
"kind": "event"
|
|
48
|
+
},
|
|
49
|
+
"description": "Charges card.",
|
|
50
|
+
"detail": "file://details/payment-service.md"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "fulfillment-service",
|
|
55
|
+
"type": "stateNode",
|
|
56
|
+
"data": {
|
|
57
|
+
"name": "Fulfillment Service",
|
|
58
|
+
"kind": "worker",
|
|
59
|
+
"stateSource": {
|
|
60
|
+
"kind": "event"
|
|
61
|
+
},
|
|
62
|
+
"description": "Enqueues shipment.",
|
|
63
|
+
"detail": "file://details/fulfillment-service.md"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"connectors": [
|
|
68
|
+
{
|
|
69
|
+
"id": "c1",
|
|
70
|
+
"source": "post-orders",
|
|
71
|
+
"target": "inventory-service",
|
|
72
|
+
"kind": "event",
|
|
73
|
+
"eventName": "order.created",
|
|
74
|
+
"label": "order.created"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "c2",
|
|
78
|
+
"source": "inventory-service",
|
|
79
|
+
"target": "payment-service",
|
|
80
|
+
"kind": "event",
|
|
81
|
+
"eventName": "stock.reserved",
|
|
82
|
+
"label": "stock.reserved"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "c3",
|
|
86
|
+
"source": "payment-service",
|
|
87
|
+
"target": "fulfillment-service",
|
|
88
|
+
"kind": "event",
|
|
89
|
+
"eventName": "payment.captured",
|
|
90
|
+
"label": "payment.captured"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Fulfillment Service
|
|
2
|
+
|
|
3
|
+
Listens for `payment.captured` and enqueues a shipment job for the warehouse to pick, pack, and dispatch the order. Assigns a tracking ID and notifies the customer.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `payment.captured`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Convert the stock reservation into a pick list
|
|
10
|
+
2. Assign a carrier and service level
|
|
11
|
+
3. Generate a shipment ID and tracking number
|
|
12
|
+
4. Push the job to the warehouse queue
|
|
13
|
+
5. Send dispatch confirmation to the customer
|
|
14
|
+
|
|
15
|
+
### Payload
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"shipmentId": "shp_1234567890",
|
|
19
|
+
"orderId": "ord_1234567890"
|
|
20
|
+
}
|
|
21
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Inventory Service
|
|
2
|
+
|
|
3
|
+
Listens for `order.created` and attempts to reserve the requested stock in the warehouse. Checks available quantity, places a hold on the items, and records the warehouse location.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `order.created`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Look up each SKU in the warehouse
|
|
10
|
+
2. Verify sufficient quantity is available
|
|
11
|
+
3. Place a reservation hold
|
|
12
|
+
4. Record the fulfilling warehouse ID
|
|
13
|
+
|
|
14
|
+
### Emits
|
|
15
|
+
- `stock.reserved` → Payment Service
|
|
16
|
+
|
|
17
|
+
### Payload
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"reserved": true,
|
|
21
|
+
"warehouseId": "wh_sydney"
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Payment Service
|
|
2
|
+
|
|
3
|
+
Listens for `stock.reserved` and charges the customer's card on file. Integrates with the payment gateway to authorise and capture funds for the order total.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `stock.reserved`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Retrieve customer's saved payment method
|
|
10
|
+
2. Calculate order total (items + tax + shipping)
|
|
11
|
+
3. Authorise charge with payment gateway
|
|
12
|
+
4. Capture funds and record the charge ID
|
|
13
|
+
|
|
14
|
+
### Emits
|
|
15
|
+
- `payment.captured` → Fulfillment Service
|
|
16
|
+
|
|
17
|
+
### Payload
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"chargeId": "ch_1234567890",
|
|
21
|
+
"amount": 4999
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## POST /orders
|
|
2
|
+
|
|
3
|
+
Entry point for the order pipeline. Accepts a customer ID and list of line items, creates an order record, and publishes the `order.created` event to kick off downstream processing.
|
|
4
|
+
|
|
5
|
+
### Request
|
|
6
|
+
```json
|
|
7
|
+
{
|
|
8
|
+
"customerId": "cust_123",
|
|
9
|
+
"items": [{ "sku": "WIDGET-1", "qty": 2 }]
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Response
|
|
14
|
+
```json
|
|
15
|
+
{ "orderId": "ord_1234567890" }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Emits
|
|
19
|
+
- `order.created` → Inventory Service
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const flowId = process.env.SEEFLOW_DEMO_ID ?? '';
|
|
2
2
|
const runId = process.env.SEEFLOW_RUN_ID ?? '';
|
|
3
3
|
const studioUrl = (process.env.SEEFLOW_STUDIO_URL ?? 'http://localhost:4321').replace(/\/+$/, '');
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ const res = await fetch(`${studioUrl}/demo/orders`, {
|
|
|
6
6
|
method: 'POST',
|
|
7
7
|
headers: {
|
|
8
8
|
'content-type': 'application/json',
|
|
9
|
-
'x-seeflow-demo-id':
|
|
9
|
+
'x-seeflow-demo-id': flowId,
|
|
10
10
|
'x-seeflow-run-id': runId,
|
|
11
11
|
},
|
|
12
12
|
body: JSON.stringify({ customerId: 'cust_123', items: [{ sku: 'WIDGET-1', qty: 2 }] }),
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodes": {
|
|
3
|
+
"post-orders": {
|
|
4
|
+
"position": {
|
|
5
|
+
"x": -181.96549037838943,
|
|
6
|
+
"y": 138.95644990042385
|
|
7
|
+
},
|
|
8
|
+
"fontSize": 15,
|
|
9
|
+
"borderColor": "green",
|
|
10
|
+
"borderSize": 1
|
|
11
|
+
},
|
|
12
|
+
"inventory-service": {
|
|
13
|
+
"position": {
|
|
14
|
+
"x": 66.21484197841792,
|
|
15
|
+
"y": -126.31035925520507
|
|
16
|
+
},
|
|
17
|
+
"width": 201,
|
|
18
|
+
"height": 118,
|
|
19
|
+
"fontSize": 15,
|
|
20
|
+
"borderColor": "green",
|
|
21
|
+
"borderSize": 1
|
|
22
|
+
},
|
|
23
|
+
"payment-service": {
|
|
24
|
+
"position": {
|
|
25
|
+
"x": 469.1422114437386,
|
|
26
|
+
"y": 206.48855752663212
|
|
27
|
+
},
|
|
28
|
+
"borderSize": 1,
|
|
29
|
+
"fontSize": 15,
|
|
30
|
+
"borderColor": "green"
|
|
31
|
+
},
|
|
32
|
+
"fulfillment-service": {
|
|
33
|
+
"position": {
|
|
34
|
+
"x": 747.51321046746,
|
|
35
|
+
"y": -37.78865629343234
|
|
36
|
+
},
|
|
37
|
+
"fontSize": 15,
|
|
38
|
+
"borderColor": "green",
|
|
39
|
+
"borderSize": 1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
package/package.json
CHANGED