@tbox.cn/app-module-member 0.9.0 → 0.9.2

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 (36) hide show
  1. package/AGENTS.md +1 -1
  2. package/dist/{chunk-QWGRWD5C.js → chunk-GMHJMLRV.js} +10 -9
  3. package/dist/{chunk-EPQEF43P.js → chunk-YQZ64C6P.js} +12 -9
  4. package/dist/client/index.d.ts +1 -1
  5. package/dist/client/index.js +1 -1
  6. package/dist/index.d.ts +3 -2
  7. package/dist/index.js +2 -2
  8. package/dist/server/index.d.ts +86 -86
  9. package/dist/server/index.js +1 -1
  10. package/package.json +5 -4
  11. package/src/client/cards/member-card-summary/index.tsx +1 -1
  12. package/src/client/cards/member-enrollment-cta/index.tsx +1 -1
  13. package/src/client/cards/member-enrollment-form/index.tsx +1 -1
  14. package/src/client/cards/member-enrollment-status/index.tsx +1 -1
  15. package/src/client/cards/member-login-cta/index.tsx +1 -1
  16. package/src/client/components/ImageWithFallback.tsx +2 -1
  17. package/src/client/index.ts +1 -1
  18. package/src/server/action.ts +2 -2
  19. package/src/server/cards/member-card-summary/meta.ts +4 -4
  20. package/src/server/cards/member-card-summary/samples.ts +15 -6
  21. package/src/server/handler.ts +1 -1
  22. package/src/server/index.ts +2 -2
  23. package/src/server/ports.ts +1 -1
  24. package/src/server/status.ts +1 -1
  25. package/src/server/subject-binding.ts +1 -1
  26. package/src/server/tool.ts +3 -3
  27. package/tbox.module.json +32 -12
  28. package/tests/cards-render.test.tsx +3 -3
  29. package/tests/enrollment.test.ts +1 -1
  30. package/tests/ports-resolve.test.ts +2 -2
  31. package/tests/preference-memory.test.ts +1 -1
  32. package/tests/samples.test.ts +20 -1
  33. package/tests/service.test.ts +2 -2
  34. package/tests/snapshot-service.test.ts +1 -1
  35. package/tests/status.test.ts +1 -1
  36. package/tsup.config.ts +2 -1
package/AGENTS.md CHANGED
@@ -12,5 +12,5 @@
12
12
 
13
13
  ## 真实厂商接入
14
14
 
15
- 官方 provider 包形态(manifest 槽声明 + 独立包发布)参照 `modules/provider-mock` 结构样例与
15
+ 官方 provider 包形态(manifest 槽声明 + 独立包发布)参照 `modules/provider-mock`(极简形态)/ `modules/provider-mocktest`(带 configSchema 形态)结构样例与
16
16
  docs/reference/providers.md;厂商中立措辞纪律见该参考(本文件受 vendor-neutrality 门禁扫描)。
@@ -5,12 +5,13 @@ import "./member-372B74DY.css";
5
5
  import { CalendarBlank, Phone, Tag, UserCircle } from "@phosphor-icons/react";
6
6
 
7
7
  // src/client/components/ImageWithFallback.tsx
8
- import { useState } from "react";
8
+ import { useEffect, useState } from "react";
9
9
  import { ImageSquare } from "@phosphor-icons/react";
10
10
  import { jsx } from "react/jsx-runtime";
11
11
  function ImageWithFallback(props) {
12
12
  const { src, alt, className, size = 40, loading = "lazy", fallback } = props;
13
13
  const [failed, setFailed] = useState(false);
14
+ useEffect(() => setFailed(false), [src]);
14
15
  if (!src || failed) {
15
16
  return /* @__PURE__ */ jsx("div", { className: `img-fallback ${className ?? ""}`.trim(), "aria-label": alt, role: "img", children: fallback ?? /* @__PURE__ */ jsx(ImageSquare, { weight: "duotone", size: Math.round(size * 0.45) }) });
16
17
  }
@@ -103,10 +104,10 @@ function MemberInfoCard(props) {
103
104
  var member_info_default = MemberInfoCard;
104
105
 
105
106
  // src/client/cards/member-card-summary/index.tsx
106
- import { useEffect, useMemo, useRef, useState as useState2 } from "react";
107
+ import { useEffect as useEffect2, useMemo, useRef, useState as useState2 } from "react";
107
108
  import { createPortal } from "react-dom";
108
109
  import { X } from "@phosphor-icons/react";
109
- import { markSelfRendering, sendCardAction } from "@tbox.cn/app-sdk/client";
110
+ import { markSelfRendering, sendCardAction } from "@tbox.cn/app-agent-sdk-client";
110
111
  import { Car, Confetti, Coins, Gift, Sparkle } from "@phosphor-icons/react";
111
112
  import { MEMBER_PREFERENCE_PROMPTS } from "@tbox.cn/app-contracts-mall";
112
113
  import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -158,7 +159,7 @@ function MemberCardSummaryCard(props) {
158
159
  const pointsRuleTriggerRef = useRef(null);
159
160
  const pointsRuleCloseRef = useRef(null);
160
161
  const pointsRuleCloseTimerRef = useRef();
161
- useEffect(() => {
162
+ useEffect2(() => {
162
163
  if (!pointsRuleOpen) return;
163
164
  const previousOverflow = document.body.style.overflow;
164
165
  document.body.style.overflow = "hidden";
@@ -173,7 +174,7 @@ function MemberCardSummaryCard(props) {
173
174
  window.removeEventListener("keydown", onKeyDown);
174
175
  };
175
176
  }, [pointsRuleOpen]);
176
- useEffect(() => () => {
177
+ useEffect2(() => () => {
177
178
  window.clearTimeout(pointsRuleCloseTimerRef.current);
178
179
  window.clearTimeout(benefitActionCloseTimerRef.current);
179
180
  }, []);
@@ -452,7 +453,7 @@ var member_point_usage_list_default = MemberPointUsageListCard;
452
453
  // src/client/cards/member-enrollment-form/index.tsx
453
454
  import { useRef as useRef2, useState as useState3 } from "react";
454
455
  import { Lock, ShieldCheck, UserPlus } from "@phosphor-icons/react";
455
- import { sendCardAction as sendCardAction2, markSelfRendering as markSelfRendering2 } from "@tbox.cn/app-sdk/client";
456
+ import { sendCardAction as sendCardAction2, markSelfRendering as markSelfRendering2 } from "@tbox.cn/app-agent-sdk-client";
456
457
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
457
458
  var AUTO_AUTH_ACTION = "member.request-alipay-authorization";
458
459
  function MemberEnrollmentFormCard(props) {
@@ -601,7 +602,7 @@ var member_enrollment_form_default = markSelfRendering2(MemberEnrollmentFormCard
601
602
  // src/client/cards/member-enrollment-status/index.tsx
602
603
  import { useRef as useRef3, useState as useState4 } from "react";
603
604
  import { ArrowClockwise, CheckCircle, Clock, WarningCircle } from "@phosphor-icons/react";
604
- import { sendCardAction as sendCardAction3, markSelfRendering as markSelfRendering3 } from "@tbox.cn/app-sdk/client";
605
+ import { sendCardAction as sendCardAction3, markSelfRendering as markSelfRendering3 } from "@tbox.cn/app-agent-sdk-client";
605
606
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
606
607
  var ICONS = { success: CheckCircle, warning: Clock, neutral: WarningCircle };
607
608
  function MemberEnrollmentStatusCard(props) {
@@ -648,7 +649,7 @@ var member_enrollment_status_default = markSelfRendering3(MemberEnrollmentStatus
648
649
  // src/client/cards/member-enrollment-cta/index.tsx
649
650
  import { useRef as useRef4, useState as useState5 } from "react";
650
651
  import { ArrowSquareOut, IdentificationCard, ShieldCheck as ShieldCheck2, WarningCircle as WarningCircle2 } from "@phosphor-icons/react";
651
- import { sendCardAction as sendCardAction4 } from "@tbox.cn/app-sdk/client";
652
+ import { sendCardAction as sendCardAction4 } from "@tbox.cn/app-agent-sdk-client";
652
653
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
653
654
  function MemberEnrollmentCtaCard(props) {
654
655
  const { data, cardId, isHistory } = props;
@@ -695,7 +696,7 @@ var member_enrollment_cta_default = MemberEnrollmentCtaCard;
695
696
  // src/client/cards/member-login-cta/index.tsx
696
697
  import { useRef as useRef5, useState as useState6 } from "react";
697
698
  import { ArrowSquareOut as ArrowSquareOut2, WarningCircle as WarningCircle3 } from "@phosphor-icons/react";
698
- import { sendCardAction as sendCardAction5 } from "@tbox.cn/app-sdk/client";
699
+ import { sendCardAction as sendCardAction5 } from "@tbox.cn/app-agent-sdk-client";
699
700
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
700
701
  function MemberLoginCtaCard(props) {
701
702
  const { data, cardId, isHistory } = props;
@@ -1,5 +1,5 @@
1
1
  // src/server/index.ts
2
- import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from "@tbox.cn/app-sdk/server";
2
+ import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from "@tbox.cn/app-agent-sdk-server";
3
3
  import { MEMBER_SNAPSHOT_SERVICE } from "@tbox.cn/app-contracts-mall";
4
4
 
5
5
  // src/server/cards/member-info/meta.ts
@@ -28,11 +28,14 @@ function cardFace(from, to) {
28
28
  const marks = '<rect x="58" y="52" width="210" height="42" rx="8" fill="%23000000" opacity="0.14"/><rect x="58" y="130" width="132" height="26" rx="6" fill="%23000000" opacity="0.10"/>';
29
29
  return `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="672" height="347"><defs><linearGradient id="f" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="%23${from}"/><stop offset="1" stop-color="%23${to}"/></linearGradient></defs><rect width="672" height="347" fill="url(%23f)"/><circle cx="548" cy="60" r="150" fill="%23ffffff" opacity="0.16"/>` + marks + "</svg>";
30
30
  }
31
+ var BLACK_CARD_IMAGE = "https://mdn.alipayobjects.com/huamei_b00jk5/afts/img/A*sdTfQ5NaRN8AAAAAgEAAAAgAegitAQ/fmt.webp";
31
32
  var FACE = {
32
- blue: cardFace("dce8fb", "aecdf5"),
33
+ blue: "https://mdn.alipayobjects.com/huamei_b00jk5/afts/img/A*OVn3SL73QbQAAAAAgDAAAAgAegitAQ/fmt.webp",
33
34
  silver: cardFace("eef1f7", "c4cddf"),
35
+ // gold 配浅金 SVG:恢复真实厂商世代叠字后金卡是浅底深字,黑金深图配金档=深字压深底不可读;
36
+ // 待世代规格(1344×694+透明边)浅金素材重制后再换平台 CDN 图。
34
37
  gold: cardFace("f9ecca", "e3c283"),
35
- black: cardFace("1b1e26", "4a412c")
38
+ black: BLACK_CARD_IMAGE
36
39
  };
37
40
  var POINTS_RULE_IMAGE = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="750" height="1600"><rect width="750" height="1600" fill="%23fffdf8"/><rect x="60" y="80" width="380" height="44" rx="10" fill="%23e2c78f"/><rect x="60" y="180" width="630" height="24" rx="8" fill="%23ece7dd"/><rect x="60" y="230" width="560" height="24" rx="8" fill="%23ece7dd"/><rect x="60" y="280" width="610" height="24" rx="8" fill="%23ece7dd"/><rect x="60" y="700" width="630" height="24" rx="8" fill="%23ece7dd"/><rect x="60" y="1500" width="400" height="24" rx="8" fill="%23ece7dd"/></svg>';
38
41
  var ICON_COLORS = {
@@ -288,12 +291,12 @@ var meta2 = {
288
291
  sampleData: {
289
292
  userId: "u_1001",
290
293
  cardRef: "card:u_1001",
291
- cardDisplay: "\u91D1\u5361\u4F1A\u5458",
294
+ cardDisplay: "\u9ED1\u5361\u4F1A\u5458",
292
295
  status: "active",
293
296
  availablePoints: 860,
294
- cardImageUrl: "https://assets.example.com/member/gold-card.png",
297
+ cardImageUrl: BLACK_CARD_IMAGE,
295
298
  pointsRuleImageUrl: "https://assets.example.com/member/points-rule.jpg",
296
- presentation: { variant: "gold", labelsEmbedded: true },
299
+ presentation: { variant: "black", labelsEmbedded: true },
297
300
  progress: {
298
301
  daySpentCents: 12345,
299
302
  yearSpentCents: 5e5,
@@ -412,8 +415,8 @@ var meta7 = {
412
415
  var meta_default7 = meta7;
413
416
 
414
417
  // src/server/tool.ts
415
- import { createTool } from "@tbox.cn/app-sdk/server";
416
- import { requireToolRequestContext } from "@tbox.cn/app-sdk/server";
418
+ import { createTool } from "@tbox.cn/app-agent-sdk-server";
419
+ import { requireToolRequestContext } from "@tbox.cn/app-agent-sdk-server";
417
420
  import { MEMBER_PREFERENCE_PROMPTS } from "@tbox.cn/app-contracts-mall";
418
421
  import { classifyMemberOutcome as classifyMemberOutcome2, memberGateCardOf } from "@tbox.cn/app-contracts-mall";
419
422
 
@@ -1195,7 +1198,7 @@ function createMemberHandler(ctx) {
1195
1198
 
1196
1199
  // src/server/action.ts
1197
1200
  import { createHash } from "crypto";
1198
- import { createAlipayUserAuthorization, InMemoryIdempotencyStore } from "@tbox.cn/app-sdk/server";
1201
+ import { createAlipayUserAuthorization, InMemoryIdempotencyStore } from "@tbox.cn/app-agent-sdk-server";
1199
1202
  import { parseMallScope as parseMallScope2 } from "@tbox.cn/app-contracts-mall";
1200
1203
  import { z as z2 } from "zod";
1201
1204
  var MEMBER_PROFILE_NAMESPACE = "member.enrollment.profile";
@@ -1,5 +1,5 @@
1
1
  import { CardComponent } from '@tbox.cn/app-contracts';
2
- import { ClientContext } from '@tbox.cn/app-sdk/client';
2
+ import { ClientContext } from '@tbox.cn/app-agent-sdk-client';
3
3
 
4
4
  /**
5
5
  * module-member 客户端入口(与服务端 serverModule 对称)。
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clientModule
3
- } from "../chunk-QWGRWD5C.js";
3
+ } from "../chunk-GMHJMLRV.js";
4
4
  export {
5
5
  clientModule
6
6
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export { InMemoryMemberService, MemberAccountService, MemberEnrollmentService, MemberService, memberCards, resolveMemberAccountPort, resolveMemberBenefitsPort, resolveMemberCardPort, resolveMemberEnrollmentPort, resolveMemberProfilePort, serverModule } from './server/index.js';
2
2
  export { clientModule } from './client/index.js';
3
- import '@tbox.cn/app-sdk/server';
3
+ import '@tbox.cn/app-sdk-server';
4
4
  import '@tbox.cn/app-contracts';
5
5
  import 'zod';
6
+ import '@tbox.cn/app-agent-sdk-server';
6
7
  import '@tbox.cn/app-contracts-mall';
7
- import '@tbox.cn/app-sdk/client';
8
+ import '@tbox.cn/app-agent-sdk-client';
package/dist/index.js CHANGED
@@ -7,10 +7,10 @@ import {
7
7
  resolveMemberEnrollmentPort,
8
8
  resolveMemberProfilePort,
9
9
  serverModule
10
- } from "./chunk-EPQEF43P.js";
10
+ } from "./chunk-YQZ64C6P.js";
11
11
  import {
12
12
  clientModule
13
- } from "./chunk-QWGRWD5C.js";
13
+ } from "./chunk-GMHJMLRV.js";
14
14
  export {
15
15
  InMemoryMemberService,
16
16
  clientModule,
@@ -1,8 +1,8 @@
1
- import * as _tbox_cn_app_sdk_server from '@tbox.cn/app-sdk/server';
2
- import { ServerContext } from '@tbox.cn/app-sdk/server';
1
+ import * as _tbox_cn_app_sdk_server from '@tbox.cn/app-sdk-server';
3
2
  import * as _tbox_cn_app_contracts from '@tbox.cn/app-contracts';
4
3
  import { RequestContext } from '@tbox.cn/app-contracts';
5
4
  import * as zod from 'zod';
5
+ import { ServerContext } from '@tbox.cn/app-agent-sdk-server';
6
6
  import { MemberAccountPort, MemberProfilePort, MemberCardPort, MemberBenefitsPort, MemberEnrollmentPort, MemberAccountSnapshot, MemberProfileSnapshot, MemberCardSnapshot, Points, MemberBenefitsSnapshot, MemberEnrollmentFormDefinition, PointUsageRecord, DiscountRule, MemberEnrollmentInput, MemberEnrollmentResult, MemberEnrollmentStatus } from '@tbox.cn/app-contracts-mall';
7
7
 
8
8
  /**
@@ -103,19 +103,19 @@ declare const memberCards: {
103
103
  labelRef: zod.ZodString;
104
104
  name: zod.ZodString;
105
105
  }, "strip", zod.ZodTypeAny, {
106
- labelRef: string;
107
106
  name: string;
108
- }, {
109
107
  labelRef: string;
108
+ }, {
110
109
  name: string;
110
+ labelRef: string;
111
111
  }>, "many">;
112
112
  }, "strip", zod.ZodTypeAny, {
113
113
  userId: string;
114
- authState: "authenticated" | "unauthenticated";
115
114
  state: "unknown" | "active" | "not_enrolled" | "closed";
115
+ authState: "authenticated" | "unauthenticated";
116
116
  labels: {
117
- labelRef: string;
118
117
  name: string;
118
+ labelRef: string;
119
119
  }[];
120
120
  displayName?: string | undefined;
121
121
  avatarUrl?: string | undefined;
@@ -124,11 +124,11 @@ declare const memberCards: {
124
124
  registeredAt?: string | undefined;
125
125
  }, {
126
126
  userId: string;
127
- authState: "authenticated" | "unauthenticated";
128
127
  state: "unknown" | "active" | "not_enrolled" | "closed";
128
+ authState: "authenticated" | "unauthenticated";
129
129
  labels: {
130
- labelRef: string;
131
130
  name: string;
131
+ labelRef: string;
132
132
  }[];
133
133
  displayName?: string | undefined;
134
134
  avatarUrl?: string | undefined;
@@ -185,13 +185,13 @@ declare const memberCards: {
185
185
  text: zod.ZodOptional<zod.ZodString>;
186
186
  }, "strip", zod.ZodTypeAny, {
187
187
  kind: "toast" | "miniapp" | "dialog";
188
- title?: string | undefined;
189
188
  url?: string | undefined;
189
+ title?: string | undefined;
190
190
  text?: string | undefined;
191
191
  }, {
192
192
  kind: "toast" | "miniapp" | "dialog";
193
- title?: string | undefined;
194
193
  url?: string | undefined;
194
+ title?: string | undefined;
195
195
  text?: string | undefined;
196
196
  }>>;
197
197
  }, "strip", zod.ZodTypeAny, {
@@ -200,8 +200,8 @@ declare const memberCards: {
200
200
  description?: string | undefined;
201
201
  action?: {
202
202
  kind: "toast" | "miniapp" | "dialog";
203
- title?: string | undefined;
204
203
  url?: string | undefined;
204
+ title?: string | undefined;
205
205
  text?: string | undefined;
206
206
  } | undefined;
207
207
  iconUrl?: string | undefined;
@@ -211,8 +211,8 @@ declare const memberCards: {
211
211
  description?: string | undefined;
212
212
  action?: {
213
213
  kind: "toast" | "miniapp" | "dialog";
214
- title?: string | undefined;
215
214
  url?: string | undefined;
215
+ title?: string | undefined;
216
216
  text?: string | undefined;
217
217
  } | undefined;
218
218
  iconUrl?: string | undefined;
@@ -228,8 +228,8 @@ declare const memberCards: {
228
228
  query: string;
229
229
  }>, "many">>;
230
230
  }, "strip", zod.ZodTypeAny, {
231
- userId: string;
232
231
  status: "unknown" | "active" | "inactive" | "frozen" | "expired";
232
+ userId: string;
233
233
  cardRef: string;
234
234
  cardDisplay: string;
235
235
  availablePoints: number;
@@ -254,8 +254,8 @@ declare const memberCards: {
254
254
  description?: string | undefined;
255
255
  action?: {
256
256
  kind: "toast" | "miniapp" | "dialog";
257
- title?: string | undefined;
258
257
  url?: string | undefined;
258
+ title?: string | undefined;
259
259
  text?: string | undefined;
260
260
  } | undefined;
261
261
  iconUrl?: string | undefined;
@@ -265,8 +265,8 @@ declare const memberCards: {
265
265
  query: string;
266
266
  }[] | undefined;
267
267
  }, {
268
- userId: string;
269
268
  status: "unknown" | "active" | "inactive" | "frozen" | "expired";
269
+ userId: string;
270
270
  cardRef: string;
271
271
  cardDisplay: string;
272
272
  availablePoints: number;
@@ -291,8 +291,8 @@ declare const memberCards: {
291
291
  description?: string | undefined;
292
292
  action?: {
293
293
  kind: "toast" | "miniapp" | "dialog";
294
- title?: string | undefined;
295
294
  url?: string | undefined;
295
+ title?: string | undefined;
296
296
  text?: string | undefined;
297
297
  } | undefined;
298
298
  iconUrl?: string | undefined;
@@ -313,42 +313,42 @@ declare const memberCards: {
313
313
  usedAt: zod.ZodOptional<zod.ZodString>;
314
314
  description: zod.ZodOptional<zod.ZodString>;
315
315
  }, "strip", zod.ZodTypeAny, {
316
- usageRecordRef: string;
317
316
  title: string;
317
+ usageRecordRef: string;
318
318
  amount: string;
319
- usedAt?: string | undefined;
320
319
  description?: string | undefined;
320
+ usedAt?: string | undefined;
321
321
  }, {
322
- usageRecordRef: string;
323
322
  title: string;
323
+ usageRecordRef: string;
324
324
  amount: string;
325
- usedAt?: string | undefined;
326
325
  description?: string | undefined;
326
+ usedAt?: string | undefined;
327
327
  }>, "many">;
328
328
  total: zod.ZodNumber;
329
329
  }, "strip", zod.ZodTypeAny, {
330
330
  userId: string;
331
- balance: number;
331
+ total: number;
332
332
  items: {
333
- usageRecordRef: string;
334
333
  title: string;
334
+ usageRecordRef: string;
335
335
  amount: string;
336
- usedAt?: string | undefined;
337
336
  description?: string | undefined;
337
+ usedAt?: string | undefined;
338
338
  }[];
339
- total: number;
339
+ balance: number;
340
340
  membershipLabel?: string | undefined;
341
341
  }, {
342
342
  userId: string;
343
- balance: number;
343
+ total: number;
344
344
  items: {
345
- usageRecordRef: string;
346
345
  title: string;
346
+ usageRecordRef: string;
347
347
  amount: string;
348
- usedAt?: string | undefined;
349
348
  description?: string | undefined;
349
+ usedAt?: string | undefined;
350
350
  }[];
351
- total: number;
351
+ balance: number;
352
352
  membershipLabel?: string | undefined;
353
353
  }>>;
354
354
  readonly 'member-enrollment-form': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -390,14 +390,14 @@ declare const memberCards: {
390
390
  required: zod.ZodBoolean;
391
391
  url: zod.ZodOptional<zod.ZodString>;
392
392
  }, "strip", zod.ZodTypeAny, {
393
- title: string;
394
393
  required: boolean;
394
+ title: string;
395
395
  version: string;
396
396
  consentId: string;
397
397
  url?: string | undefined;
398
398
  }, {
399
- title: string;
400
399
  required: boolean;
400
+ title: string;
401
401
  version: string;
402
402
  consentId: string;
403
403
  url?: string | undefined;
@@ -406,18 +406,17 @@ declare const memberCards: {
406
406
  status: zod.ZodEnum<["required", "authorized", "unavailable"]>;
407
407
  mobileMasked: zod.ZodOptional<zod.ZodString>;
408
408
  }, "strip", zod.ZodTypeAny, {
409
- status: "required" | "unavailable" | "authorized";
409
+ status: "unavailable" | "required" | "authorized";
410
410
  mobileMasked?: string | undefined;
411
411
  }, {
412
- status: "required" | "unavailable" | "authorized";
412
+ status: "unavailable" | "required" | "authorized";
413
413
  mobileMasked?: string | undefined;
414
414
  }>;
415
415
  manualNotice: zod.ZodOptional<zod.ZodString>;
416
416
  }, "strip", zod.ZodTypeAny, {
417
417
  userId: string;
418
- state: "unknown" | "active" | "not_enrolled" | "closed";
419
418
  authorization: {
420
- status: "required" | "unavailable" | "authorized";
419
+ status: "unavailable" | "required" | "authorized";
421
420
  mobileMasked?: string | undefined;
422
421
  };
423
422
  fields: {
@@ -430,10 +429,11 @@ declare const memberCards: {
430
429
  prefill?: string | undefined;
431
430
  placeholder?: string | undefined;
432
431
  }[];
432
+ state: "unknown" | "active" | "not_enrolled" | "closed";
433
433
  formVersion: string;
434
434
  consents: {
435
- title: string;
436
435
  required: boolean;
436
+ title: string;
437
437
  version: string;
438
438
  consentId: string;
439
439
  url?: string | undefined;
@@ -441,9 +441,8 @@ declare const memberCards: {
441
441
  manualNotice?: string | undefined;
442
442
  }, {
443
443
  userId: string;
444
- state: "unknown" | "active" | "not_enrolled" | "closed";
445
444
  authorization: {
446
- status: "required" | "unavailable" | "authorized";
445
+ status: "unavailable" | "required" | "authorized";
447
446
  mobileMasked?: string | undefined;
448
447
  };
449
448
  fields: {
@@ -456,10 +455,11 @@ declare const memberCards: {
456
455
  prefill?: string | undefined;
457
456
  placeholder?: string | undefined;
458
457
  }[];
458
+ state: "unknown" | "active" | "not_enrolled" | "closed";
459
459
  formVersion: string;
460
460
  consents: {
461
- title: string;
462
461
  required: boolean;
462
+ title: string;
463
463
  version: string;
464
464
  consentId: string;
465
465
  url?: string | undefined;
@@ -474,15 +474,15 @@ declare const memberCards: {
474
474
  message: zod.ZodOptional<zod.ZodString>;
475
475
  }, "strip", zod.ZodTypeAny, {
476
476
  userId: string;
477
- state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
478
- memberRef?: string | undefined;
477
+ state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
479
478
  message?: string | undefined;
479
+ memberRef?: string | undefined;
480
480
  attemptRef?: string | undefined;
481
481
  }, {
482
482
  userId: string;
483
- state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
484
- memberRef?: string | undefined;
483
+ state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
485
484
  message?: string | undefined;
485
+ memberRef?: string | undefined;
486
486
  attemptRef?: string | undefined;
487
487
  }>>;
488
488
  readonly 'member-enrollment-cta': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -495,16 +495,16 @@ declare const memberCards: {
495
495
  perks: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
496
496
  }, "strip", zod.ZodTypeAny, {
497
497
  userId: string;
498
- authState: "authenticated";
499
498
  state: "not_enrolled" | "closed";
499
+ authState: "authenticated";
500
500
  title?: string | undefined;
501
501
  subtitle?: string | undefined;
502
502
  enrollUrl?: string | undefined;
503
503
  perks?: string[] | undefined;
504
504
  }, {
505
505
  userId: string;
506
- authState: "authenticated";
507
506
  state: "not_enrolled" | "closed";
507
+ authState: "authenticated";
508
508
  title?: string | undefined;
509
509
  subtitle?: string | undefined;
510
510
  enrollUrl?: string | undefined;
@@ -541,19 +541,19 @@ declare const serverModule: {
541
541
  labelRef: zod.ZodString;
542
542
  name: zod.ZodString;
543
543
  }, "strip", zod.ZodTypeAny, {
544
- labelRef: string;
545
544
  name: string;
546
- }, {
547
545
  labelRef: string;
546
+ }, {
548
547
  name: string;
548
+ labelRef: string;
549
549
  }>, "many">;
550
550
  }, "strip", zod.ZodTypeAny, {
551
551
  userId: string;
552
- authState: "authenticated" | "unauthenticated";
553
552
  state: "unknown" | "active" | "not_enrolled" | "closed";
553
+ authState: "authenticated" | "unauthenticated";
554
554
  labels: {
555
- labelRef: string;
556
555
  name: string;
556
+ labelRef: string;
557
557
  }[];
558
558
  displayName?: string | undefined;
559
559
  avatarUrl?: string | undefined;
@@ -562,11 +562,11 @@ declare const serverModule: {
562
562
  registeredAt?: string | undefined;
563
563
  }, {
564
564
  userId: string;
565
- authState: "authenticated" | "unauthenticated";
566
565
  state: "unknown" | "active" | "not_enrolled" | "closed";
566
+ authState: "authenticated" | "unauthenticated";
567
567
  labels: {
568
- labelRef: string;
569
568
  name: string;
569
+ labelRef: string;
570
570
  }[];
571
571
  displayName?: string | undefined;
572
572
  avatarUrl?: string | undefined;
@@ -623,13 +623,13 @@ declare const serverModule: {
623
623
  text: zod.ZodOptional<zod.ZodString>;
624
624
  }, "strip", zod.ZodTypeAny, {
625
625
  kind: "toast" | "miniapp" | "dialog";
626
- title?: string | undefined;
627
626
  url?: string | undefined;
627
+ title?: string | undefined;
628
628
  text?: string | undefined;
629
629
  }, {
630
630
  kind: "toast" | "miniapp" | "dialog";
631
- title?: string | undefined;
632
631
  url?: string | undefined;
632
+ title?: string | undefined;
633
633
  text?: string | undefined;
634
634
  }>>;
635
635
  }, "strip", zod.ZodTypeAny, {
@@ -638,8 +638,8 @@ declare const serverModule: {
638
638
  description?: string | undefined;
639
639
  action?: {
640
640
  kind: "toast" | "miniapp" | "dialog";
641
- title?: string | undefined;
642
641
  url?: string | undefined;
642
+ title?: string | undefined;
643
643
  text?: string | undefined;
644
644
  } | undefined;
645
645
  iconUrl?: string | undefined;
@@ -649,8 +649,8 @@ declare const serverModule: {
649
649
  description?: string | undefined;
650
650
  action?: {
651
651
  kind: "toast" | "miniapp" | "dialog";
652
- title?: string | undefined;
653
652
  url?: string | undefined;
653
+ title?: string | undefined;
654
654
  text?: string | undefined;
655
655
  } | undefined;
656
656
  iconUrl?: string | undefined;
@@ -666,8 +666,8 @@ declare const serverModule: {
666
666
  query: string;
667
667
  }>, "many">>;
668
668
  }, "strip", zod.ZodTypeAny, {
669
- userId: string;
670
669
  status: "unknown" | "active" | "inactive" | "frozen" | "expired";
670
+ userId: string;
671
671
  cardRef: string;
672
672
  cardDisplay: string;
673
673
  availablePoints: number;
@@ -692,8 +692,8 @@ declare const serverModule: {
692
692
  description?: string | undefined;
693
693
  action?: {
694
694
  kind: "toast" | "miniapp" | "dialog";
695
- title?: string | undefined;
696
695
  url?: string | undefined;
696
+ title?: string | undefined;
697
697
  text?: string | undefined;
698
698
  } | undefined;
699
699
  iconUrl?: string | undefined;
@@ -703,8 +703,8 @@ declare const serverModule: {
703
703
  query: string;
704
704
  }[] | undefined;
705
705
  }, {
706
- userId: string;
707
706
  status: "unknown" | "active" | "inactive" | "frozen" | "expired";
707
+ userId: string;
708
708
  cardRef: string;
709
709
  cardDisplay: string;
710
710
  availablePoints: number;
@@ -729,8 +729,8 @@ declare const serverModule: {
729
729
  description?: string | undefined;
730
730
  action?: {
731
731
  kind: "toast" | "miniapp" | "dialog";
732
- title?: string | undefined;
733
732
  url?: string | undefined;
733
+ title?: string | undefined;
734
734
  text?: string | undefined;
735
735
  } | undefined;
736
736
  iconUrl?: string | undefined;
@@ -751,42 +751,42 @@ declare const serverModule: {
751
751
  usedAt: zod.ZodOptional<zod.ZodString>;
752
752
  description: zod.ZodOptional<zod.ZodString>;
753
753
  }, "strip", zod.ZodTypeAny, {
754
- usageRecordRef: string;
755
754
  title: string;
755
+ usageRecordRef: string;
756
756
  amount: string;
757
- usedAt?: string | undefined;
758
757
  description?: string | undefined;
758
+ usedAt?: string | undefined;
759
759
  }, {
760
- usageRecordRef: string;
761
760
  title: string;
761
+ usageRecordRef: string;
762
762
  amount: string;
763
- usedAt?: string | undefined;
764
763
  description?: string | undefined;
764
+ usedAt?: string | undefined;
765
765
  }>, "many">;
766
766
  total: zod.ZodNumber;
767
767
  }, "strip", zod.ZodTypeAny, {
768
768
  userId: string;
769
- balance: number;
769
+ total: number;
770
770
  items: {
771
- usageRecordRef: string;
772
771
  title: string;
772
+ usageRecordRef: string;
773
773
  amount: string;
774
- usedAt?: string | undefined;
775
774
  description?: string | undefined;
775
+ usedAt?: string | undefined;
776
776
  }[];
777
- total: number;
777
+ balance: number;
778
778
  membershipLabel?: string | undefined;
779
779
  }, {
780
780
  userId: string;
781
- balance: number;
781
+ total: number;
782
782
  items: {
783
- usageRecordRef: string;
784
783
  title: string;
784
+ usageRecordRef: string;
785
785
  amount: string;
786
- usedAt?: string | undefined;
787
786
  description?: string | undefined;
787
+ usedAt?: string | undefined;
788
788
  }[];
789
- total: number;
789
+ balance: number;
790
790
  membershipLabel?: string | undefined;
791
791
  }>>;
792
792
  readonly 'member-enrollment-form': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -828,14 +828,14 @@ declare const serverModule: {
828
828
  required: zod.ZodBoolean;
829
829
  url: zod.ZodOptional<zod.ZodString>;
830
830
  }, "strip", zod.ZodTypeAny, {
831
- title: string;
832
831
  required: boolean;
832
+ title: string;
833
833
  version: string;
834
834
  consentId: string;
835
835
  url?: string | undefined;
836
836
  }, {
837
- title: string;
838
837
  required: boolean;
838
+ title: string;
839
839
  version: string;
840
840
  consentId: string;
841
841
  url?: string | undefined;
@@ -844,18 +844,17 @@ declare const serverModule: {
844
844
  status: zod.ZodEnum<["required", "authorized", "unavailable"]>;
845
845
  mobileMasked: zod.ZodOptional<zod.ZodString>;
846
846
  }, "strip", zod.ZodTypeAny, {
847
- status: "required" | "unavailable" | "authorized";
847
+ status: "unavailable" | "required" | "authorized";
848
848
  mobileMasked?: string | undefined;
849
849
  }, {
850
- status: "required" | "unavailable" | "authorized";
850
+ status: "unavailable" | "required" | "authorized";
851
851
  mobileMasked?: string | undefined;
852
852
  }>;
853
853
  manualNotice: zod.ZodOptional<zod.ZodString>;
854
854
  }, "strip", zod.ZodTypeAny, {
855
855
  userId: string;
856
- state: "unknown" | "active" | "not_enrolled" | "closed";
857
856
  authorization: {
858
- status: "required" | "unavailable" | "authorized";
857
+ status: "unavailable" | "required" | "authorized";
859
858
  mobileMasked?: string | undefined;
860
859
  };
861
860
  fields: {
@@ -868,10 +867,11 @@ declare const serverModule: {
868
867
  prefill?: string | undefined;
869
868
  placeholder?: string | undefined;
870
869
  }[];
870
+ state: "unknown" | "active" | "not_enrolled" | "closed";
871
871
  formVersion: string;
872
872
  consents: {
873
- title: string;
874
873
  required: boolean;
874
+ title: string;
875
875
  version: string;
876
876
  consentId: string;
877
877
  url?: string | undefined;
@@ -879,9 +879,8 @@ declare const serverModule: {
879
879
  manualNotice?: string | undefined;
880
880
  }, {
881
881
  userId: string;
882
- state: "unknown" | "active" | "not_enrolled" | "closed";
883
882
  authorization: {
884
- status: "required" | "unavailable" | "authorized";
883
+ status: "unavailable" | "required" | "authorized";
885
884
  mobileMasked?: string | undefined;
886
885
  };
887
886
  fields: {
@@ -894,10 +893,11 @@ declare const serverModule: {
894
893
  prefill?: string | undefined;
895
894
  placeholder?: string | undefined;
896
895
  }[];
896
+ state: "unknown" | "active" | "not_enrolled" | "closed";
897
897
  formVersion: string;
898
898
  consents: {
899
- title: string;
900
899
  required: boolean;
900
+ title: string;
901
901
  version: string;
902
902
  consentId: string;
903
903
  url?: string | undefined;
@@ -912,15 +912,15 @@ declare const serverModule: {
912
912
  message: zod.ZodOptional<zod.ZodString>;
913
913
  }, "strip", zod.ZodTypeAny, {
914
914
  userId: string;
915
- state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
916
- memberRef?: string | undefined;
915
+ state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
917
916
  message?: string | undefined;
917
+ memberRef?: string | undefined;
918
918
  attemptRef?: string | undefined;
919
919
  }, {
920
920
  userId: string;
921
- state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
922
- memberRef?: string | undefined;
921
+ state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
923
922
  message?: string | undefined;
923
+ memberRef?: string | undefined;
924
924
  attemptRef?: string | undefined;
925
925
  }>>;
926
926
  readonly 'member-enrollment-cta': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -933,16 +933,16 @@ declare const serverModule: {
933
933
  perks: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
934
934
  }, "strip", zod.ZodTypeAny, {
935
935
  userId: string;
936
- authState: "authenticated";
937
936
  state: "not_enrolled" | "closed";
937
+ authState: "authenticated";
938
938
  title?: string | undefined;
939
939
  subtitle?: string | undefined;
940
940
  enrollUrl?: string | undefined;
941
941
  perks?: string[] | undefined;
942
942
  }, {
943
943
  userId: string;
944
- authState: "authenticated";
945
944
  state: "not_enrolled" | "closed";
945
+ authState: "authenticated";
946
946
  title?: string | undefined;
947
947
  subtitle?: string | undefined;
948
948
  enrollUrl?: string | undefined;
@@ -7,7 +7,7 @@ import {
7
7
  resolveMemberEnrollmentPort,
8
8
  resolveMemberProfilePort,
9
9
  serverModule
10
- } from "../chunk-EPQEF43P.js";
10
+ } from "../chunk-YQZ64C6P.js";
11
11
  export {
12
12
  InMemoryMemberService,
13
13
  memberCards,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-module-member",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "type": "module",
5
5
  "description": "商圈会员模块:会员账户、会员卡、积分流水与入会流程(codegen 源)。",
6
6
  "exports": {
@@ -18,9 +18,10 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@tbox.cn/app-sdk": "0.20.0",
22
- "@tbox.cn/app-contracts": "0.11.0",
23
- "@tbox.cn/app-contracts-mall": "0.11.0"
21
+ "@tbox.cn/app-contracts": "0.12.0",
22
+ "@tbox.cn/app-contracts-mall": "0.12.1",
23
+ "@tbox.cn/app-agent-sdk-client": "0.1.1",
24
+ "@tbox.cn/app-agent-sdk-server": "0.1.1"
24
25
  },
25
26
  "peerDependencies": {
26
27
  "zod": "3.25.76",
@@ -6,7 +6,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
6
6
  import type { ReactNode, SyntheticEvent, UIEvent } from 'react';
7
7
  import { createPortal } from 'react-dom';
8
8
  import { X } from '@phosphor-icons/react';
9
- import { markSelfRendering, sendCardAction } from '@tbox.cn/app-sdk/client';
9
+ import { markSelfRendering, sendCardAction } from '@tbox.cn/app-agent-sdk-client';
10
10
  import { Car, Confetti, Coins, Gift, Sparkle } from '@phosphor-icons/react';
11
11
  import { ImageWithFallback } from '../../components/ImageWithFallback';
12
12
  import { MEMBER_PREFERENCE_PROMPTS } from '@tbox.cn/app-contracts-mall';
@@ -1,7 +1,7 @@
1
1
  /** member-enrollment-cta:只呈现真实跳转入口,不预告未由 Provider 返回的会员权益。 */
2
2
  import { useRef, useState } from 'react';
3
3
  import { ArrowSquareOut, IdentificationCard, ShieldCheck, WarningCircle } from '@phosphor-icons/react';
4
- import { sendCardAction } from '@tbox.cn/app-sdk/client';
4
+ import { sendCardAction } from '@tbox.cn/app-agent-sdk-client';
5
5
  import type { MemberEnrollmentCtaCardData } from '@tbox.cn/app-contracts-mall';
6
6
 
7
7
  export function MemberEnrollmentCtaCard(props: {
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { useRef, useState } from 'react';
7
7
  import { Lock, ShieldCheck, UserPlus } from '@phosphor-icons/react';
8
- import { sendCardAction, markSelfRendering } from '@tbox.cn/app-sdk/client';
8
+ import { sendCardAction, markSelfRendering } from '@tbox.cn/app-agent-sdk-client';
9
9
  import type { MemberEnrollmentFormCardData } from '@tbox.cn/app-contracts-mall';
10
10
 
11
11
  const AUTO_AUTH_ACTION = 'member.request-alipay-authorization';
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { useRef, useState } from 'react';
5
5
  import { ArrowClockwise, CheckCircle, Clock, WarningCircle } from '@phosphor-icons/react';
6
- import { sendCardAction, markSelfRendering } from '@tbox.cn/app-sdk/client';
6
+ import { sendCardAction, markSelfRendering } from '@tbox.cn/app-agent-sdk-client';
7
7
  import { enrollmentStateText, enrollmentTone } from '../view';
8
8
  import type { MemberEnrollmentStatusCardData } from '@tbox.cn/app-contracts-mall';
9
9
 
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { useRef, useState } from 'react';
11
11
  import { ArrowSquareOut, WarningCircle } from '@phosphor-icons/react';
12
- import { sendCardAction } from '@tbox.cn/app-sdk/client';
12
+ import { sendCardAction } from '@tbox.cn/app-agent-sdk-client';
13
13
  import type { MemberLoginCtaCardData } from '@tbox.cn/app-contracts-mall';
14
14
 
15
15
  export function MemberLoginCtaCard(props: {
@@ -2,7 +2,7 @@
2
2
  * 图片 + 加载失败占位(0.4.0 D6:模块自持 ~20 行,禁跨模块依赖/基元封顶不破)。
3
3
  * 源:POC shopping-guide 占位语义。src 缺省或加载失败 → 图标占位。
4
4
  */
5
- import { useState } from 'react';
5
+ import { useEffect, useState } from 'react';
6
6
  import type { ReactNode } from 'react';
7
7
  import { ImageSquare } from '@phosphor-icons/react';
8
8
 
@@ -18,6 +18,7 @@ export function ImageWithFallback(props: {
18
18
  }) {
19
19
  const { src, alt, className, size = 40, loading = 'lazy', fallback } = props;
20
20
  const [failed, setFailed] = useState(false);
21
+ useEffect(() => setFailed(false), [src]);
21
22
  if (!src || failed) {
22
23
  return (
23
24
  <div className={`img-fallback ${className ?? ''}`.trim()} aria-label={alt} role="img">
@@ -4,7 +4,7 @@
4
4
  import './styles/member.css'; // 0.4.0 D1:模块自持 CSS(副作用 import,首行保证先行加载)
5
5
 
6
6
  import type { CardComponent } from '@tbox.cn/app-contracts';
7
- import type { ClientContext, ClientModule } from '@tbox.cn/app-sdk/client';
7
+ import type { ClientContext, ClientModule } from '@tbox.cn/app-agent-sdk-client';
8
8
  import {
9
9
  MemberInfoCard,
10
10
  MemberCardSummaryCard,
@@ -10,8 +10,8 @@
10
10
  * - member.query-enrollment-status:显式刷新(R4:POC 自动轮询不迁)
11
11
  */
12
12
  import { createHash } from 'node:crypto';
13
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
14
- import { createAlipayUserAuthorization, InMemoryIdempotencyStore } from '@tbox.cn/app-sdk/server';
13
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
14
+ import { createAlipayUserAuthorization, InMemoryIdempotencyStore } from '@tbox.cn/app-agent-sdk-server';
15
15
  import { parseMallScope } from '@tbox.cn/app-contracts-mall';
16
16
  import type { CardActionResult, RequestContext } from '@tbox.cn/app-contracts';
17
17
  import { z } from 'zod';
@@ -1,6 +1,6 @@
1
1
  import type { CardMeta } from '@tbox.cn/app-contracts';
2
2
  import { memberCardSummaryCardDataSchema } from '@tbox.cn/app-contracts-mall';
3
- import { samples } from './samples';
3
+ import { BLACK_CARD_IMAGE, samples } from './samples';
4
4
 
5
5
  const meta: CardMeta<typeof memberCardSummaryCardDataSchema> = {
6
6
  cardType: 'member-card-summary',
@@ -10,12 +10,12 @@ const meta: CardMeta<typeof memberCardSummaryCardDataSchema> = {
10
10
  sampleData: {
11
11
  userId: 'u_1001',
12
12
  cardRef: 'card:u_1001',
13
- cardDisplay: '金卡会员',
13
+ cardDisplay: '黑卡会员',
14
14
  status: 'active',
15
15
  availablePoints: 860,
16
- cardImageUrl: 'https://assets.example.com/member/gold-card.png',
16
+ cardImageUrl: BLACK_CARD_IMAGE,
17
17
  pointsRuleImageUrl: 'https://assets.example.com/member/points-rule.jpg',
18
- presentation: { variant: 'gold', labelsEmbedded: true },
18
+ presentation: { variant: 'black', labelsEmbedded: true },
19
19
  progress: {
20
20
  daySpentCents: 12_345,
21
21
  yearSpentCents: 500_000,
@@ -7,17 +7,21 @@
7
7
  * - 视觉等价的输入合并为一格,note 列全合并口径;
8
8
  * - 样本即契约:data 必须 dataSchema 校验通过且无 shape 外键(tests/samples.test.ts 双断言)。
9
9
  *
10
- * 素材中立化(画廊时期权益图标指向厂商 CDN,模块样本按仓库铁律净化):
11
- * - 卡面底图/积分规则长图:无网络依赖的内联 SVG data URI(画廊原实现随行);
10
+ * 素材边界(规范真源 = 厂商中立门禁:禁厂商租户字样/标识/深链——平台 CDN 演示素材不在禁列):
11
+ * - 卡面底图:平台 CDN 演示素材(mdn.alipayobjects.com,预览/截图保真)。样本只服务预览,
12
+ * 运行时素材恒由 provider 下发(mock 发 dynamic face 与真实厂商集成同构,见 provider-mock
13
+ * member);silver 档保留内联 SVG 作「无外部素材占位」分支;
12
14
  * - 权益图标:内联 SVG 按变体分色——验证的是「图标配色压不压得住卡面底色」与四列网格
13
15
  * 换行(低两档 14 项、高两档 15 项的数量差异照实铺),不是图标的图案还原度
14
16
  * (真实图标由 provider 运行时下发;图案语义兜底归组件内 ImageWithFallback);
15
- * - 卡图/图标的外链失败分支刻意保留 example.com 占位(该分支本身是合法预览态)。
17
+ * - 卡图/图标的外链失败分支刻意保留 example.com 占位(该分支本身是合法预览态);
18
+ * - 白名单由 tests/samples.test.ts 断言收口:卡面 URL 仅允许 mdn.alipayobjects.com /
19
+ * example.com / data:image/svg+xml,厂商租户素材回潜即 fail。
16
20
  */
17
21
  import type { CardSample } from '@tbox.cn/app-contracts';
18
22
  import type { MemberCardSummaryCardData } from '@tbox.cn/app-contracts-mall';
19
23
 
20
- /** 卡面底图:底色随 variant 走(前三档浅底深字、black 深底浅字——与模块 CSS 叠字色配对) */
24
+ /** 内联卡面底图:银/金档占位(浅底深字,与模块叠字配色配对)。 */
21
25
  function cardFace(from: string, to: string): string {
22
26
  // 真实卡图恒自带卡名与「我的积分」字样(labelsEmbedded 恒 true),前端只叠积分数字。
23
27
  // 两块半透明色块代表那两行字的占位——不写真文字是为了不依赖 SVG 内的中文字体,
@@ -36,11 +40,16 @@ function cardFace(from: string, to: string): string {
36
40
  + '</svg>';
37
41
  }
38
42
 
43
+ export const BLACK_CARD_IMAGE
44
+ = 'https://mdn.alipayobjects.com/huamei_b00jk5/afts/img/A*sdTfQ5NaRN8AAAAAgEAAAAgAegitAQ/fmt.webp';
45
+
39
46
  const FACE = {
40
- blue: cardFace('dce8fb', 'aecdf5'),
47
+ blue: 'https://mdn.alipayobjects.com/huamei_b00jk5/afts/img/A*OVn3SL73QbQAAAAAgDAAAAgAegitAQ/fmt.webp',
41
48
  silver: cardFace('eef1f7', 'c4cddf'),
49
+ // gold 配浅金 SVG:恢复真实厂商世代叠字后金卡是浅底深字,黑金深图配金档=深字压深底不可读;
50
+ // 待世代规格(1344×694+透明边)浅金素材重制后再换平台 CDN 图。
42
51
  gold: cardFace('f9ecca', 'e3c283'),
43
- black: cardFace('1b1e26', '4a412c'),
52
+ black: BLACK_CARD_IMAGE,
44
53
  };
45
54
 
46
55
  /** 积分规则长图占位(弹层内容):只需一张有高度的图验证弹层滚动与关闭 */
@@ -5,7 +5,7 @@
5
5
  * - 上下文统一化:userId 来源 = 运行身份(reqCtx.identity.userId,handler 第四参)——
6
6
  * 旧 payload.userId 是模型注入面(P4-3),已删除;偏好分支同经 reqCtx 显式读取。
7
7
  */
8
- import type { HandlerDefinition, ServerContext } from '@tbox.cn/app-sdk/server';
8
+ import type { HandlerDefinition, ServerContext } from '@tbox.cn/app-agent-sdk-server';
9
9
  import {
10
10
  MEMBER_PREFERENCE_PROMPTS,
11
11
  MEMBER_PREFERENCE_RECOMMENDATION_QUERIES,
@@ -1,5 +1,5 @@
1
- import type { ServerContext, ServerModule } from '@tbox.cn/app-sdk/server';
2
- import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from '@tbox.cn/app-sdk/server';
1
+ import type { ServerContext, ServerModule } from '@tbox.cn/app-agent-sdk-server';
2
+ import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from '@tbox.cn/app-agent-sdk-server';
3
3
  import type { RequestContext } from '@tbox.cn/app-contracts';
4
4
  import { MEMBER_SNAPSHOT_SERVICE, type MemberSnapshotPort } from '@tbox.cn/app-contracts-mall';
5
5
  import memberInfoMeta from './cards/member-info/meta';
@@ -21,7 +21,7 @@ import {
21
21
  } from '@tbox.cn/app-contracts-mall';
22
22
  import { mallScopeOf } from '@tbox.cn/app-contracts-mall';
23
23
  import type { RequestContext } from '@tbox.cn/app-contracts';
24
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
24
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
25
25
 
26
26
  /** account 槽产物类型视图:Port + 厂商实例携带的登录深链(可选) */
27
27
  export type MemberAccountService = MemberAccountPort & { readonly loginUrl?: string };
@@ -9,7 +9,7 @@ import type {
9
9
  } from '@tbox.cn/app-contracts-mall';
10
10
  import { classifyMemberOutcome } from '@tbox.cn/app-contracts-mall';
11
11
  import type { RequestContext } from '@tbox.cn/app-contracts';
12
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
12
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
13
13
  import { resolveMemberAccountPort, resolveMemberEnrollmentPort } from './ports';
14
14
 
15
15
  /** 模块内超集(跨模块窄面 = 契约 MemberStatusResolution)。
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { SubjectBindingPort } from '@tbox.cn/app-contracts-mall';
8
8
  import { createHash } from 'node:crypto';
9
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
9
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
10
10
 
11
11
  export function createSubjectBinding(ctx: ServerContext): SubjectBindingPort {
12
12
  return {
@@ -1,6 +1,6 @@
1
- import { createTool } from '@tbox.cn/app-sdk/server';
2
- import type { AnyTool, ToolExecContextLike } from '@tbox.cn/app-sdk/server';
3
- import { requireToolRequestContext } from '@tbox.cn/app-sdk/server';
1
+ import { createTool } from '@tbox.cn/app-agent-sdk-server';
2
+ import type { AnyTool, ToolExecContextLike } from '@tbox.cn/app-agent-sdk-server';
3
+ import { requireToolRequestContext } from '@tbox.cn/app-agent-sdk-server';
4
4
  import type { RequestContext } from '@tbox.cn/app-contracts';
5
5
  import { MEMBER_PREFERENCE_PROMPTS } from '@tbox.cn/app-contracts-mall';
6
6
  import type { MemberAccountSnapshot, MemberCardPort } from '@tbox.cn/app-contracts-mall';
package/tbox.module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "name": "module-member",
4
- "title": "会员积分",
3
+ "id": "module-member",
4
+ "name": "会员积分",
5
5
  "description": "会员信息与会员卡、积分余额与流水、入会引导(两步授权)",
6
6
  "version": "0.3.0",
7
7
  "kind": "business",
@@ -12,7 +12,16 @@
12
12
  "distribution": {
13
13
  "defaultMode": "codegen"
14
14
  },
15
- "contributes": {
15
+ "dependencies": {
16
+ "modules": [
17
+ {
18
+ "id": "contracts-mall",
19
+ "required": true
20
+ }
21
+ ]
22
+ },
23
+ "env": [],
24
+ "declare": {
16
25
  "handlers": [
17
26
  "member"
18
27
  ],
@@ -61,7 +70,7 @@
61
70
  "member.enroll",
62
71
  "member.query-enrollment-status"
63
72
  ],
64
- "services": [
73
+ "consumes": [
65
74
  {
66
75
  "service": "member.account",
67
76
  "optional": false,
@@ -112,15 +121,26 @@
112
121
  }
113
122
  ]
114
123
  }
115
- ]
116
- },
117
- "dependencies": {
118
- "modules": [
124
+ ],
125
+ "owns": [
119
126
  {
120
- "id": "contracts-mall",
121
- "required": true
127
+ "service": "member.account"
128
+ },
129
+ {
130
+ "service": "member.profile"
131
+ },
132
+ {
133
+ "service": "member.card"
134
+ },
135
+ {
136
+ "service": "member.benefits"
137
+ },
138
+ {
139
+ "service": "member.enrollment"
140
+ },
141
+ {
142
+ "service": "member.snapshot"
122
143
  }
123
144
  ]
124
- },
125
- "env": []
145
+ }
126
146
  }
@@ -6,7 +6,7 @@
6
6
  import { describe, expect, it, vi, beforeEach } from 'vitest';
7
7
  import { createRoot } from 'react-dom/client';
8
8
  import { act } from 'react-dom/test-utils';
9
- import { sendCardAction } from '@tbox.cn/app-sdk/client';
9
+ import { sendCardAction } from '@tbox.cn/app-agent-sdk-client';
10
10
  import {
11
11
  MemberCardSummaryCard,
12
12
  MemberEnrollmentCtaCard,
@@ -20,8 +20,8 @@ import MemberCardSummaryCardDefault from '../src/client/cards/member-card-summar
20
20
  import MemberEnrollmentFormCardDefault from '../src/client/cards/member-enrollment-form';
21
21
  import MemberEnrollmentStatusCardDefault from '../src/client/cards/member-enrollment-status';
22
22
 
23
- vi.mock('@tbox.cn/app-sdk/client', async (importOriginal) => {
24
- const mod = await importOriginal<typeof import('@tbox.cn/app-sdk/client')>();
23
+ vi.mock('@tbox.cn/app-agent-sdk-client', async (importOriginal) => {
24
+ const mod = await importOriginal<typeof import('@tbox.cn/app-agent-sdk-client')>();
25
25
  return { ...mod, sendCardAction: vi.fn() };
26
26
  });
27
27
 
@@ -3,7 +3,7 @@
3
3
  * 覆盖:授权成功预填 / 授权降级 manual / PII TTL 与用后即删(F2)/ 幂等重入 / pending 刷新收口(R4)。
4
4
  */
5
5
  import { describe, expect, it } from 'vitest';
6
- import { createInMemoryStateStore } from '@tbox.cn/app-sdk/server';
6
+ import { createInMemoryStateStore } from '@tbox.cn/app-agent-sdk-server';
7
7
  import {
8
8
  createMemberActions,
9
9
  MEMBER_PROFILE_NAMESPACE,
@@ -7,8 +7,8 @@
7
7
  */
8
8
  import { describe, expect, it, vi } from 'vitest';
9
9
  import type { RequestContext } from '@tbox.cn/app-contracts';
10
- import { createServerContext } from '@tbox.cn/app-sdk/server';
11
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
10
+ import { createServerContext } from '@tbox.cn/app-agent-sdk-server';
11
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
12
12
  import {
13
13
  resolveMemberAccountPort,
14
14
  resolveMemberBenefitsPort,
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { createInMemoryMemoryStore, createServerContext } from '@tbox.cn/app-sdk/server';
2
+ import { createInMemoryMemoryStore, createServerContext } from '@tbox.cn/app-agent-sdk-server';
3
3
  import { createMemberHandler } from '../src/server/handler';
4
4
 
5
5
  /** 上下文统一化:显式缝——reqCtx 由调用方透传(handle 第四参) */
@@ -7,7 +7,7 @@
7
7
  * 主动交互——样本只描述状态,不描述动作)。
8
8
  */
9
9
  import { describe, expect, it } from 'vitest';
10
- import { findSampleShapeViolations } from '@tbox.cn/app-sdk/server';
10
+ import { findSampleShapeViolations } from '@tbox.cn/app-agent-sdk-server';
11
11
  import meta from '../src/server/cards/member-card-summary/meta';
12
12
 
13
13
  describe('member samples 双断言(样本即契约)', () => {
@@ -44,6 +44,25 @@ describe('member samples 双断言(样本即契约)', () => {
44
44
  expect(Math.min(...counts.filter((n) => n >= 10))).toBe(14);
45
45
  });
46
46
 
47
+ it('卡面素材白名单:平台 CDN 演示素材 / example.com 失败分支 / 内联 SVG(厂商租户素材回潜即 fail)', () => {
48
+ const allowed = (url: string) =>
49
+ url.startsWith('https://mdn.alipayobjects.com/')
50
+ || url.startsWith('https://assets.example.com/')
51
+ || url.startsWith('data:image/svg+xml');
52
+ for (const s of meta.samples ?? []) {
53
+ const url = (s.data as { cardImageUrl?: string }).cardImageUrl;
54
+ if (url) expect(allowed(url), s.label).toBe(true);
55
+ }
56
+ const initial = (meta.sampleData as { cardImageUrl?: string }).cardImageUrl;
57
+ if (initial) expect(allowed(initial), '初始态').toBe(true);
58
+ });
59
+
60
+ it('初始态深卡配对:black 变体配深底卡图(恢复真实厂商世代叠字后浅金字压深底可读)', () => {
61
+ const data = meta.sampleData as { presentation?: { variant?: string }; cardImageUrl?: string };
62
+ expect(data.presentation?.variant).toBe('black');
63
+ expect(data.cardImageUrl).toMatch(/^https:\/\/mdn\.alipayobjects\.com\//);
64
+ });
65
+
47
66
  it('素材中立:权益图标全部为内联 SVG 分色占位或 example.com 占位', () => {
48
67
  const serialized = JSON.stringify(meta.samples ?? []);
49
68
  expect(serialized).toContain('data:image/svg+xml');
@@ -21,8 +21,8 @@ import {
21
21
  createEnvironmentSecretProvider,
22
22
  createServerContext,
23
23
  createToolExecContext,
24
- } from '@tbox.cn/app-sdk/server';
25
- import type { ToolExecContextLike, ServerContext } from '@tbox.cn/app-sdk/server';
24
+ } from '@tbox.cn/app-agent-sdk-server';
25
+ import type { ToolExecContextLike, ServerContext } from '@tbox.cn/app-agent-sdk-server';
26
26
  import type { MemberAccountPort, MemberBenefitsFactory, MemberStatusFactory } from '@tbox.cn/app-contracts-mall';
27
27
  import type { MemberService } from '../src/server/service';
28
28
  import { serverModule } from '../src/server/index';
@@ -18,7 +18,7 @@ vi.mock('../src/server/ports', async (importOriginal) => {
18
18
  import type { RequestContext } from '@tbox.cn/app-contracts';
19
19
  import type { MemberSnapshotPort } from '@tbox.cn/app-contracts-mall';
20
20
  import { MEMBER_SNAPSHOT_SERVICE } from '@tbox.cn/app-contracts-mall';
21
- import { createServerContext } from '@tbox.cn/app-sdk/server';
21
+ import { createServerContext } from '@tbox.cn/app-agent-sdk-server';
22
22
  import { serverModule } from '../src/server/index';
23
23
  import {
24
24
  resolveMemberAccountPort,
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { describe, expect, it, vi } from 'vitest';
6
6
  import type { RequestContext } from '@tbox.cn/app-contracts';
7
- import type { ServerContext } from '@tbox.cn/app-sdk/server';
7
+ import type { ServerContext } from '@tbox.cn/app-agent-sdk-server';
8
8
  import { resolveMemberStatus, MEMBER_QUERY_NOTICES } from '../src/server/status';
9
9
 
10
10
  const reqCtx = (source: 'local' | 'anonymous' = 'local'): RequestContext =>
package/tsup.config.ts CHANGED
@@ -16,7 +16,8 @@ export default defineConfig({
16
16
  // 声明产物一次性构建无需增量——仅 dts 关闭,typecheck 的增量缓存不受影响。
17
17
  dts: { compilerOptions: { incremental: false } },
18
18
  external: [
19
- '@tbox.cn/app-sdk',
19
+ '@tbox.cn/app-agent-sdk-client',
20
+ '@tbox.cn/app-agent-sdk-server',
20
21
  '@tbox.cn/app-contracts',
21
22
  '@tbox.cn/app-contracts-mall',
22
23
  'react',