feat(account): map iteration review reminders
This commit is contained in:
parent
8594d8eef7
commit
8cc0cd9e78
|
|
@ -10,7 +10,8 @@ export type AccountPostReleaseNotificationEvent =
|
||||||
| "feedback_received"
|
| "feedback_received"
|
||||||
| "revenue_signal"
|
| "revenue_signal"
|
||||||
| "compliance_blocked"
|
| "compliance_blocked"
|
||||||
| "iteration_recommendation";
|
| "iteration_recommendation"
|
||||||
|
| "next_change_review";
|
||||||
export type AccountReleaseNotificationEvent =
|
export type AccountReleaseNotificationEvent =
|
||||||
| "release_gate_blocked"
|
| "release_gate_blocked"
|
||||||
| "release_gate_ready"
|
| "release_gate_ready"
|
||||||
|
|
@ -67,7 +68,7 @@ export interface AccountReleaseGateNotificationPreference {
|
||||||
export interface AccountPostReleaseNotificationPreference {
|
export interface AccountPostReleaseNotificationPreference {
|
||||||
event: AccountPostReleaseNotificationEvent;
|
event: AccountPostReleaseNotificationEvent;
|
||||||
notificationKey: AccountNotificationKey;
|
notificationKey: AccountNotificationKey;
|
||||||
surface: "release_growth";
|
surface: "release_growth" | "change_review";
|
||||||
spaceReadable: boolean;
|
spaceReadable: boolean;
|
||||||
inAppEnabled: boolean;
|
inAppEnabled: boolean;
|
||||||
showInAppReminder: boolean;
|
showInAppReminder: boolean;
|
||||||
|
|
@ -188,24 +189,33 @@ const releaseNotificationEventMeta: Record<
|
||||||
|
|
||||||
const postReleaseNotificationEventMeta: Record<
|
const postReleaseNotificationEventMeta: Record<
|
||||||
AccountPostReleaseNotificationEvent,
|
AccountPostReleaseNotificationEvent,
|
||||||
{ notificationKey: AccountNotificationKey; reason: string }
|
{ notificationKey: AccountNotificationKey; surface: "release_growth" | "change_review"; reason: string }
|
||||||
> = {
|
> = {
|
||||||
feedback_received: {
|
feedback_received: {
|
||||||
notificationKey: "releaseGate",
|
notificationKey: "releaseGate",
|
||||||
|
surface: "release_growth",
|
||||||
reason: "Release/Growth 收到发布后用户反馈时使用发布门禁偏好控制页面内提醒;反馈证据本身不受偏好隐藏。",
|
reason: "Release/Growth 收到发布后用户反馈时使用发布门禁偏好控制页面内提醒;反馈证据本身不受偏好隐藏。",
|
||||||
},
|
},
|
||||||
revenue_signal: {
|
revenue_signal: {
|
||||||
notificationKey: "releaseGate",
|
notificationKey: "releaseGate",
|
||||||
|
surface: "release_growth",
|
||||||
reason: "Release/Growth 收到收入、转化或增长信号时使用发布门禁偏好控制页面内提醒;收入证据本身不受偏好隐藏。",
|
reason: "Release/Growth 收到收入、转化或增长信号时使用发布门禁偏好控制页面内提醒;收入证据本身不受偏好隐藏。",
|
||||||
},
|
},
|
||||||
compliance_blocked: {
|
compliance_blocked: {
|
||||||
notificationKey: "releaseGate",
|
notificationKey: "releaseGate",
|
||||||
|
surface: "release_growth",
|
||||||
reason: "合规、风控或发布后审核阻塞下一步时使用发布门禁偏好控制页面内提醒;阻塞状态与证据仍必须展示在业务页面。",
|
reason: "合规、风控或发布后审核阻塞下一步时使用发布门禁偏好控制页面内提醒;阻塞状态与证据仍必须展示在业务页面。",
|
||||||
},
|
},
|
||||||
iteration_recommendation: {
|
iteration_recommendation: {
|
||||||
notificationKey: "pendingConfirmation",
|
notificationKey: "pendingConfirmation",
|
||||||
|
surface: "change_review",
|
||||||
reason: "AI 生成下一轮迭代建议、需要人类拍板时使用待确认偏好控制页面内提醒;建议对象和证据仍保留。",
|
reason: "AI 生成下一轮迭代建议、需要人类拍板时使用待确认偏好控制页面内提醒;建议对象和证据仍保留。",
|
||||||
},
|
},
|
||||||
|
next_change_review: {
|
||||||
|
notificationKey: "pendingConfirmation",
|
||||||
|
surface: "change_review",
|
||||||
|
reason: "下一轮 Change Review 或 ChangeSet 待审需要人类拍板时使用待确认偏好控制页面内提醒;ChangeSet 与 recommendation 不受偏好隐藏。",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createDefaultAccountSettings(seed: AccountSettingsSeed = {}): AccountSettings {
|
export function createDefaultAccountSettings(seed: AccountSettingsSeed = {}): AccountSettings {
|
||||||
|
|
@ -357,7 +367,7 @@ export function getPostReleaseNotificationPreference(
|
||||||
return {
|
return {
|
||||||
event,
|
event,
|
||||||
notificationKey: meta.notificationKey,
|
notificationKey: meta.notificationKey,
|
||||||
surface: "release_growth",
|
surface: meta.surface,
|
||||||
spaceReadable: true,
|
spaceReadable: true,
|
||||||
inAppEnabled: enabled,
|
inAppEnabled: enabled,
|
||||||
showInAppReminder: enabled,
|
showInAppReminder: enabled,
|
||||||
|
|
@ -369,7 +379,7 @@ export function getPostReleaseNotificationPreference(
|
||||||
reminderPolicy: "page_reminder_only",
|
reminderPolicy: "page_reminder_only",
|
||||||
mutedDetail: enabled
|
mutedDetail: enabled
|
||||||
? "Release/Growth 或 Space 可显示页面内提醒;桌面/邮件只记录偏好,不代表系统级推送已接入。"
|
? "Release/Growth 或 Space 可显示页面内提醒;桌面/邮件只记录偏好,不代表系统级推送已接入。"
|
||||||
: "仅静默页面内提醒;反馈、收入、合规、迭代建议及其证据仍必须按业务页面展示。",
|
: "仅静默页面内提醒;反馈、收入、合规、ChangeSet、迭代建议及其证据仍必须按业务页面展示。",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ describe("account settings api", () => {
|
||||||
const revenue = getPostReleaseNotificationPreference(settings, "revenue_signal");
|
const revenue = getPostReleaseNotificationPreference(settings, "revenue_signal");
|
||||||
const compliance = getPostReleaseNotificationPreference(settings, "compliance_blocked");
|
const compliance = getPostReleaseNotificationPreference(settings, "compliance_blocked");
|
||||||
const iteration = getPostReleaseNotificationPreference(settings, "iteration_recommendation");
|
const iteration = getPostReleaseNotificationPreference(settings, "iteration_recommendation");
|
||||||
|
const nextReview = getPostReleaseNotificationPreference(settings, "next_change_review");
|
||||||
|
|
||||||
expect(feedback.notificationKey).toBe("releaseGate");
|
expect(feedback.notificationKey).toBe("releaseGate");
|
||||||
expect(feedback.surface).toBe("release_growth");
|
expect(feedback.surface).toBe("release_growth");
|
||||||
|
|
@ -163,10 +164,16 @@ describe("account settings api", () => {
|
||||||
expect(compliance.notificationKey).toBe("releaseGate");
|
expect(compliance.notificationKey).toBe("releaseGate");
|
||||||
expect(compliance.reason).toContain("合规");
|
expect(compliance.reason).toContain("合规");
|
||||||
expect(iteration.notificationKey).toBe("pendingConfirmation");
|
expect(iteration.notificationKey).toBe("pendingConfirmation");
|
||||||
|
expect(iteration.surface).toBe("change_review");
|
||||||
expect(iteration.showInAppReminder).toBe(false);
|
expect(iteration.showInAppReminder).toBe(false);
|
||||||
expect(iteration.desktopPreference).toBe(false);
|
expect(iteration.desktopPreference).toBe(false);
|
||||||
expect(iteration.emailDigestPreference).toBe(false);
|
expect(iteration.emailDigestPreference).toBe(false);
|
||||||
expect(iteration.mutedDetail).toContain("证据仍必须");
|
expect(iteration.mutedDetail).toContain("证据仍必须");
|
||||||
|
expect(nextReview.notificationKey).toBe("pendingConfirmation");
|
||||||
|
expect(nextReview.surface).toBe("change_review");
|
||||||
|
expect(nextReview.showInAppReminder).toBe(false);
|
||||||
|
expect(nextReview.reason).toContain("ChangeSet");
|
||||||
|
expect(nextReview.mutedDetail).toContain("ChangeSet");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("falls back missing notification fields to safe defaults", async () => {
|
it("falls back missing notification fields to safe defaults", async () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue