@tbox.cn/app-contracts-mall 0.2.0 → 0.10.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.
Files changed (84) hide show
  1. package/README.md +16 -2
  2. package/dist/alipay-activity/cards.d.ts +305 -0
  3. package/dist/assembly.d.ts +73 -7
  4. package/dist/chunk-KIZD6FZ2.js +43 -0
  5. package/dist/deployment.d.ts +32 -33
  6. package/dist/domain/activity.d.ts +64 -0
  7. package/dist/domain/coupon.d.ts +2 -0
  8. package/dist/domain/entitlement.d.ts +53 -0
  9. package/dist/domain/offer.d.ts +111 -0
  10. package/dist/domain/operation.d.ts +22 -0
  11. package/dist/domain/parking.d.ts +195 -12
  12. package/dist/domain/points.d.ts +3 -2
  13. package/dist/domain/shopping-guide.d.ts +201 -0
  14. package/dist/index.d.ts +15 -2
  15. package/dist/mall-scope-url.d.ts +13 -0
  16. package/dist/member/cards.d.ts +636 -213
  17. package/dist/parking/cards.d.ts +1271 -0
  18. package/dist/promotion/cards.d.ts +2529 -0
  19. package/dist/query-context.d.ts +47 -0
  20. package/dist/runtime.d.ts +12 -2
  21. package/dist/runtime.js +940 -86
  22. package/dist/scope.d.ts +42 -15
  23. package/dist/server/index.d.ts +11 -0
  24. package/dist/server/index.js +92 -0
  25. package/dist/server/mall-context.d.ts +24 -0
  26. package/dist/server/mall-control-plane.d.ts +10 -0
  27. package/dist/server/request-credentials.d.ts +22 -0
  28. package/dist/services/customer-service.d.ts +11 -0
  29. package/dist/services/mall-info.d.ts +39 -0
  30. package/dist/services/member.d.ts +188 -31
  31. package/dist/services/parking.d.ts +115 -11
  32. package/dist/services/promotion.d.ts +100 -4
  33. package/dist/services/shopping-guide.d.ts +97 -0
  34. package/dist/shared/cards.d.ts +42 -0
  35. package/dist/shopping-guide/cards.d.ts +3399 -561
  36. package/package.json +19 -7
  37. package/src/alipay-activity/cards.ts +66 -0
  38. package/src/assembly.ts +159 -0
  39. package/src/deployment.ts +44 -0
  40. package/src/domain/activity.ts +66 -0
  41. package/src/domain/coupon.ts +11 -0
  42. package/src/domain/discount.ts +6 -0
  43. package/src/domain/entitlement.ts +56 -0
  44. package/src/domain/offer.ts +120 -0
  45. package/src/domain/operation.ts +40 -0
  46. package/src/domain/parking.ts +207 -0
  47. package/src/domain/points.ts +15 -0
  48. package/src/domain/shopping-guide.ts +242 -0
  49. package/src/events/index.ts +10 -0
  50. package/src/guard.ts +48 -0
  51. package/src/index.ts +34 -0
  52. package/src/mall-scope-url.ts +21 -0
  53. package/src/member/cards.ts +209 -0
  54. package/src/parking/cards.ts +233 -0
  55. package/src/promotion/cards.ts +290 -0
  56. package/src/query-context.ts +81 -0
  57. package/src/runtime.ts +43 -0
  58. package/src/scope.ts +92 -0
  59. package/src/server/index.ts +11 -0
  60. package/src/server/mall-context.ts +39 -0
  61. package/src/server/mall-control-plane.ts +92 -0
  62. package/src/server/request-credentials.ts +43 -0
  63. package/src/service-slots.json +26 -0
  64. package/src/services/customer-service.ts +12 -0
  65. package/src/services/mall-info.ts +48 -0
  66. package/src/services/member.ts +386 -0
  67. package/src/services/parking.ts +182 -0
  68. package/src/services/promotion.ts +126 -0
  69. package/src/services/shopping-guide.ts +138 -0
  70. package/src/shared/cards.ts +25 -0
  71. package/src/shopping-guide/cards.ts +438 -0
  72. package/tests/assembly-validate-scope.test.ts +132 -0
  73. package/tests/cards.test.ts +586 -0
  74. package/tests/context-unification.test.ts +73 -0
  75. package/tests/mall-control-plane.test.ts +169 -0
  76. package/tests/mall-scope-url.test.ts +59 -0
  77. package/tests/member-status.test.ts +197 -0
  78. package/tests/query-context.test.ts +111 -0
  79. package/tests/request-credentials.test.ts +38 -0
  80. package/tests/resolve-primitives.test.ts +55 -0
  81. package/tests/service-slots.test.ts +83 -0
  82. package/tsconfig.build.json +15 -0
  83. package/tsconfig.json +5 -0
  84. package/dist/shopping-guide/ports.d.ts +0 -216
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @tbox.cn/app-contracts-mall
2
2
 
3
- 商圈领域契约(TIER1,types-only):Port 接口 + MallEventMap + 领域 DTO
3
+ 商圈领域契约与运行时(TIER1):Port 接口 + MallEventMap + 领域 DTO + runtime 装配器 + 签名策略。
4
4
 
5
5
  ## 安装
6
6
 
@@ -8,6 +8,20 @@
8
8
  pnpm add @tbox.cn/app-contracts-mall
9
9
  ```
10
10
 
11
+ 发布包同时提供两种消费形态:直接安装使用 `dist` 编译产物;模板中的 `@app/contracts-mall` shim 默认转发发布包,`tbox-app module add` 自动依赖本包时将其替换为本地源码包。显式使用 `--mode sdk` 时仍保持发布态消费。
12
+
13
+ ## 入口
14
+
15
+ - `@tbox.cn/app-contracts-mall` — 领域类型与 Port(模块消费面)
16
+ - `@tbox.cn/app-contracts-mall/runtime` — runtime:`createMallRuntimeAssembly` 装配器、
17
+ `createInMemoryStateStore`、`createScopeSessionRegistry`、Provider 四件、
18
+ `createActionGrantService` / `createModuleActionDispatcher` / `createEffectRuntime`、
19
+ knowledge/payment client(tsup 出 `dist/runtime.js`)
20
+ - `@tbox.cn/app-contracts-mall/server` — server-only 请求凭证读取助手
21
+ (`request-credentials.ts`:credentialsToken / credentialsMemberId / credentialsOpenId;
22
+ 登录换码器已归 provider 包,见 `@tbox.cn/app-provider-<vendor>/server` 系列)
23
+
11
24
  ## 说明
12
25
 
13
- 商圈业务契约类型真源包;消费方经 `@tbox.cn/app-contracts-mall` 公开入口引用。
26
+ 商圈业务语义唯一真源(MallScope zod 解析 + 领域卡 schema/Port);模块只消费本包,
27
+ 不 import SDK 内部路径。分层判据见仓库 [Provider 与集成参考](../../docs/reference/providers.md)。
@@ -0,0 +1,305 @@
1
+ /**
2
+ * 支付宝「碰出惊喜」互动营销活动卡片数据契约。
3
+ * alipay-activity 专属——与 promotion 通用卡型解耦,独立维护。
4
+ */
5
+ import { z } from 'zod';
6
+ /** 单张优惠券奖品 */
7
+ declare const bumpInVoucherSchema: z.ZodObject<{
8
+ prizeId: z.ZodString;
9
+ voucherName: z.ZodString;
10
+ voucherType: z.ZodString;
11
+ reductionAmount: z.ZodString;
12
+ thresholdAmountText: z.ZodString;
13
+ unit: z.ZodString;
14
+ merchantName: z.ZodString;
15
+ merchantLogo: z.ZodOptional<z.ZodString>;
16
+ itemLogo: z.ZodOptional<z.ZodString>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ merchantName: string;
19
+ prizeId: string;
20
+ voucherName: string;
21
+ voucherType: string;
22
+ reductionAmount: string;
23
+ thresholdAmountText: string;
24
+ unit: string;
25
+ merchantLogo?: string | undefined;
26
+ itemLogo?: string | undefined;
27
+ }, {
28
+ merchantName: string;
29
+ prizeId: string;
30
+ voucherName: string;
31
+ voucherType: string;
32
+ reductionAmount: string;
33
+ thresholdAmountText: string;
34
+ unit: string;
35
+ merchantLogo?: string | undefined;
36
+ itemLogo?: string | undefined;
37
+ }>;
38
+ export type BumpInVoucher = z.infer<typeof bumpInVoucherSchema>;
39
+ /**
40
+ * 碰出惊喜活动生命周期状态(支付宝 IoT NSP 权威枚举):
41
+ * NOT_START 未开始 / INIT 初始化 / PROCESSING 进行中 / FINISH 已完成 / RECEIVED 已领奖。
42
+ * RECEIVED 是用户级终态(奖励已领取),其余为活动级状态。
43
+ */
44
+ export declare const bumpInActStatusSchema: z.ZodEnum<["NOT_START", "INIT", "PROCESSING", "FINISH", "RECEIVED"]>;
45
+ export type BumpInActStatus = z.infer<typeof bumpInActStatusSchema>;
46
+ /** promotion-bumpin-activity:进度 + 奖励池,detail/banner 双模式 */
47
+ export declare const promotionBumpInActivityCardDataSchema: z.ZodObject<{
48
+ activityRef: z.ZodString;
49
+ title: z.ZodString;
50
+ mainTitle: z.ZodOptional<z.ZodString>;
51
+ coverUrl: z.ZodOptional<z.ZodString>;
52
+ /** 联单活动全幅背景图 URL(与 coverUrl 互斥;backgroundUrl 存在时头部采用全幅覆盖布局) */
53
+ backgroundUrl: z.ZodOptional<z.ZodString>;
54
+ /** 左上角活动类型胶囊标签,如"碰一下联单" */
55
+ tagLabel: z.ZodOptional<z.ZodString>;
56
+ cardLogoUrl: z.ZodOptional<z.ZodString>;
57
+ actStatus: z.ZodEnum<["NOT_START", "INIT", "PROCESSING", "FINISH", "RECEIVED"]>;
58
+ totalProgress: z.ZodOptional<z.ZodString>;
59
+ currentProgress: z.ZodOptional<z.ZodString>;
60
+ progressUnit: z.ZodOptional<z.ZodString>;
61
+ startAtText: z.ZodOptional<z.ZodString>;
62
+ endAtText: z.ZodOptional<z.ZodString>;
63
+ description: z.ZodOptional<z.ZodString>;
64
+ vouchers: z.ZodArray<z.ZodObject<{
65
+ prizeId: z.ZodString;
66
+ voucherName: z.ZodString;
67
+ voucherType: z.ZodString;
68
+ reductionAmount: z.ZodString;
69
+ thresholdAmountText: z.ZodString;
70
+ unit: z.ZodString;
71
+ merchantName: z.ZodString;
72
+ merchantLogo: z.ZodOptional<z.ZodString>;
73
+ itemLogo: z.ZodOptional<z.ZodString>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ merchantName: string;
76
+ prizeId: string;
77
+ voucherName: string;
78
+ voucherType: string;
79
+ reductionAmount: string;
80
+ thresholdAmountText: string;
81
+ unit: string;
82
+ merchantLogo?: string | undefined;
83
+ itemLogo?: string | undefined;
84
+ }, {
85
+ merchantName: string;
86
+ prizeId: string;
87
+ voucherName: string;
88
+ voucherType: string;
89
+ reductionAmount: string;
90
+ thresholdAmountText: string;
91
+ unit: string;
92
+ merchantLogo?: string | undefined;
93
+ itemLogo?: string | undefined;
94
+ }>, "many">;
95
+ mode: z.ZodDefault<z.ZodEnum<["detail", "banner"]>>;
96
+ /** bar(线性进度条,默认)| steps(圆形步骤节点,适合联单任务) */
97
+ progressStyle: z.ZodDefault<z.ZodEnum<["bar", "steps"]>>;
98
+ /** 参与步骤(联单活动 guide.steps;banner 模式用于渲染步骤进度节点) */
99
+ steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
100
+ title: z.ZodString;
101
+ description: z.ZodOptional<z.ZodString>;
102
+ }, "strip", z.ZodTypeAny, {
103
+ title: string;
104
+ description?: string | undefined;
105
+ }, {
106
+ title: string;
107
+ description?: string | undefined;
108
+ }>, "many">>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ title: string;
111
+ activityRef: string;
112
+ actStatus: "NOT_START" | "INIT" | "PROCESSING" | "FINISH" | "RECEIVED";
113
+ vouchers: {
114
+ merchantName: string;
115
+ prizeId: string;
116
+ voucherName: string;
117
+ voucherType: string;
118
+ reductionAmount: string;
119
+ thresholdAmountText: string;
120
+ unit: string;
121
+ merchantLogo?: string | undefined;
122
+ itemLogo?: string | undefined;
123
+ }[];
124
+ mode: "detail" | "banner";
125
+ progressStyle: "bar" | "steps";
126
+ description?: string | undefined;
127
+ coverUrl?: string | undefined;
128
+ mainTitle?: string | undefined;
129
+ backgroundUrl?: string | undefined;
130
+ tagLabel?: string | undefined;
131
+ cardLogoUrl?: string | undefined;
132
+ totalProgress?: string | undefined;
133
+ currentProgress?: string | undefined;
134
+ progressUnit?: string | undefined;
135
+ startAtText?: string | undefined;
136
+ endAtText?: string | undefined;
137
+ steps?: {
138
+ title: string;
139
+ description?: string | undefined;
140
+ }[] | undefined;
141
+ }, {
142
+ title: string;
143
+ activityRef: string;
144
+ actStatus: "NOT_START" | "INIT" | "PROCESSING" | "FINISH" | "RECEIVED";
145
+ vouchers: {
146
+ merchantName: string;
147
+ prizeId: string;
148
+ voucherName: string;
149
+ voucherType: string;
150
+ reductionAmount: string;
151
+ thresholdAmountText: string;
152
+ unit: string;
153
+ merchantLogo?: string | undefined;
154
+ itemLogo?: string | undefined;
155
+ }[];
156
+ description?: string | undefined;
157
+ coverUrl?: string | undefined;
158
+ mainTitle?: string | undefined;
159
+ backgroundUrl?: string | undefined;
160
+ tagLabel?: string | undefined;
161
+ cardLogoUrl?: string | undefined;
162
+ totalProgress?: string | undefined;
163
+ currentProgress?: string | undefined;
164
+ progressUnit?: string | undefined;
165
+ startAtText?: string | undefined;
166
+ endAtText?: string | undefined;
167
+ mode?: "detail" | "banner" | undefined;
168
+ steps?: {
169
+ title: string;
170
+ description?: string | undefined;
171
+ }[] | undefined;
172
+ progressStyle?: "bar" | "steps" | undefined;
173
+ }>;
174
+ export type PromotionBumpInActivityCardData = z.infer<typeof promotionBumpInActivityCardDataSchema>;
175
+ export declare const alipayActivityCardDataSchemas: {
176
+ readonly 'promotion-bumpin-activity': z.ZodObject<{
177
+ activityRef: z.ZodString;
178
+ title: z.ZodString;
179
+ mainTitle: z.ZodOptional<z.ZodString>;
180
+ coverUrl: z.ZodOptional<z.ZodString>;
181
+ /** 联单活动全幅背景图 URL(与 coverUrl 互斥;backgroundUrl 存在时头部采用全幅覆盖布局) */
182
+ backgroundUrl: z.ZodOptional<z.ZodString>;
183
+ /** 左上角活动类型胶囊标签,如"碰一下联单" */
184
+ tagLabel: z.ZodOptional<z.ZodString>;
185
+ cardLogoUrl: z.ZodOptional<z.ZodString>;
186
+ actStatus: z.ZodEnum<["NOT_START", "INIT", "PROCESSING", "FINISH", "RECEIVED"]>;
187
+ totalProgress: z.ZodOptional<z.ZodString>;
188
+ currentProgress: z.ZodOptional<z.ZodString>;
189
+ progressUnit: z.ZodOptional<z.ZodString>;
190
+ startAtText: z.ZodOptional<z.ZodString>;
191
+ endAtText: z.ZodOptional<z.ZodString>;
192
+ description: z.ZodOptional<z.ZodString>;
193
+ vouchers: z.ZodArray<z.ZodObject<{
194
+ prizeId: z.ZodString;
195
+ voucherName: z.ZodString;
196
+ voucherType: z.ZodString;
197
+ reductionAmount: z.ZodString;
198
+ thresholdAmountText: z.ZodString;
199
+ unit: z.ZodString;
200
+ merchantName: z.ZodString;
201
+ merchantLogo: z.ZodOptional<z.ZodString>;
202
+ itemLogo: z.ZodOptional<z.ZodString>;
203
+ }, "strip", z.ZodTypeAny, {
204
+ merchantName: string;
205
+ prizeId: string;
206
+ voucherName: string;
207
+ voucherType: string;
208
+ reductionAmount: string;
209
+ thresholdAmountText: string;
210
+ unit: string;
211
+ merchantLogo?: string | undefined;
212
+ itemLogo?: string | undefined;
213
+ }, {
214
+ merchantName: string;
215
+ prizeId: string;
216
+ voucherName: string;
217
+ voucherType: string;
218
+ reductionAmount: string;
219
+ thresholdAmountText: string;
220
+ unit: string;
221
+ merchantLogo?: string | undefined;
222
+ itemLogo?: string | undefined;
223
+ }>, "many">;
224
+ mode: z.ZodDefault<z.ZodEnum<["detail", "banner"]>>;
225
+ /** bar(线性进度条,默认)| steps(圆形步骤节点,适合联单任务) */
226
+ progressStyle: z.ZodDefault<z.ZodEnum<["bar", "steps"]>>;
227
+ /** 参与步骤(联单活动 guide.steps;banner 模式用于渲染步骤进度节点) */
228
+ steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
229
+ title: z.ZodString;
230
+ description: z.ZodOptional<z.ZodString>;
231
+ }, "strip", z.ZodTypeAny, {
232
+ title: string;
233
+ description?: string | undefined;
234
+ }, {
235
+ title: string;
236
+ description?: string | undefined;
237
+ }>, "many">>;
238
+ }, "strip", z.ZodTypeAny, {
239
+ title: string;
240
+ activityRef: string;
241
+ actStatus: "NOT_START" | "INIT" | "PROCESSING" | "FINISH" | "RECEIVED";
242
+ vouchers: {
243
+ merchantName: string;
244
+ prizeId: string;
245
+ voucherName: string;
246
+ voucherType: string;
247
+ reductionAmount: string;
248
+ thresholdAmountText: string;
249
+ unit: string;
250
+ merchantLogo?: string | undefined;
251
+ itemLogo?: string | undefined;
252
+ }[];
253
+ mode: "detail" | "banner";
254
+ progressStyle: "bar" | "steps";
255
+ description?: string | undefined;
256
+ coverUrl?: string | undefined;
257
+ mainTitle?: string | undefined;
258
+ backgroundUrl?: string | undefined;
259
+ tagLabel?: string | undefined;
260
+ cardLogoUrl?: string | undefined;
261
+ totalProgress?: string | undefined;
262
+ currentProgress?: string | undefined;
263
+ progressUnit?: string | undefined;
264
+ startAtText?: string | undefined;
265
+ endAtText?: string | undefined;
266
+ steps?: {
267
+ title: string;
268
+ description?: string | undefined;
269
+ }[] | undefined;
270
+ }, {
271
+ title: string;
272
+ activityRef: string;
273
+ actStatus: "NOT_START" | "INIT" | "PROCESSING" | "FINISH" | "RECEIVED";
274
+ vouchers: {
275
+ merchantName: string;
276
+ prizeId: string;
277
+ voucherName: string;
278
+ voucherType: string;
279
+ reductionAmount: string;
280
+ thresholdAmountText: string;
281
+ unit: string;
282
+ merchantLogo?: string | undefined;
283
+ itemLogo?: string | undefined;
284
+ }[];
285
+ description?: string | undefined;
286
+ coverUrl?: string | undefined;
287
+ mainTitle?: string | undefined;
288
+ backgroundUrl?: string | undefined;
289
+ tagLabel?: string | undefined;
290
+ cardLogoUrl?: string | undefined;
291
+ totalProgress?: string | undefined;
292
+ currentProgress?: string | undefined;
293
+ progressUnit?: string | undefined;
294
+ startAtText?: string | undefined;
295
+ endAtText?: string | undefined;
296
+ mode?: "detail" | "banner" | undefined;
297
+ steps?: {
298
+ title: string;
299
+ description?: string | undefined;
300
+ }[] | undefined;
301
+ progressStyle?: "bar" | "steps" | undefined;
302
+ }>;
303
+ };
304
+ export type AlipayActivityCardType = keyof typeof alipayActivityCardDataSchemas;
305
+ export {};
@@ -4,26 +4,92 @@
4
4
  * SDK 原语(ScopeSessionRegistry/ProviderRegistry)组合在模板装配点完成(011 L1)。
5
5
  *
6
6
  * 不 import app-sdk(依赖方向:contracts-mall → contracts;SDK 不依赖 TIER1)。
7
+ *
8
+ * integrations v4 恒动态:参考表(instances 注册表)纯元数据,永不充当解析闸门——
9
+ * 白名单/动态判定(dynamicMalls/mallIdAllowed)退役。任意合法拓扑形态(注册表缺席/非空)
10
+ * 均支持动态 mallId 会话;实例集限制是 provider 业务限制的表达位(槽 instances 激活表
11
+ * 显式键集 → 数据面 INSTANCE_NOT_FOUND),非框架限制。WS/HTTP 两形态共享单一形状守卫核。
7
12
  */
8
- import type { RequestContext } from '@tbox.cn/app-contracts';
13
+ import type { RequestContext, ScopeAssemblyContract } from '@tbox.cn/app-contracts';
9
14
  import type { MallDeploymentControlPlane } from './deployment';
10
- import { type MallScope, type MallRequestContext } from './scope';
15
+ import { type MallScope } from './scope';
16
+ /**
17
+ * mall 域登录换码槽(integrations services 键;TIER1 拥有 mall 域槽位词汇——
18
+ * provider 包与模板装配点经本常量收敛,禁止各处拼写 'auth.alipay-login' 字面量)。
19
+ */
20
+ export declare const AUTH_LOGIN_SERVICE = "auth.alipay-login";
21
+ /**
22
+ * mall 域装配形状(TIER0 ScopeAssemblyContract 的 TIER1 具体化;W3-3 自 module-mall-core 下沉):
23
+ * module-mall-core register 期注册于 ctx.domainAssemblies(SCOPE_ASSEMBLY_KIND),
24
+ * 消费方(模板装配点/module-mall-home/SDK)按本类型泛型断言查表——域模块间零包依赖
25
+ * (workspace-dag 铁律:跨模块走注册表 + 契约类型)。
26
+ * 成员 = 模板装配点(validateContext/scopeSessions/start 装点/WS 双钩)最小必要性合集。
27
+ */
28
+ export interface MallScopeAssembly extends ScopeAssemblyContract {
29
+ /** 控制平面(只读快照;纯元数据参考表——展示/目录/默认解析消费,非闸门) */
30
+ readonly controlPlane: Readonly<MallDeploymentControlPlane>;
31
+ /** root config.miniAppId(登录槽 code2Session 入参真源;enhance 回填 + default 兜底共用) */
32
+ readonly rootMiniAppId: string | undefined;
33
+ /** scope 键提取(SDK ScopeSessionRegistry 注入点) */
34
+ extractScopeKey(ctx: RequestContext): string;
35
+ /** scope 形状校验(SDK ScopeSessionRegistry 注入点 + HTTP validateContext 同核) */
36
+ validateScope(attributes: Record<string, unknown>): boolean;
37
+ /** 提取 MallScope(模块 handler 前置;无 scope → undefined 由调用方降级) */
38
+ extractMallScope(ctx: RequestContext): MallScope | undefined;
39
+ /** 领域扁平 scope(原始形态;ActionGrant/memory 隔离等消费) */
40
+ buildScope(attributes: Record<string, unknown>): Record<string, string>;
41
+ /** 扁平 scope + mallName 回填(scopeSessions 注入点;三级回退见 withMallName) */
42
+ buildScopeWithMallName(attributes: Record<string, unknown>): Record<string, string>;
43
+ /** instanceId 提取(integrations 槽解析轴;SDK 零领域注入点) */
44
+ instanceIdOf(scope: Record<string, string>): string;
45
+ /** 域默认值(SDK ctx.scopeDefaults 视图唯一直接消费面) */
46
+ readonly scopeDefaults: Readonly<Record<string, unknown>> | undefined;
47
+ /** 016:默认商圈 HELLO context(无 URL 参数访问时的服务端兜底;缺省 defaultMallId → undefined) */
48
+ defaultMallContext(): Record<string, unknown> | undefined;
49
+ /** D1:ENHANCE_CTX 双职责(miniAppId 回填 + mall.info 预热;fail-soft——抛错/超时原 context 继续) */
50
+ enhanceHelloContext(context: Record<string, unknown>): Promise<Record<string, unknown>>;
51
+ }
52
+ /**
53
+ * 形状守卫核(WS/HTTP 两形态共享单一来源):
54
+ * - mall 键缺席 → true(非 mall 部署/无 context 放行——校验面不因缺 mall 拒绝;
55
+ * '' scopeKey = 全局会话);
56
+ * - mall 键在场 → mallId 非空串(会话边界键唯一硬要求;miniAppId 可选——
57
+ * 客户端发送侧本就条件附加,v4 起服务端不再要求)。
58
+ */
59
+ export declare function isValidMallShape(attributes: Record<string, unknown>): boolean;
11
60
  /** 装配器产物:模板注入 createScopeSessionRegistry 的 extractor/validator + 领域提取函数 */
12
61
  export interface MallRuntimeAssembly {
13
62
  /**
14
63
  * scope 键提取(SDK ScopeSessionRegistry 注入点):
15
- * mall scope → 'Mall scope is required'(非 mall 部署不应装载本装配器)。
64
+ * mall scope 在场 mallId;防御兜底 ''(主通路:无 mall context 不触发 bootstrap,
65
+ * 本函数不会被无 scope 会话调用)。
16
66
  */
17
67
  extractScopeKey(ctx: RequestContext): string;
18
- /** scope 白名单校验(SDK ScopeSessionRegistry 注入点):parseMallScope 成功且 mallId ∈ malls */
68
+ /** scope 形状校验(SDK ScopeSessionRegistry 注入点):单一形状守卫核(白名单判定已退役) */
19
69
  validateScope(attributes: Record<string, unknown>): boolean;
20
70
  /** 011 D1:领域扁平 scope(回显 + ActionGrant 签发/校验单一来源) */
21
71
  buildScope(attributes: Record<string, unknown>): Record<string, string>;
22
72
  /** 提取 MallScope(模块 handler 前置;无 scope → undefined 由调用方降级) */
23
73
  extractMallScope(ctx: RequestContext): MallScope | undefined;
24
- /** 提取必在 MallScope(调用方已确认存在) */
25
- requireMallScope(ctx: MallRequestContext): MallScope;
26
- /** 控制平面(只读快照) */
74
+ /** 控制平面(只读快照;纯元数据参考表——展示/目录/默认解析消费,非闸门) */
27
75
  controlPlane: Readonly<MallDeploymentControlPlane>;
28
76
  }
29
77
  export declare function createMallRuntimeAssembly(controlPlane: MallDeploymentControlPlane): MallRuntimeAssembly;
78
+ /**
79
+ * HTTP validateContext 形态(上下文统一化全局面注入点):与 WS validateScope
80
+ * 共享同一形状守卫核(isValidMallShape)——单一来源,勿再分叉。
81
+ * HTTP 面消费 mallId-only 形状(login/dev-login 的 body.context 有独立归一化,
82
+ * 不套 MallScope 全形状);miniAppId 不要求(消费点自补:linked-panel 自查表;
83
+ * WS 面由 enhanceContext 补——两形态不对称有内在一致性,勿补对称)。
84
+ */
85
+ export declare function createMallContextValidator(): (attributes: Record<string, unknown>) => boolean;
86
+ /**
87
+ * 014 T1:buildScope 包装——从控制平面参考表回填 mallName(自 mall 模板 deployment.ts
88
+ * 迁入,单一模板统一化 W1-①)。
89
+ * scopeFlat(mallId[+miniAppId])→ HELLO_ACK.mallScope 回显,mallName 为壳品牌区
90
+ * (ChatHeader)服务端真源。
91
+ *
92
+ * 三级回退(动态商场):参考表命中 → mall.name;未命中 → fallbackName?.(mallId)
93
+ * (mall.info 槽缓存)→ 双 miss 原样返回(降级)。
94
+ */
95
+ export declare function withMallName(assembly: MallRuntimeAssembly, controlPlane: MallDeploymentControlPlane, fallbackName?: (mallId: string) => string | undefined): (attributes: Record<string, unknown>) => Record<string, string>;
@@ -0,0 +1,43 @@
1
+ // src/scope.ts
2
+ import { z } from "zod";
3
+ import { defineContextSlot } from "@tbox.cn/app-contracts";
4
+ var MALL_SCOPE_KEY = "mall";
5
+ var mallScopeSchema = z.object({
6
+ miniAppId: z.string().min(1).optional(),
7
+ mallId: z.string().min(1),
8
+ subjectId: z.string().optional()
9
+ });
10
+ var mallSlot = defineContextSlot({
11
+ key: MALL_SCOPE_KEY,
12
+ parse: (raw) => {
13
+ if (!raw || typeof raw !== "object") return void 0;
14
+ const result = mallScopeSchema.safeParse(raw);
15
+ return result.success ? result.data : void 0;
16
+ }
17
+ });
18
+ function parseMallScope(attributes) {
19
+ return mallSlot.read(attributes);
20
+ }
21
+ function extractMallScope(ctx) {
22
+ return parseMallScope(ctx.attributes);
23
+ }
24
+ function mallScopeOf(reqCtx) {
25
+ const mallId = parseMallScope(reqCtx.attributes ?? {})?.mallId;
26
+ return mallId ? { mallId } : {};
27
+ }
28
+ function readLoginMallId(context) {
29
+ const mall = context?.[MALL_SCOPE_KEY];
30
+ if (!mall || typeof mall !== "object") return void 0;
31
+ const mallId = mall.mallId;
32
+ return typeof mallId === "string" && mallId.length > 0 ? mallId : void 0;
33
+ }
34
+
35
+ export {
36
+ MALL_SCOPE_KEY,
37
+ mallScopeSchema,
38
+ mallSlot,
39
+ parseMallScope,
40
+ extractMallScope,
41
+ mallScopeOf,
42
+ readLoginMallId
43
+ };
@@ -1,43 +1,42 @@
1
1
  /**
2
- * 商圈部署控制平面(011 L2:三段配置的类型真源):
3
- * deployment(小程序/agent/组件清单)+ malls(白名单)+ providerInstances(外部服务实例)。
4
- * 无内联密钥(loader 断言在模板层,见 011 L2)。
2
+ * 商圈部署控制平面(纯 mall 域两键:零重复收敛):
3
+ * malls(参考表——纯元数据,v4 起永不充当解析闸门)+ defaultMallId(默认商圈)。
4
+ * 构造来源 = mallControlPlaneOf 投影(server/mall-control-plane.ts):root instances
5
+ * 注册表(integrations v4)→ 本形状;无参考表 → 空平面(模板装配零拓扑分支)。
6
+ * provider 绑定唯一真源 = config/integrations.json(integrations v4:绑定组整组继承 + catalog 派生,
7
+ * 真源 providers.md)——控制面不再承载
8
+ * providerTemplates/providerInstances(换码走 resolveLoginExchange、旁路 bumpin 走
9
+ * config/bumpin.json 配置面)。无内联密钥(loader 断言在模板层)。
10
+ * 014:deployment(miniAppId/agentId/components)整体移除——零消费方(代码即事实),
11
+ * 能力开关 = 模块 add/remove,非部署级 feature 裁剪。
5
12
  */
6
- import type { ProviderInstance } from '@tbox.cn/app-contracts';
7
- /** 组件启用项:componentId + 可选 feature 子集(feature 门控 = 运行时护栏,非装配期裁剪,011 D10) */
8
- export interface MallDeploymentComponent {
9
- componentId: string;
10
- /** 启用 feature(⊆ 模块 declaration.features,doctor feature-declaration 校验) */
11
- enabledFeatures?: string[];
12
- /** 可选组件:未安装该模块时 doctor 降级 warning(缺省 false = 必须安装) */
13
- optional?: boolean;
14
- }
15
13
  /** 商圈白名单项 */
16
14
  export interface MallDeploymentMall {
17
15
  mallId: string;
18
16
  name: string;
17
+ /** 客服电话(可选;shopping-guide customer-service-faq 卡 link 拨打条目消费,缺省不渲染) */
18
+ contactPhone?: string;
19
+ /** 小程序 appId(可选拓扑值;mall 级共享——HELLO context.mall.miniAppId 的配置承载,供默认商圈拼装) */
20
+ miniAppId?: string;
21
+ /**
22
+ * 地理坐标(可选;有值时参与 /api/m/mall-home/nearby-mall 就近推荐;缺省不参与排序)。
23
+ * 坐标系:WGS-84(高德/支付宝 getLocation 默认输出)。
24
+ */
25
+ location?: {
26
+ lat: number;
27
+ lon: number;
28
+ /** 展示地址(可选;推荐 Banner 展示用) */
29
+ address?: string;
30
+ };
19
31
  }
20
- /** Provider 模版声明(011 评审 7.1:credentialType 真源参数化,模板装配不再硬编码商家类型) */
21
- export interface MallDeploymentProviderTemplate {
22
- /** 'id@version'(与 ProviderInstance.providerTemplateId 匹配) */
23
- providerTemplateId: string;
24
- /** 认证类型(ProviderAuthStrategy.credentialType 注册点匹配键) */
25
- credentialType: string;
26
- }
27
- /** 部署控制平面(部署配置 JSON 的形状) */
32
+ /** 部署控制平面(mallControlPlaneOf 投影产物;provider 绑定迁 integrations 后纯两键) */
28
33
  export interface MallDeploymentControlPlane {
29
- deployment: {
30
- /** 小程序 appId */
31
- miniAppId: string;
32
- /** agent 实例 id */
33
- agentId: string;
34
- /** 组件清单(与已装模块对账,doctor deployment-consistency) */
35
- components: MallDeploymentComponent[];
36
- };
37
- /** 商圈白名单(validateScope 依据) */
34
+ /** 商圈参考表(纯元数据:目录/展示/默认解析;v4 起非会话闸门) */
38
35
  malls: MallDeploymentMall[];
39
- /** Provider 模版声明(可选;缺省由模板装配从实例派生) */
40
- providerTemplates?: MallDeploymentProviderTemplate[];
41
- /** Provider 实例(三段之三;机密走 credentialRef,禁内联密钥) */
42
- providerInstances: ProviderInstance[];
36
+ /**
37
+ * 默认商圈(可选):无 URL 参数访问时服务端补入 HELLO context 的 mallId。
38
+ * 来源 = normalizeInstances(显式 ?? 单实例唯一解);参考表缺席时仍可在场
39
+ * (env 注入动态默认形态——defaultInstanceId 独立键);URL 显式参数优先级更高。
40
+ */
41
+ defaultMallId?: string;
43
42
  }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 营销活动域模型(015,TIER1):活动聚合 + 场次 + 参与指南。
3
+ */
4
+ export interface PromotionActivity {
5
+ /** 报名/详情深链(provider 出参快照,数据驱动;缺省 = 无报名通道) */
6
+ registrationUrl?: string;
7
+ readonly activityRef: string;
8
+ readonly title: string;
9
+ readonly subtitle?: string;
10
+ readonly coverUrl?: string;
11
+ readonly categoryId?: string;
12
+ /** 是否需要报名 */
13
+ readonly registrationRequired: boolean;
14
+ /** 剩余名额(厂商事实,可缺省) */
15
+ readonly remainingQuota?: number;
16
+ readonly startAt?: string;
17
+ readonly endAt?: string;
18
+ /** 活动关联 Offer(可领取优惠券等) */
19
+ readonly offerRefs: readonly string[];
20
+ /**
21
+ * 联单/累计型活动(N 笔累计解锁奖励;卡片走 steps 进度形态)。
22
+ * 厂商中立语义标志:由 provider 按厂商侧活动类型枚举映射(如支付宝 actType=N_COUNT_TYPE),
23
+ * 消费方不得用标题关键字自行判定。
24
+ */
25
+ readonly linkedOrder?: boolean;
26
+ /**
27
+ * 活动生命周期状态(厂商侧枚举经 provider 映射为中立语义,如支付宝碰出惊喜
28
+ * NOT_START/INIT/PROCESSING/FINISH/RECEIVED)。缺省 = 无法判定,消费方按进行中兜底展示。
29
+ */
30
+ readonly activityStatus?: string;
31
+ /** 首页资源位没有独立详情时为 true;用于调整卡片文案而不改变历史活动语义。 */
32
+ readonly jumpOnly?: boolean;
33
+ /** 资源位跳转按钮文案,缺省由卡片按活动/资源位语义生成。 */
34
+ readonly jumpLabel?: string;
35
+ }
36
+ export interface PromotionActivityPage {
37
+ readonly items: readonly PromotionActivity[];
38
+ readonly nextCursor?: string;
39
+ readonly hasMore: boolean;
40
+ }
41
+ /** 活动场次 */
42
+ export interface ActivitySession {
43
+ readonly sessionRef: string;
44
+ readonly title: string;
45
+ readonly startAt: string;
46
+ readonly endAt?: string;
47
+ readonly location?: string;
48
+ readonly remainingQuota?: number;
49
+ readonly status: 'OPEN' | 'FULL' | 'CLOSED' | 'UNKNOWN';
50
+ }
51
+ /** 参与指南(步骤 + 条款) */
52
+ export interface ActivityGuide {
53
+ readonly steps: ReadonlyArray<{
54
+ readonly title: string;
55
+ readonly description?: string;
56
+ }>;
57
+ readonly conditions: readonly string[];
58
+ readonly notice?: string;
59
+ }
60
+ export interface PromotionActivityDetail extends PromotionActivity {
61
+ readonly description?: string;
62
+ readonly sessions: readonly ActivitySession[];
63
+ readonly guide?: ActivityGuide;
64
+ }
@@ -6,3 +6,5 @@ export interface Coupon {
6
6
  amount: number;
7
7
  status: 'AVAILABLE' | 'USED' | 'EXPIRED';
8
8
  }
9
+ /** 免费券领取通道;缺省由消费方保持既有直领语义。 */
10
+ export type FreeCouponClaimMode = 'DIRECT' | 'REDIRECT';