@tbox.cn/app-contracts-mall 0.1.0 → 0.2.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/dist/assembly.d.ts +29 -0
- package/dist/deployment.d.ts +43 -0
- package/dist/guard.d.ts +50 -0
- package/dist/index.d.ts +10 -2
- package/dist/member/cards.d.ts +517 -0
- package/dist/runtime.d.ts +11 -0
- package/dist/runtime.js +457 -0
- package/dist/scope.d.ts +49 -0
- package/dist/services/member.d.ts +101 -9
- package/dist/shopping-guide/cards.d.ts +4201 -0
- package/dist/shopping-guide/ports.d.ts +216 -0
- package/package.json +7 -8
- package/src/domain/coupon.ts +0 -8
- package/src/domain/discount.ts +0 -6
- package/src/domain/parking.ts +0 -13
- package/src/domain/points.ts +0 -14
- package/src/events/index.ts +0 -10
- package/src/index.ts +0 -13
- package/src/services/member.ts +0 -21
- package/src/services/parking.ts +0 -16
- package/src/services/promotion.ts +0 -6
- package/tsconfig.build.json +0 -15
- package/tsconfig.json +0 -5
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
// src/scope.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var MALL_SCOPE_KEY = "mall";
|
|
4
|
+
var mallScopeSchema = z.object({
|
|
5
|
+
miniAppId: z.string().min(1),
|
|
6
|
+
mallId: z.string().min(1),
|
|
7
|
+
subjectId: z.string().optional()
|
|
8
|
+
});
|
|
9
|
+
function parseMallScope(attributes) {
|
|
10
|
+
const raw = attributes?.[MALL_SCOPE_KEY];
|
|
11
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
12
|
+
const result = mallScopeSchema.safeParse(raw);
|
|
13
|
+
return result.success ? result.data : void 0;
|
|
14
|
+
}
|
|
15
|
+
function extractMallScope(ctx) {
|
|
16
|
+
return parseMallScope(ctx.attributes);
|
|
17
|
+
}
|
|
18
|
+
function requireMallScope(ctx) {
|
|
19
|
+
return ctx.attributes[MALL_SCOPE_KEY];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/assembly.ts
|
|
23
|
+
function createMallRuntimeAssembly(controlPlane) {
|
|
24
|
+
const mallIds = new Set(controlPlane.malls.map((m) => m.mallId));
|
|
25
|
+
return {
|
|
26
|
+
extractScopeKey(ctx) {
|
|
27
|
+
const scope = extractMallScope(ctx);
|
|
28
|
+
if (!scope) throw new Error("Mall scope is required");
|
|
29
|
+
return scope.mallId;
|
|
30
|
+
},
|
|
31
|
+
validateScope(attributes) {
|
|
32
|
+
const scope = parseMallScope(attributes);
|
|
33
|
+
return scope !== void 0 && mallIds.has(scope.mallId);
|
|
34
|
+
},
|
|
35
|
+
buildScope(attributes) {
|
|
36
|
+
const scope = parseMallScope(attributes);
|
|
37
|
+
if (!scope) return {};
|
|
38
|
+
return { miniAppId: scope.miniAppId, mallId: scope.mallId };
|
|
39
|
+
},
|
|
40
|
+
extractMallScope,
|
|
41
|
+
requireMallScope,
|
|
42
|
+
controlPlane
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/guard.ts
|
|
47
|
+
import { z as z2 } from "zod";
|
|
48
|
+
var mallLocationSchema = z2.object({
|
|
49
|
+
latitude: z2.string().min(1),
|
|
50
|
+
longitude: z2.string().min(1),
|
|
51
|
+
mallId: z2.string().optional(),
|
|
52
|
+
name: z2.string().optional()
|
|
53
|
+
});
|
|
54
|
+
function parseMallLocation(raw) {
|
|
55
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
56
|
+
const result = mallLocationSchema.safeParse(raw);
|
|
57
|
+
return result.success ? result.data : void 0;
|
|
58
|
+
}
|
|
59
|
+
var mallUserRefSchema = z2.object({
|
|
60
|
+
userId: z2.string().min(1),
|
|
61
|
+
subjectId: z2.string().optional()
|
|
62
|
+
});
|
|
63
|
+
function parseMallUserRef(raw) {
|
|
64
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
65
|
+
const result = mallUserRefSchema.safeParse(raw);
|
|
66
|
+
return result.success ? result.data : void 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/shopping-guide/cards.ts
|
|
70
|
+
import { z as z3 } from "zod";
|
|
71
|
+
var httpsUrlSchema = z3.string().regex(/^https:\/\//).max(2048);
|
|
72
|
+
var isoDateTimeSchema = z3.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/);
|
|
73
|
+
var moneySchema = z3.object({
|
|
74
|
+
currency: z3.literal("CNY"),
|
|
75
|
+
amountMinor: z3.number().int().min(0),
|
|
76
|
+
display: z3.string().min(1)
|
|
77
|
+
});
|
|
78
|
+
var priceSummarySchema = z3.object({
|
|
79
|
+
sale: moneySchema.optional(),
|
|
80
|
+
original: moneySchema.optional(),
|
|
81
|
+
promotion: moneySchema.optional()
|
|
82
|
+
});
|
|
83
|
+
var evidenceSchema = z3.object({
|
|
84
|
+
code: z3.string().min(1),
|
|
85
|
+
label: z3.string().min(1),
|
|
86
|
+
value: z3.string().optional(),
|
|
87
|
+
observedAt: isoDateTimeSchema,
|
|
88
|
+
expiresAt: isoDateTimeSchema.optional(),
|
|
89
|
+
sourceKind: z3.enum(["catalog", "merchant", "mall", "policy"])
|
|
90
|
+
});
|
|
91
|
+
var reasonItemSchema = z3.object({ code: z3.string().min(1), label: z3.string().min(1) });
|
|
92
|
+
var merchantLocationSchema = z3.object({
|
|
93
|
+
buildingName: z3.string().optional(),
|
|
94
|
+
floorName: z3.string().optional(),
|
|
95
|
+
unitName: z3.string().optional(),
|
|
96
|
+
displayText: z3.string().min(1),
|
|
97
|
+
poiId: z3.string().optional()
|
|
98
|
+
});
|
|
99
|
+
var merchantStatusSchema = z3.object({
|
|
100
|
+
code: z3.enum(["enabled", "disabled", "unknown"]),
|
|
101
|
+
label: z3.string().min(1),
|
|
102
|
+
observedAt: isoDateTimeSchema
|
|
103
|
+
});
|
|
104
|
+
var pageInfoSchema = z3.object({
|
|
105
|
+
page: z3.number().int().min(1),
|
|
106
|
+
pageSize: z3.number().int().min(1).max(100),
|
|
107
|
+
total: z3.number().int().min(0),
|
|
108
|
+
hasMore: z3.boolean()
|
|
109
|
+
});
|
|
110
|
+
var refinementSchema = z3.object({ label: z3.string().min(1), queryText: z3.string().min(1) });
|
|
111
|
+
var actionDraftSchema = z3.object({
|
|
112
|
+
actionId: z3.string().min(1),
|
|
113
|
+
label: z3.string().min(1),
|
|
114
|
+
input: z3.record(z3.string(), z3.unknown()).optional()
|
|
115
|
+
});
|
|
116
|
+
var productListCardDataSchema = z3.object({
|
|
117
|
+
context: z3.enum(["recommendation", "search", "similar", "history"]),
|
|
118
|
+
summary: z3.string().optional(),
|
|
119
|
+
items: z3.array(
|
|
120
|
+
z3.object({
|
|
121
|
+
productId: z3.string().min(1),
|
|
122
|
+
name: z3.string().min(1),
|
|
123
|
+
imageUrl: httpsUrlSchema.optional(),
|
|
124
|
+
brand: z3.string().optional(),
|
|
125
|
+
categoryPath: z3.array(z3.string()),
|
|
126
|
+
price: priceSummarySchema,
|
|
127
|
+
availability: z3.object({
|
|
128
|
+
status: z3.enum(["in_stock", "out_of_stock", "limited", "unknown"]),
|
|
129
|
+
label: z3.string(),
|
|
130
|
+
marketable: z3.boolean(),
|
|
131
|
+
observedAt: isoDateTimeSchema
|
|
132
|
+
}),
|
|
133
|
+
merchant: z3.object({
|
|
134
|
+
merchantId: z3.string(),
|
|
135
|
+
name: z3.string(),
|
|
136
|
+
location: merchantLocationSchema.optional()
|
|
137
|
+
}),
|
|
138
|
+
badges: z3.array(z3.string()),
|
|
139
|
+
reasons: z3.array(reasonItemSchema).optional(),
|
|
140
|
+
evidence: z3.array(evidenceSchema).optional(),
|
|
141
|
+
caveats: z3.array(z3.string()),
|
|
142
|
+
itemActions: z3.array(actionDraftSchema)
|
|
143
|
+
})
|
|
144
|
+
),
|
|
145
|
+
noResultsReason: z3.string().optional(),
|
|
146
|
+
pageInfo: pageInfoSchema.optional(),
|
|
147
|
+
refinements: z3.array(refinementSchema)
|
|
148
|
+
});
|
|
149
|
+
var merchantListCardDataSchema = z3.object({
|
|
150
|
+
context: z3.enum(["recommendation", "search"]),
|
|
151
|
+
summary: z3.string().optional(),
|
|
152
|
+
items: z3.array(
|
|
153
|
+
z3.object({
|
|
154
|
+
merchantId: z3.string(),
|
|
155
|
+
name: z3.string(),
|
|
156
|
+
logoUrl: httpsUrlSchema.optional(),
|
|
157
|
+
coverUrl: httpsUrlSchema.optional(),
|
|
158
|
+
brand: z3.string().optional(),
|
|
159
|
+
businessCategories: z3.array(z3.string()),
|
|
160
|
+
location: merchantLocationSchema,
|
|
161
|
+
status: merchantStatusSchema,
|
|
162
|
+
services: z3.array(z3.string()),
|
|
163
|
+
promotionFacts: z3.array(z3.string()),
|
|
164
|
+
reasons: z3.array(reasonItemSchema).optional(),
|
|
165
|
+
evidence: z3.array(evidenceSchema).optional(),
|
|
166
|
+
itemActions: z3.array(actionDraftSchema)
|
|
167
|
+
})
|
|
168
|
+
),
|
|
169
|
+
noResultsReason: z3.string().optional(),
|
|
170
|
+
pageInfo: pageInfoSchema.optional(),
|
|
171
|
+
refinements: z3.array(refinementSchema)
|
|
172
|
+
});
|
|
173
|
+
var productDetailCardDataSchema = z3.object({
|
|
174
|
+
productId: z3.string().min(1),
|
|
175
|
+
name: z3.string().min(1),
|
|
176
|
+
description: z3.string().optional(),
|
|
177
|
+
imageUrls: z3.array(httpsUrlSchema),
|
|
178
|
+
brand: z3.string().optional(),
|
|
179
|
+
categoryPath: z3.array(z3.string()),
|
|
180
|
+
price: priceSummarySchema,
|
|
181
|
+
availability: z3.object({
|
|
182
|
+
status: z3.enum(["in_stock", "out_of_stock", "limited", "unknown"]),
|
|
183
|
+
label: z3.string(),
|
|
184
|
+
marketable: z3.boolean(),
|
|
185
|
+
observedAt: isoDateTimeSchema
|
|
186
|
+
}),
|
|
187
|
+
merchant: z3.object({
|
|
188
|
+
merchantId: z3.string(),
|
|
189
|
+
name: z3.string(),
|
|
190
|
+
location: merchantLocationSchema.optional()
|
|
191
|
+
}),
|
|
192
|
+
attributes: z3.array(z3.object({ name: z3.string(), value: z3.string() })),
|
|
193
|
+
promotionFacts: z3.array(z3.string()),
|
|
194
|
+
evidence: z3.array(evidenceSchema),
|
|
195
|
+
humanGuideAvailable: z3.boolean(),
|
|
196
|
+
itemActions: z3.array(actionDraftSchema)
|
|
197
|
+
});
|
|
198
|
+
var merchantDetailCardDataSchema = z3.object({
|
|
199
|
+
merchantId: z3.string(),
|
|
200
|
+
name: z3.string(),
|
|
201
|
+
logoUrl: httpsUrlSchema.optional(),
|
|
202
|
+
coverUrls: z3.array(httpsUrlSchema),
|
|
203
|
+
brand: z3.string().optional(),
|
|
204
|
+
businessCategories: z3.array(z3.string()),
|
|
205
|
+
location: merchantLocationSchema,
|
|
206
|
+
status: merchantStatusSchema,
|
|
207
|
+
description: z3.string().optional(),
|
|
208
|
+
contactInfo: z3.array(z3.object({ channel: z3.string(), value: z3.string() })).optional(),
|
|
209
|
+
services: z3.array(z3.string()),
|
|
210
|
+
promotionFacts: z3.array(z3.string()),
|
|
211
|
+
evidence: z3.array(evidenceSchema),
|
|
212
|
+
itemActions: z3.array(actionDraftSchema)
|
|
213
|
+
});
|
|
214
|
+
var categoryListCardDataSchema = z3.object({
|
|
215
|
+
categories: z3.array(
|
|
216
|
+
z3.object({
|
|
217
|
+
code: z3.string().min(1),
|
|
218
|
+
name: z3.string().min(1),
|
|
219
|
+
description: z3.string().optional(),
|
|
220
|
+
merchantCount: z3.number().int().min(0),
|
|
221
|
+
subCategories: z3.array(z3.object({ code: z3.string(), name: z3.string(), merchantCount: z3.number().int().min(0) })).optional()
|
|
222
|
+
})
|
|
223
|
+
),
|
|
224
|
+
observedAt: isoDateTimeSchema
|
|
225
|
+
});
|
|
226
|
+
var productComparisonCardDataSchema = z3.object({
|
|
227
|
+
products: z3.array(
|
|
228
|
+
z3.object({
|
|
229
|
+
productId: z3.string().min(1),
|
|
230
|
+
name: z3.string().min(1),
|
|
231
|
+
imageUrl: httpsUrlSchema.optional(),
|
|
232
|
+
brand: z3.string().optional(),
|
|
233
|
+
price: priceSummarySchema,
|
|
234
|
+
availability: z3.object({
|
|
235
|
+
status: z3.enum(["in_stock", "out_of_stock", "limited", "unknown"]),
|
|
236
|
+
label: z3.string(),
|
|
237
|
+
marketable: z3.boolean(),
|
|
238
|
+
observedAt: isoDateTimeSchema
|
|
239
|
+
}),
|
|
240
|
+
merchant: z3.object({ merchantId: z3.string(), name: z3.string() }),
|
|
241
|
+
attributes: z3.array(z3.object({ name: z3.string(), value: z3.string() })),
|
|
242
|
+
caveats: z3.array(z3.string())
|
|
243
|
+
})
|
|
244
|
+
),
|
|
245
|
+
observedAt: isoDateTimeSchema
|
|
246
|
+
});
|
|
247
|
+
var mallDirectoryCardDataSchema = z3.object({
|
|
248
|
+
mallId: z3.string(),
|
|
249
|
+
mallName: z3.string(),
|
|
250
|
+
buildings: z3.array(
|
|
251
|
+
z3.object({
|
|
252
|
+
buildingCode: z3.string(),
|
|
253
|
+
buildingName: z3.string(),
|
|
254
|
+
floors: z3.array(
|
|
255
|
+
z3.object({
|
|
256
|
+
floorCode: z3.string(),
|
|
257
|
+
floorName: z3.string(),
|
|
258
|
+
businessCategories: z3.array(z3.string()),
|
|
259
|
+
merchantCount: z3.number().int().min(0)
|
|
260
|
+
})
|
|
261
|
+
)
|
|
262
|
+
})
|
|
263
|
+
),
|
|
264
|
+
observedAt: isoDateTimeSchema
|
|
265
|
+
});
|
|
266
|
+
var nearbyMallListCardDataSchema = z3.object({
|
|
267
|
+
query: z3.string().optional(),
|
|
268
|
+
malls: z3.array(
|
|
269
|
+
z3.object({
|
|
270
|
+
mallId: z3.string(),
|
|
271
|
+
name: z3.string(),
|
|
272
|
+
address: z3.string(),
|
|
273
|
+
distanceKm: z3.number().min(0).optional(),
|
|
274
|
+
status: z3.object({ code: z3.enum(["open", "closed", "unknown"]), label: z3.string() }),
|
|
275
|
+
itemActions: z3.array(actionDraftSchema)
|
|
276
|
+
})
|
|
277
|
+
)
|
|
278
|
+
});
|
|
279
|
+
var customerServiceFaqCardDataSchema = z3.object({
|
|
280
|
+
query: z3.string().min(1),
|
|
281
|
+
faqs: z3.array(
|
|
282
|
+
z3.object({
|
|
283
|
+
question: z3.string().min(1),
|
|
284
|
+
answer: z3.string().min(1),
|
|
285
|
+
category: z3.string().optional(),
|
|
286
|
+
relevanceScore: z3.number().min(0).max(1)
|
|
287
|
+
})
|
|
288
|
+
),
|
|
289
|
+
noResultsReason: z3.string().optional()
|
|
290
|
+
});
|
|
291
|
+
var humanGuideListCardDataSchema = z3.object({
|
|
292
|
+
merchantId: z3.string(),
|
|
293
|
+
merchantName: z3.string(),
|
|
294
|
+
guides: z3.array(
|
|
295
|
+
z3.object({
|
|
296
|
+
guideId: z3.string(),
|
|
297
|
+
name: z3.string(),
|
|
298
|
+
title: z3.string().optional(),
|
|
299
|
+
avatarUrl: httpsUrlSchema.optional(),
|
|
300
|
+
contactInfo: z3.array(z3.object({ channel: z3.string(), value: z3.string() })).optional(),
|
|
301
|
+
available: z3.boolean(),
|
|
302
|
+
itemActions: z3.array(actionDraftSchema)
|
|
303
|
+
})
|
|
304
|
+
)
|
|
305
|
+
});
|
|
306
|
+
var locationHandoffCardDataSchema = z3.object({
|
|
307
|
+
merchantId: z3.string(),
|
|
308
|
+
merchantName: z3.string(),
|
|
309
|
+
location: merchantLocationSchema,
|
|
310
|
+
mapUrl: httpsUrlSchema.optional(),
|
|
311
|
+
navigation: z3.object({
|
|
312
|
+
provider: z3.enum(["amap", "builtin"]),
|
|
313
|
+
launchParams: z3.record(z3.string(), z3.string()).optional()
|
|
314
|
+
}).optional(),
|
|
315
|
+
itemActions: z3.array(actionDraftSchema)
|
|
316
|
+
});
|
|
317
|
+
var shoppingGuideCardDataSchemas = {
|
|
318
|
+
"product-list": productListCardDataSchema,
|
|
319
|
+
"product-detail": productDetailCardDataSchema,
|
|
320
|
+
"merchant-list": merchantListCardDataSchema,
|
|
321
|
+
"merchant-detail": merchantDetailCardDataSchema,
|
|
322
|
+
"category-list": categoryListCardDataSchema,
|
|
323
|
+
"product-comparison": productComparisonCardDataSchema,
|
|
324
|
+
"mall-directory": mallDirectoryCardDataSchema,
|
|
325
|
+
"nearby-mall-list": nearbyMallListCardDataSchema,
|
|
326
|
+
"customer-service-faq": customerServiceFaqCardDataSchema,
|
|
327
|
+
"human-guide-list": humanGuideListCardDataSchema,
|
|
328
|
+
"location-handoff": locationHandoffCardDataSchema
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// src/member/cards.ts
|
|
332
|
+
import { z as z4 } from "zod";
|
|
333
|
+
var memberStateSchema = z4.enum(["active", "not_enrolled", "closed"]);
|
|
334
|
+
var memberInfoCardDataSchema = z4.object({
|
|
335
|
+
userId: z4.string().min(1),
|
|
336
|
+
state: memberStateSchema,
|
|
337
|
+
displayName: z4.string().optional(),
|
|
338
|
+
avatarUrl: z4.string().optional(),
|
|
339
|
+
contactDisplay: z4.string().optional(),
|
|
340
|
+
memberRef: z4.string().optional(),
|
|
341
|
+
registeredAt: z4.string().optional(),
|
|
342
|
+
labels: z4.array(z4.object({ labelRef: z4.string(), name: z4.string() }))
|
|
343
|
+
});
|
|
344
|
+
var memberCardSummaryCardDataSchema = z4.object({
|
|
345
|
+
userId: z4.string().min(1),
|
|
346
|
+
cardRef: z4.string(),
|
|
347
|
+
cardDisplay: z4.string(),
|
|
348
|
+
status: z4.enum(["active", "inactive", "frozen", "expired", "unknown"]),
|
|
349
|
+
levelName: z4.string().optional(),
|
|
350
|
+
availablePoints: z4.number().int().min(0),
|
|
351
|
+
cardImageUrl: z4.string().optional()
|
|
352
|
+
});
|
|
353
|
+
var memberCouponListCardDataSchema = z4.object({
|
|
354
|
+
userId: z4.string().min(1),
|
|
355
|
+
items: z4.array(
|
|
356
|
+
z4.object({
|
|
357
|
+
couponRef: z4.string(),
|
|
358
|
+
title: z4.string(),
|
|
359
|
+
type: z4.enum(["amount", "discount", "gift", "parking", "unknown"]),
|
|
360
|
+
status: z4.enum(["effective", "used", "expired", "invalid", "unknown"]),
|
|
361
|
+
benefitText: z4.string().optional(),
|
|
362
|
+
thresholdText: z4.string().optional()
|
|
363
|
+
})
|
|
364
|
+
),
|
|
365
|
+
total: z4.number().int().min(0)
|
|
366
|
+
});
|
|
367
|
+
var memberCouponDetailCardDataSchema = z4.object({
|
|
368
|
+
couponRef: z4.string(),
|
|
369
|
+
title: z4.string(),
|
|
370
|
+
type: z4.enum(["amount", "discount", "gift", "parking", "unknown"]),
|
|
371
|
+
status: z4.enum(["effective", "used", "expired", "invalid", "unknown"]),
|
|
372
|
+
description: z4.string().optional(),
|
|
373
|
+
benefitText: z4.string().optional(),
|
|
374
|
+
thresholdText: z4.string().optional()
|
|
375
|
+
});
|
|
376
|
+
var memberPointUsageListCardDataSchema = z4.object({
|
|
377
|
+
userId: z4.string().min(1),
|
|
378
|
+
balance: z4.number().int(),
|
|
379
|
+
level: z4.enum(["silver", "gold", "platinum"]),
|
|
380
|
+
items: z4.array(
|
|
381
|
+
z4.object({
|
|
382
|
+
usageRecordRef: z4.string(),
|
|
383
|
+
title: z4.string(),
|
|
384
|
+
amount: z4.string(),
|
|
385
|
+
usedAt: z4.string().optional(),
|
|
386
|
+
description: z4.string().optional()
|
|
387
|
+
})
|
|
388
|
+
),
|
|
389
|
+
total: z4.number().int().min(0)
|
|
390
|
+
});
|
|
391
|
+
var memberEnrollmentFormCardDataSchema = z4.object({
|
|
392
|
+
userId: z4.string().min(1),
|
|
393
|
+
state: memberStateSchema,
|
|
394
|
+
/** 表单必填项(渲染端收集后经 componentAction member.enroll 提交) */
|
|
395
|
+
fields: z4.array(z4.object({ fieldId: z4.string(), label: z4.string(), required: z4.boolean() })),
|
|
396
|
+
actionId: z4.string()
|
|
397
|
+
});
|
|
398
|
+
var memberEnrollmentStatusCardDataSchema = z4.object({
|
|
399
|
+
userId: z4.string().min(1),
|
|
400
|
+
success: z4.boolean(),
|
|
401
|
+
memberRef: z4.string().optional(),
|
|
402
|
+
message: z4.string().optional(),
|
|
403
|
+
state: memberStateSchema
|
|
404
|
+
});
|
|
405
|
+
var memberCardDataSchemas = {
|
|
406
|
+
"member-info": memberInfoCardDataSchema,
|
|
407
|
+
"member-card-summary": memberCardSummaryCardDataSchema,
|
|
408
|
+
"member-coupon-list": memberCouponListCardDataSchema,
|
|
409
|
+
"member-coupon-detail": memberCouponDetailCardDataSchema,
|
|
410
|
+
"member-point-usage-list": memberPointUsageListCardDataSchema,
|
|
411
|
+
"member-enrollment-form": memberEnrollmentFormCardDataSchema,
|
|
412
|
+
"member-enrollment-status": memberEnrollmentStatusCardDataSchema
|
|
413
|
+
};
|
|
414
|
+
export {
|
|
415
|
+
MALL_SCOPE_KEY,
|
|
416
|
+
actionDraftSchema,
|
|
417
|
+
categoryListCardDataSchema,
|
|
418
|
+
createMallRuntimeAssembly,
|
|
419
|
+
customerServiceFaqCardDataSchema,
|
|
420
|
+
evidenceSchema,
|
|
421
|
+
extractMallScope,
|
|
422
|
+
httpsUrlSchema,
|
|
423
|
+
humanGuideListCardDataSchema,
|
|
424
|
+
isoDateTimeSchema,
|
|
425
|
+
locationHandoffCardDataSchema,
|
|
426
|
+
mallDirectoryCardDataSchema,
|
|
427
|
+
mallLocationSchema,
|
|
428
|
+
mallScopeSchema,
|
|
429
|
+
mallUserRefSchema,
|
|
430
|
+
memberCardDataSchemas,
|
|
431
|
+
memberCardSummaryCardDataSchema,
|
|
432
|
+
memberCouponDetailCardDataSchema,
|
|
433
|
+
memberCouponListCardDataSchema,
|
|
434
|
+
memberEnrollmentFormCardDataSchema,
|
|
435
|
+
memberEnrollmentStatusCardDataSchema,
|
|
436
|
+
memberInfoCardDataSchema,
|
|
437
|
+
memberPointUsageListCardDataSchema,
|
|
438
|
+
memberStateSchema,
|
|
439
|
+
merchantDetailCardDataSchema,
|
|
440
|
+
merchantListCardDataSchema,
|
|
441
|
+
merchantLocationSchema,
|
|
442
|
+
merchantStatusSchema,
|
|
443
|
+
moneySchema,
|
|
444
|
+
nearbyMallListCardDataSchema,
|
|
445
|
+
pageInfoSchema,
|
|
446
|
+
parseMallLocation,
|
|
447
|
+
parseMallScope,
|
|
448
|
+
parseMallUserRef,
|
|
449
|
+
priceSummarySchema,
|
|
450
|
+
productComparisonCardDataSchema,
|
|
451
|
+
productDetailCardDataSchema,
|
|
452
|
+
productListCardDataSchema,
|
|
453
|
+
reasonItemSchema,
|
|
454
|
+
refinementSchema,
|
|
455
|
+
requireMallScope,
|
|
456
|
+
shoppingGuideCardDataSchemas
|
|
457
|
+
};
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 商圈 scope(011 B2:TIER1 领域语义唯一真源):
|
|
3
|
+
* MallScope 类型 + zod 解析 + RequestContext 提取器。
|
|
4
|
+
*
|
|
5
|
+
* 消费方(模块)只依赖本文件解析 attributes,不解析原始形状(011 B4);
|
|
6
|
+
* TIER0(app-contracts)不出现任何 mall 语义(011 B1)。
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import type { RequestContext } from '@tbox.cn/app-contracts';
|
|
10
|
+
/** attributes 键名(TIER0 槽位内 TIER1 自定键,单一来源) */
|
|
11
|
+
export declare const MALL_SCOPE_KEY = "mall";
|
|
12
|
+
/** 商圈 scope(客户端输入形状——HELLO context.attributes.mall;会话边界键:mallId) */
|
|
13
|
+
export interface MallScope {
|
|
14
|
+
/** 小程序 appId(定位到具体小程序实例) */
|
|
15
|
+
miniAppId: string;
|
|
16
|
+
/** 商圈 id(会话边界:跨 mall 强制新会话,011 F3) */
|
|
17
|
+
mallId: string;
|
|
18
|
+
/** 可选主体 id(会员体系 subject) */
|
|
19
|
+
subjectId?: string;
|
|
20
|
+
}
|
|
21
|
+
/** 011 S7:服务端回显形状(= MallScope + 服务端生成的 sessionId;与输入形状分离) */
|
|
22
|
+
export interface MallSessionScope extends MallScope {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const mallScopeSchema: z.ZodObject<{
|
|
26
|
+
miniAppId: z.ZodString;
|
|
27
|
+
mallId: z.ZodString;
|
|
28
|
+
subjectId: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
miniAppId: string;
|
|
31
|
+
mallId: string;
|
|
32
|
+
subjectId?: string | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
miniAppId: string;
|
|
35
|
+
mallId: string;
|
|
36
|
+
subjectId?: string | undefined;
|
|
37
|
+
}>;
|
|
38
|
+
/** 解析失败返回 undefined(不 throw),模块自行降级(011 B2 语义) */
|
|
39
|
+
export declare function parseMallScope(attributes: Record<string, unknown> | undefined): MallScope | undefined;
|
|
40
|
+
/** 从 RequestContext 提取 MallScope(parseMallScope 包装) */
|
|
41
|
+
export declare function extractMallScope(ctx: RequestContext): MallScope | undefined;
|
|
42
|
+
/** mall 领域运行上下文(attributes 含 mall 的 RequestContext 收窄,模块 handler 入参可用) */
|
|
43
|
+
export type MallRequestContext = RequestContext & {
|
|
44
|
+
attributes: Record<string, unknown> & {
|
|
45
|
+
[MALL_SCOPE_KEY]: MallScope;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/** 从 MallRequestContext 取 MallScope(调用方已确认 scope 存在) */
|
|
49
|
+
export declare function requireMallScope(ctx: MallRequestContext): MallScope;
|
|
@@ -1,19 +1,111 @@
|
|
|
1
1
|
import type { Points } from '../domain/points';
|
|
2
2
|
import type { DiscountRule } from '../domain/discount';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* 结构类型子集接口——模块完整实现 extends
|
|
4
|
+
* 会员域 Port(011 K2:6 Port 替换旧 MemberQueryPort/MemberSettlementPort,breaking 0.2.0)。
|
|
5
|
+
* 结构类型子集接口——模块完整实现 extends 本接口,消费方仅依赖契约包。
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
/** 会员状态(含未入会/关闭) */
|
|
8
|
+
export type MemberState = 'active' | 'not_enrolled' | 'closed';
|
|
9
|
+
export interface MemberAccountSnapshot {
|
|
10
|
+
readonly state: MemberState;
|
|
11
|
+
readonly memberRef?: string;
|
|
12
|
+
readonly primaryMallCardNo?: string;
|
|
13
|
+
readonly registeredAt?: string;
|
|
14
|
+
readonly observedAt: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MemberAccountPort {
|
|
17
|
+
getAccount(userId: string): Promise<MemberAccountSnapshot>;
|
|
18
|
+
}
|
|
19
|
+
export interface MemberProfileSnapshot {
|
|
20
|
+
readonly displayName?: string;
|
|
21
|
+
readonly avatarUrl?: string;
|
|
22
|
+
readonly contactDisplay?: string;
|
|
23
|
+
readonly birthday?: string;
|
|
24
|
+
readonly gender?: 'unknown' | 'unspecified' | 'male' | 'female';
|
|
25
|
+
readonly labels: ReadonlyArray<{
|
|
26
|
+
readonly labelRef: string;
|
|
27
|
+
readonly name: string;
|
|
28
|
+
}>;
|
|
29
|
+
readonly observedAt: string;
|
|
30
|
+
}
|
|
31
|
+
export interface MemberProfilePort {
|
|
32
|
+
getProfile(userId: string): Promise<MemberProfileSnapshot>;
|
|
33
|
+
}
|
|
34
|
+
export interface MemberCardSnapshot {
|
|
35
|
+
readonly cardRef: string;
|
|
36
|
+
readonly cardDisplay: string;
|
|
37
|
+
readonly status: 'active' | 'inactive' | 'frozen' | 'expired' | 'unknown';
|
|
38
|
+
readonly levelName?: string;
|
|
39
|
+
readonly cardImageUrl?: string;
|
|
40
|
+
readonly observedAt: string;
|
|
41
|
+
}
|
|
42
|
+
export interface MemberCardPort {
|
|
43
|
+
getCard(userId: string): Promise<MemberCardSnapshot | null>;
|
|
44
|
+
}
|
|
45
|
+
export interface MemberBenefitsSnapshot {
|
|
46
|
+
readonly availablePoints: number;
|
|
47
|
+
readonly usedPoints?: number;
|
|
48
|
+
readonly expiringPoints?: number;
|
|
49
|
+
readonly levelName?: string;
|
|
50
|
+
readonly observedAt: string;
|
|
51
|
+
}
|
|
52
|
+
export interface MemberBenefitsPort {
|
|
53
|
+
/** 积分查询(替代旧 MemberQueryPort.queryPoints) */
|
|
8
54
|
queryPoints(userId: string): Promise<Points>;
|
|
55
|
+
/** 权益快照 */
|
|
56
|
+
getBenefits(userId: string): Promise<MemberBenefitsSnapshot>;
|
|
57
|
+
/** 积分流水(points 卡数据源) */
|
|
58
|
+
listPointUsage(userId: string, page: number, pageSize: number): Promise<{
|
|
59
|
+
items: ReadonlyArray<PointUsageRecord>;
|
|
60
|
+
total: number;
|
|
61
|
+
}>;
|
|
62
|
+
/** 折扣查询(替代旧 MemberQueryPort.queryDiscount) */
|
|
9
63
|
queryDiscount(userId: string): Promise<DiscountRule | undefined>;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* MemberSettlementPort:跨模块写操作(scenario 编排 + 补偿用)。
|
|
13
|
-
* 幂等键由调用方(scenario handler)生成。
|
|
14
|
-
*/
|
|
15
|
-
export interface MemberSettlementPort {
|
|
64
|
+
/** 结算写(替代旧 MemberSettlementPort;幂等键由调用方生成) */
|
|
16
65
|
deductPoints(userId: string, amount: number, idempotencyKey: string): Promise<boolean>;
|
|
17
66
|
refundPoints(userId: string, amount: number, idempotencyKey: string): Promise<boolean>;
|
|
18
67
|
awardPoints(userId: string, amount: number): Promise<boolean>;
|
|
19
68
|
}
|
|
69
|
+
export interface PointUsageRecord {
|
|
70
|
+
readonly usageRecordRef: string;
|
|
71
|
+
readonly title: string;
|
|
72
|
+
/** 字符串化金额(D11 展示层统一字符串) */
|
|
73
|
+
readonly amount: string;
|
|
74
|
+
readonly usedAt?: string;
|
|
75
|
+
readonly description?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface MemberCouponSnapshot {
|
|
78
|
+
readonly couponRef: string;
|
|
79
|
+
readonly title: string;
|
|
80
|
+
readonly type: 'amount' | 'discount' | 'gift' | 'parking' | 'unknown';
|
|
81
|
+
readonly status: 'effective' | 'used' | 'expired' | 'invalid' | 'unknown';
|
|
82
|
+
readonly description?: string;
|
|
83
|
+
readonly benefitText?: string;
|
|
84
|
+
readonly thresholdText?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface MemberCouponPort {
|
|
87
|
+
listCoupons(userId: string, page: number, pageSize: number): Promise<{
|
|
88
|
+
items: ReadonlyArray<MemberCouponSnapshot>;
|
|
89
|
+
total: number;
|
|
90
|
+
}>;
|
|
91
|
+
getCoupon(userId: string, couponRef: string): Promise<MemberCouponSnapshot | null>;
|
|
92
|
+
}
|
|
93
|
+
export interface MemberEnrollmentPort {
|
|
94
|
+
/** 入会(授权回调后调用;幂等:已入会返回成功) */
|
|
95
|
+
enroll(input: {
|
|
96
|
+
userId: string;
|
|
97
|
+
name?: string;
|
|
98
|
+
phone?: string;
|
|
99
|
+
}): Promise<{
|
|
100
|
+
success: boolean;
|
|
101
|
+
memberRef?: string;
|
|
102
|
+
error?: string;
|
|
103
|
+
}>;
|
|
104
|
+
/** 授权回调补签(alipay-user-profile 授权结果 → 会员资料落库) */
|
|
105
|
+
completeAuthorization(input: {
|
|
106
|
+
userId: string;
|
|
107
|
+
scopes: readonly string[];
|
|
108
|
+
}): Promise<{
|
|
109
|
+
success: boolean;
|
|
110
|
+
}>;
|
|
111
|
+
}
|