@tbox.cn/app-contracts-mall 0.10.0 → 0.12.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.
@@ -344,10 +344,10 @@ export declare const memberEnrollmentFormCardDataSchema: z.ZodObject<{
344
344
  status: z.ZodEnum<["required", "authorized", "unavailable"]>;
345
345
  mobileMasked: z.ZodOptional<z.ZodString>;
346
346
  }, "strip", z.ZodTypeAny, {
347
- status: "required" | "unavailable" | "authorized";
347
+ status: "unavailable" | "required" | "authorized";
348
348
  mobileMasked?: string | undefined;
349
349
  }, {
350
- status: "required" | "unavailable" | "authorized";
350
+ status: "unavailable" | "required" | "authorized";
351
351
  mobileMasked?: string | undefined;
352
352
  }>;
353
353
  /** 手动填写模式提示(授权不可用降级) */
@@ -374,7 +374,7 @@ export declare const memberEnrollmentFormCardDataSchema: z.ZodObject<{
374
374
  url?: string | undefined;
375
375
  }[];
376
376
  authorization: {
377
- status: "required" | "unavailable" | "authorized";
377
+ status: "unavailable" | "required" | "authorized";
378
378
  mobileMasked?: string | undefined;
379
379
  };
380
380
  manualNotice?: string | undefined;
@@ -400,7 +400,7 @@ export declare const memberEnrollmentFormCardDataSchema: z.ZodObject<{
400
400
  url?: string | undefined;
401
401
  }[];
402
402
  authorization: {
403
- status: "required" | "unavailable" | "authorized";
403
+ status: "unavailable" | "required" | "authorized";
404
404
  mobileMasked?: string | undefined;
405
405
  };
406
406
  manualNotice?: string | undefined;
@@ -809,10 +809,10 @@ export declare const memberCardDataSchemas: {
809
809
  status: z.ZodEnum<["required", "authorized", "unavailable"]>;
810
810
  mobileMasked: z.ZodOptional<z.ZodString>;
811
811
  }, "strip", z.ZodTypeAny, {
812
- status: "required" | "unavailable" | "authorized";
812
+ status: "unavailable" | "required" | "authorized";
813
813
  mobileMasked?: string | undefined;
814
814
  }, {
815
- status: "required" | "unavailable" | "authorized";
815
+ status: "unavailable" | "required" | "authorized";
816
816
  mobileMasked?: string | undefined;
817
817
  }>;
818
818
  /** 手动填写模式提示(授权不可用降级) */
@@ -839,7 +839,7 @@ export declare const memberCardDataSchemas: {
839
839
  url?: string | undefined;
840
840
  }[];
841
841
  authorization: {
842
- status: "required" | "unavailable" | "authorized";
842
+ status: "unavailable" | "required" | "authorized";
843
843
  mobileMasked?: string | undefined;
844
844
  };
845
845
  manualNotice?: string | undefined;
@@ -865,7 +865,7 @@ export declare const memberCardDataSchemas: {
865
865
  url?: string | undefined;
866
866
  }[];
867
867
  authorization: {
868
- status: "required" | "unavailable" | "authorized";
868
+ status: "unavailable" | "required" | "authorized";
869
869
  mobileMasked?: string | undefined;
870
870
  };
871
871
  manualNotice?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-contracts-mall",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "商圈领域契约(TIER1,types + runtime):Port 接口 + MallEventMap + 领域 DTO + scope/装配器运行时。",
6
6
  "exports": {
@@ -29,11 +29,10 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@tbox.cn/app-contracts": "0.10.0",
32
+ "@tbox.cn/app-contracts": "0.12.0",
33
33
  "zod": "3.25.76"
34
34
  },
35
35
  "devDependencies": {
36
- "@tbox.cn/app-sdk": "0.19.0",
37
36
  "tsup": "8.5.1",
38
37
  "typescript": "5.9.3",
39
38
  "vitest": "4.1.10",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$comment": "mall 域 service slot 词汇唯一真源。共址 TS 常量并集必须与本文件 slots 逐元素相等(tests/service-slots.test.ts 锁);manifest demand/supply ⊆ slots(scripts/guard-service-slots.mjs 锁)。旧词汇不在此——迁移归 cookbook 配方。",
2
+ "$comment": "mall 域 service slot 词汇唯一真源。共址 TS 常量并集必须与本文件 slots 逐元素相等(tests/service-slots.test.ts 锁);manifest demand/supply ⊆ slots(scripts/guard-service-slots.mjs 锁)。旧词汇不在此——迁移归 cookbook 配方。meta 节 = 槽展示名单源(app-toolkit resolveServiceDisplay 词汇主源 > manifest demand > id;词汇锁:键集 = slots 键集 ∧ 每条 title 必填——新槽裸 id 不可上线)。",
3
3
  "slots": [
4
4
  "member.account",
5
5
  "member.profile",
@@ -22,5 +22,28 @@
22
22
  "auth.alipay-login",
23
23
  "mall.info",
24
24
  "mall.info-cache"
25
- ]
25
+ ],
26
+ "meta": {
27
+ "member.account": { "name": "会员账户", "description": "登录与入会状态、会员外部引用" },
28
+ "member.profile": { "name": "会员资料", "description": "昵称头像、联系方式与标签" },
29
+ "member.card": { "name": "会员卡面", "description": "卡面快照:等级、消费进度、权益摘要" },
30
+ "member.benefits": { "name": "会员权益", "description": "权益列表与消耗进度" },
31
+ "member.enrollment": { "name": "会员入会", "description": "入会表单查询与入会动作" },
32
+ "member.snapshot": { "name": "会员快照", "description": "会员域聚合快照(面板读)" },
33
+ "parking.query": { "name": "停车查询", "description": "费用报价、车场信息、可享权益" },
34
+ "parking.payment": { "name": "停车缴费", "description": "缴费下单、支付状态、记录与开票" },
35
+ "parking.vehicle": { "name": "车辆管理", "description": "绑定车辆、车牌管理、寻车定位" },
36
+ "parking.snapshot": { "name": "停车快照", "description": "停车域聚合快照" },
37
+ "promotion.offers": { "name": "营销优惠", "description": "券、团购等优惠查询" },
38
+ "promotion.entitlements": { "name": "营销权益", "description": "我的券与领取资格" },
39
+ "promotion.activities": { "name": "营销活动", "description": "活动列表详情与参与指引" },
40
+ "promotion.acquisition": { "name": "营销领取", "description": "券领取写链" },
41
+ "shopping-guide.catalog": { "name": "导购检索", "description": "商品与商户检索" },
42
+ "shopping-guide.shops": { "name": "商户查询", "description": "商户列表与详情" },
43
+ "shopping-guide.categories": { "name": "类目浏览", "description": "楼层与类目目录" },
44
+ "shopping-guide.directory": { "name": "商场目录", "description": "商场、门店、楼层目录服务" },
45
+ "auth.alipay-login": { "name": "支付宝登录", "description": "登录换码(code2Session)" },
46
+ "mall.info": { "name": "商场信息", "description": "商场名称地址坐标,动态商场信息源" },
47
+ "mall.info-cache": { "name": "商场信息缓存", "description": "商场信息缓存读面(缓存→合并请求→槽)" }
48
+ }
26
49
  }
@@ -9,7 +9,7 @@ import { resolveMemberGate } from '../src/services/member';
9
9
  import * as runtime from '../src/runtime';
10
10
 
11
11
  const anonymous = { source: 'anonymous' as const };
12
- const dev = { source: 'dev' as const };
12
+ const dev = { source: 'local' as const };
13
13
 
14
14
  function account(authState: 'authenticated' | 'unauthenticated', state: MemberAccountSnapshot['state']): MemberAccountSnapshot {
15
15
  return { authState, state, observedAt: '2026-08-30T00:00:00.000Z' };
@@ -148,7 +148,7 @@ describe('memberGateCardOf(纯卡映射)', () => {
148
148
  });
149
149
 
150
150
  describe('resolveMemberGate(编排单源)', () => {
151
- const reqCtx = { identity: { userId: 'u-1', source: 'dev' as const } } as never;
151
+ const reqCtx = { identity: { userId: 'u-1', source: 'local' as const } } as never;
152
152
  const statusOf = (s: Partial<MemberStatusResolution>): MemberStatusResolution =>
153
153
  ({ outcome: 'active', ...s }) as MemberStatusResolution;
154
154
 
@@ -88,8 +88,8 @@ describe('消费原子与组合子', () => {
88
88
  expect(mallScopeOrEmpty(bare)).not.toBe(fallback); // 免疫共享引用
89
89
  });
90
90
 
91
- it('Q8: mallSubjectIdOf——anonymous → undefined;local/external/dev → userId', () => {
92
- for (const source of ['local', 'external', 'dev'] as const) {
91
+ it('Q8: mallSubjectIdOf——anonymous → undefined;local/external/guest → userId', () => {
92
+ for (const source of ['local', 'external', 'guest'] as const) {
93
93
  expect(mallSubjectIdOf(reqCtxOf({ identity: { userId: 'u-1', source } }))).toBe('u-1');
94
94
  }
95
95
  expect(mallSubjectIdOf(reqCtxOf({ identity: { userId: 'u-1', source: 'anonymous' } }))).toBeUndefined();
@@ -81,3 +81,20 @@ describe('service slot 词汇交叉锁(JSON 真源 ↔ TS 共址常量)', ()
81
81
  }
82
82
  });
83
83
  });
84
+
85
+ describe('词汇 meta 锁(B2 展示名单源)', () => {
86
+ const meta = (slotsJson as { meta?: Record<string, unknown> }).meta ?? {};
87
+
88
+ it('meta 键集 ≡ slots 键集(新槽必须同步落展示名——裸 id 不可上线)', () => {
89
+ expect(Object.keys(meta).sort()).toEqual([...slotsJson.slots].sort());
90
+ });
91
+
92
+ it('每条 meta name 必填(string 非空);值形状为对象', () => {
93
+ for (const [svc, entry] of Object.entries(meta)) {
94
+ expect(entry, `${svc} meta 非对象`).toBeTypeOf('object');
95
+ const name = (entry as { name?: unknown }).name;
96
+ expect(typeof name, `${svc} 缺 name`).toBe('string');
97
+ expect((name as string).length, `${svc} name 空串`).toBeGreaterThan(0);
98
+ }
99
+ });
100
+ });