fix(p21-2e): 红娘服务拦截接线(blocker 首次生效 + 竞态兜底);2d 确认 Onboarding 本地资格已实现;文档回写
P16 遗留 2e(红娘服务拦截): - checkCanWithdraw 硬编码 0 → 接 MatchmakerServiceMapper.countActiveByUserId(非终态口径 submitted/assigned/in_service/waiting_user,与 findActiveByOperatorAndUser 一致),blocker 首次真正生效 - notifyMatchmaker TODO 空转 → terminateActiveMatchmakerServices 竞态兜底(残留非终态置 cancelled); 不发通知:Phase 18 D2 的 notifications.user_id→users(id) FK 教训 - 守卫 MatchmakerWithdrawBlockerGuardTest 4 用例全绿;首跑暴露测试基建坑:@Transactional Service 是 CGLIB 代理,ReflectionTestUtils 直调私有方法拿到的是代理实例的 null 字段 → 须先 AopTestUtils.getTargetObject 解包(已在测试内注释说明) - 另发现历史遗留:countInProgressByOperator 使用白名单外的 'processing'(已登记) P04-T10:复核确认 Onboarding 本地资格步骤早已实现(onboarding 消息/动作 + 路由 + /me/status 字段), JIRA ⏳ → ✅;清除首页语义错位的死状态 isVerified(miniapp tsc EXIT=0) 文档:JIRA 收尾行/计划文档 Task 3.1/3.3 勾选
This commit is contained in:
+33
-8
@@ -85,6 +85,7 @@ public class AccountLifecycleService {
|
||||
private final ChatService chatService;
|
||||
private final UserIdentityMapper userIdentityMapper;
|
||||
private final CounselingFollowupMapper counselingFollowupMapper;
|
||||
private final com.danyang.match.platform.matchmaker.mapper.MatchmakerServiceMapper matchmakerServiceMapper;
|
||||
|
||||
// ==================== 退出婚恋服务(暂停推荐) ====================
|
||||
|
||||
@@ -166,8 +167,9 @@ public class AccountLifecycleService {
|
||||
|
||||
Map<String, Object> blockers = new HashMap<>();
|
||||
|
||||
// 检查是否有进行中的红娘服务
|
||||
long activeMatchmakerServices = 0; // 需要 MatchmakerServiceMapper
|
||||
// 检查是否有进行中的红娘服务(2e 接线:原硬编码 0,blocker 从未生效)。
|
||||
// 状态口径 = 生产 chk_matchmaker_status 白名单的非终态值(submitted/assigned/in_service/waiting_user)。
|
||||
long activeMatchmakerServices = matchmakerServiceMapper.countActiveByUserId(userId);
|
||||
if (activeMatchmakerServices > 0) {
|
||||
blockers.put("matchmakerService", "您有进行中的红娘服务,请先完成或取消");
|
||||
}
|
||||
@@ -270,8 +272,8 @@ public class AccountLifecycleService {
|
||||
// 2b. 通知所有活跃 Match 对方
|
||||
notifyActiveMatches(user.getId(), "account_closed");
|
||||
|
||||
// 2c. 通知红娘(如果有)
|
||||
notifyMatchmaker(user.getId());
|
||||
// 2c. 终止残留红娘服务(竞态兜底,见方法注释;不能向 operator 发通知——Phase 18 D2 FK 教训)
|
||||
terminateActiveMatchmakerServices(user.getId());
|
||||
|
||||
// 2d. 取消所有未开始的活动报名
|
||||
cancelPendingActivityRegistrations(userId);
|
||||
@@ -425,11 +427,34 @@ public class AccountLifecycleService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知红娘服务已终止
|
||||
* 注销收尾(2e 接线,原 {@code notifyMatchmaker} 为 TODO 空转):把该用户残留的非终态
|
||||
* 红娘服务置为 cancelled。
|
||||
*
|
||||
* <p>正常路径下 {@code checkCanWithdraw} 的 blocker 会要求用户先完成/取消红娘服务,
|
||||
* 走到注销时不应再有非终态记录 —— 本方法是<b>竞态兜底</b>(blocker 检查与注销事务之间,
|
||||
* 红娘管理员恰好受理了新服务)。
|
||||
*
|
||||
* <p><b>为什么不是「发通知」</b>:Phase 18 D2 的教训 —— {@code notifications.user_id → users(id)}
|
||||
* 外键下,operator 不在 users 表,向红娘发用户通知在真实 PG 上必然使注销事务回滚。
|
||||
* 因此以状态收尾 + 日志代替「通知」,效果更实质且不会炸注销事务。
|
||||
*/
|
||||
private void notifyMatchmaker(String userId) {
|
||||
// TODO: 查询该用户的红娘服务,通知相关红娘
|
||||
log.info("通知红娘服务终止: userId={}", userId);
|
||||
private void terminateActiveMatchmakerServices(String userId) {
|
||||
List<com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord> active =
|
||||
matchmakerServiceMapper.selectList(
|
||||
new LambdaQueryWrapper<com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord>()
|
||||
.eq(com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord::getUserId, userId)
|
||||
.in(com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord::getStatus,
|
||||
Constants.MATCHMAKER_STATUS_SUBMITTED,
|
||||
Constants.MATCHMAKER_STATUS_ASSIGNED,
|
||||
Constants.MATCHMAKER_STATUS_IN_SERVICE,
|
||||
Constants.MATCHMAKER_STATUS_WAITING_USER)
|
||||
.isNull(com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord::getDeletedAt));
|
||||
for (com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord svc : active) {
|
||||
svc.setStatus(Constants.MATCHMAKER_STATUS_CANCELLED);
|
||||
svc.setUpdatedAt(Instant.now());
|
||||
matchmakerServiceMapper.updateById(svc);
|
||||
log.info("注销收尾: 残留红娘服务已终止 userId={}, serviceId={}", userId, svc.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+10
@@ -51,4 +51,14 @@ public interface MatchmakerServiceMapper extends BaseMapper<MatchmakerServiceRec
|
||||
"AND deleted_at IS NULL ORDER BY created_at DESC LIMIT 1")
|
||||
Optional<MatchmakerServiceRecord> findActiveByOperatorAndUser(@Param("operatorId") String operatorId,
|
||||
@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 注销前检查(P16 收尾 2e):该用户仍处于非终态的红娘服务数。
|
||||
* 状态口径与 {@link #findActiveByOperatorAndUser} 一致(submitted/assigned/in_service/waiting_user)。
|
||||
* ⚠️ 勿用 {@code Constants.MATCHMAKER_STATUS_PENDING} / {@code IN_PROGRESS} ——
|
||||
* 这两个常量不在生产 chk_matchmaker_status 白名单(V009),该表永不出现这两个值。
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM matchmaker_services WHERE user_id = #{userId} " +
|
||||
"AND status IN ('submitted','assigned','in_service','waiting_user') AND deleted_at IS NULL")
|
||||
long countActiveByUserId(@Param("userId") String userId);
|
||||
}
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package com.danyang.match.platform.account;
|
||||
|
||||
import com.danyang.match.platform.account.service.AccountLifecycleService;
|
||||
import com.danyang.match.platform.matchmaker.entity.MatchmakerServiceRecord;
|
||||
import com.danyang.match.platform.matchmaker.mapper.MatchmakerServiceMapper;
|
||||
import com.danyang.match.platform.shared.constant.Constants;
|
||||
import com.danyang.match.platform.user.entity.User;
|
||||
import com.danyang.match.platform.user.mapper.UserMapper;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.util.AopTestUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* 2e 守卫(Phase 21 遗留清偿):注销前红娘服务拦截 + 注销竞态兜底。
|
||||
*
|
||||
* <h3>缺陷本体</h3>
|
||||
* {@code checkCanWithdraw} 曾把进行中红娘服务数**硬编码为 0** —— blocker 从未生效,
|
||||
* 有进行中红娘服务的用户可以直接注销,红娘工作台留下永不终结的孤儿服务。
|
||||
* 原因注释写「需要 MatchmakerServiceMapper」,但该 Mapper 与 {@code matchmaker_services} 表
|
||||
* (V009)其实一直都在 —— 原 STATUS「数据模型无该表」的判定已被实测推翻。
|
||||
*
|
||||
* <h3>覆盖</h3>
|
||||
* <ol>
|
||||
* <li>blocker 接线:有非终态红娘服务(in_service)→ 注销被拦;</li>
|
||||
* <li>无红娘服务 → 不产生该 blocker;</li>
|
||||
* <li>竞态兜底:{@code terminateActiveMatchmakerServices} 把残留非终态服务置为 cancelled
|
||||
* (方法为 private,用 ReflectionTestUtils 直调,与 {@code AuthServiceAccountClosedGuardTest}
|
||||
* 同模式 —— 注销主流程被 blocker 挡住,正常路径到不了这里)。</li>
|
||||
* </ol>
|
||||
*/
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@Transactional
|
||||
class MatchmakerWithdrawBlockerGuardTest {
|
||||
|
||||
@Autowired private AccountLifecycleService accountLifecycleService;
|
||||
@Autowired private UserMapper userMapper;
|
||||
@Autowired private MatchmakerServiceMapper matchmakerServiceMapper;
|
||||
|
||||
private User newUser() {
|
||||
User user = new User();
|
||||
user.setId(UUID.randomUUID().toString());
|
||||
user.setWechatOpenid("openid-" + UUID.randomUUID());
|
||||
user.setAccountStatus("normal");
|
||||
userMapper.insert(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
private MatchmakerServiceRecord insertService(String userId, String status) {
|
||||
MatchmakerServiceRecord svc = new MatchmakerServiceRecord();
|
||||
svc.setId(UUID.randomUUID().toString());
|
||||
svc.setUserId(userId);
|
||||
svc.setServiceType("recommend_partner");
|
||||
svc.setStatus(status);
|
||||
matchmakerServiceMapper.insert(svc);
|
||||
return svc;
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("blocker 接线:有进行中红娘服务的用户注销被拦(原硬编码 0,拦截从未生效)")
|
||||
void activeMatchmakerServiceBlocksWithdraw() {
|
||||
User user = newUser();
|
||||
insertService(user.getId(), Constants.MATCHMAKER_STATUS_IN_SERVICE);
|
||||
|
||||
Map<String, Object> result = accountLifecycleService.checkCanWithdraw(user.getId());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> blockers = (Map<String, Object>) result.get("blockers");
|
||||
|
||||
assertTrue(blockers.containsKey("matchmakerService"),
|
||||
"进行中红娘服务必须成为注销 blocker(P16 遗留 2e 缺陷本体)");
|
||||
assertEquals(false, result.get("canWithdraw"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("无红娘服务的用户:不产生 matchmakerService blocker")
|
||||
void noMatchmakerServiceNoBlocker() {
|
||||
User user = newUser();
|
||||
|
||||
Map<String, Object> result = accountLifecycleService.checkCanWithdraw(user.getId());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> blockers = (Map<String, Object>) result.get("blockers");
|
||||
|
||||
assertFalse(blockers.containsKey("matchmakerService"),
|
||||
"无红娘服务时不得误报该 blocker");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("已完成的红娘服务不拦截注销(终态不阻塞)")
|
||||
void completedServiceDoesNotBlock() {
|
||||
User user = newUser();
|
||||
insertService(user.getId(), Constants.MATCHMAKER_STATUS_COMPLETED);
|
||||
|
||||
Map<String, Object> result = accountLifecycleService.checkCanWithdraw(user.getId());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> blockers = (Map<String, Object>) result.get("blockers");
|
||||
|
||||
assertFalse(blockers.containsKey("matchmakerService"),
|
||||
"终态(completed)红娘服务不应拦截注销");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("竞态兜底:terminateActiveMatchmakerServices 把残留非终态服务置为 cancelled")
|
||||
void terminateResidualServicesOnClose() {
|
||||
User user = newUser();
|
||||
MatchmakerServiceRecord svc = insertService(user.getId(), Constants.MATCHMAKER_STATUS_ASSIGNED);
|
||||
|
||||
// ⚠️ 必须先解包 CGLIB 代理再反射调私有方法:该 Service 含 @Transactional 方法,
|
||||
// 注入的是代理实例 —— 代理对象自身字段全为 null(委托给 target),绕过拦截器直调
|
||||
// 私有方法会拿到 null 字段 NPE。直接调代理上的 public 方法(checkCanWithdraw)
|
||||
// 走拦截器委托 target,不受影响 —— 这也是本守卫首跑暴露的测试基建坑。
|
||||
Object target = AopTestUtils.getTargetObject(accountLifecycleService);
|
||||
ReflectionTestUtils.invokeMethod(target,
|
||||
"terminateActiveMatchmakerServices", user.getId());
|
||||
|
||||
MatchmakerServiceRecord after = matchmakerServiceMapper.selectById(svc.getId());
|
||||
assertEquals(Constants.MATCHMAKER_STATUS_CANCELLED, after.getStatus(),
|
||||
"注销收尾必须终止残留的非终态红娘服务(原 notifyMatchmaker 为 TODO 空转)");
|
||||
}
|
||||
}
|
||||
@@ -187,7 +187,7 @@
|
||||
| UI-CLEANUP-20260913 | 已完成 | 废弃 UI 代码、冲突规范、旧计划和无效验收证据已清理;`ui-document-baseline-contracts` 锁定唯一视觉入口 |
|
||||
| UI-ADMIN-20260913 | 已完成(待桌面端目视复验) | 管理端全局框架与工作台已按规格交付;18 modules + 22 routes,vue-tsc 与 vite build 全绿 |
|
||||
| UI-MINIAPP-20260913 | 已完成 | 小程序 11 个核心页面已重构;11/11 页 TS-only,2026-09-16 通过用户验收 |
|
||||
| 批 2/3 收尾(2026-09-19) | 进行中 | E2E 互选 8 + 预约 8 场景真实实现(本机 65 passed)+ INV-011 显式守卫完成;隐私设置接真实落库(V047)、5 死开关 + 2 私有桶死配置移除(产品裁定)、`PUT /feature-flags` 真持久化(V048)、5 个无 SQL Mapper 方法补齐——均已处置;剩余:红娘服务拦截接线(原「无表」判定已推翻,V009 已建表)、数据保留流程(待产品决策)、Task 3.3 四项(P16-T13 / P13A-T31 / P13A-T33 / P04-T10)、CI 全绿实测(需 GitHub Actions 环境) |
|
||||
| 批 2/3 收尾(2026-09-19) | 基本完成 | E2E 互选 8 + 预约 8 场景真实实现(本机 65 passed)+ INV-011 显式守卫;隐私设置接真实落库(V047)、5 死开关 + 2 死配置移除(产品裁定)、`PUT /feature-flags` 真持久化(V048)、5 个无 SQL Mapper 方法补齐;**Task 3.3 四项 + 红娘服务拦截接线全部完成**(互选 `expires_at` 写入接线、随访审计 `recordSensitiveAccess`、随访正文风险检测、Onboarding 本地资格确认已实现并回写;`checkCanWithdraw` 红娘 blocker 首次生效 + `terminateActiveMatchmakerServices` 竞态兜底);**仅余**:数据保留流程(待产品决策)、CI 全绿实测(需 GitHub Actions 环境)、E2E 场景对账表首项之外的 CI 复跑 |
|
||||
| V1.1 UAT / RC / Production | 进行中 | `/me/*` 契约已收敛(2026-09-16);当前停在 Phase 24(UAT)启动门前 —— 启动需用户确认,前置收尾见 `docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md` |
|
||||
|
||||
---
|
||||
@@ -305,7 +305,11 @@
|
||||
### Miniapp
|
||||
- P04-V11-T08 ✅ U62 本地资格说明页
|
||||
- P04-V11-T09 ✅ U63 本地资格补充核验页
|
||||
- P04-V11-T10 ⏳ Onboarding增加本地资格步骤(后续Phase)
|
||||
- P04-V11-T10 ✅ Onboarding 本地资格步骤 —— **2026-09-19 复核确认已实现**:首页 onboarding 消息/动作覆盖
|
||||
`not_declared` / `needs_evidence`,动作「声明本地资格」路由至 `/pages/local-eligibility/local-eligibility`
|
||||
(`pages/index/index.ts` buildOnboardingMessage / buildOnboardingActions / handleQuickAction),
|
||||
`eligStatus` 取自 `/me/status` 的 `localEligibilityStatus`(该字段断言守卫见 `MeStatusLocalEligibilityGuardTest`);
|
||||
同轮清除语义错位的死状态 `isVerified`(WXML/WXSS 零引用,实名判定是 `userState.verified`)
|
||||
|
||||
### MeStatus
|
||||
- P04-V11-T11 ✅ /me/status增加localEligibilityStatus
|
||||
|
||||
@@ -343,16 +343,18 @@
|
||||
- 负向注入:把桩退回「不落库」→ **恰 2 红**(落库用例 + 类型校验用例),
|
||||
其余 6 个正确未红。已还原。
|
||||
- 至此小程序隐私设置**真正可保存**,① ② 两层均已关闭。
|
||||
- [ ] **注销红娘服务拦截硬编码 `0`**:
|
||||
- [x] **注销红娘服务拦截硬编码 `0`** → **2026-09-19 已接线清偿**(守卫 `MatchmakerWithdrawBlockerGuardTest` 4 用例):
|
||||
原文断言「数据模型**没有 `matchmaker_services` 表**(全仓搜索为空),建表属扩权,需产品先确认」——
|
||||
**三条均与实况不符,2026-09-19 实测推翻**:
|
||||
① 表**存在**,由 `V009__add_matchmaker_tables.sql` 创建(`chk_matchmaker_status` 白名单:
|
||||
`submitted / assigned / in_service / waiting_user / completed / cancelled`);
|
||||
② `MatchmakerServiceMapper`、`MatchmakerServiceRecord`、`MatchmakerServiceService` **均已存在**;
|
||||
③ 因此**不需要扩权、不需要产品裁定**,属可直接实现的接线缺陷。
|
||||
另:`AccountLifecycleService.notifyMatchmaker`(注销时通知红娘服务)同样是 TODO 空转。
|
||||
位置:`AccountLifecycleService.checkCanWithdraw` 中
|
||||
`long activeMatchmakerServices = 0; // 需要 MatchmakerServiceMapper`。
|
||||
修复:`MatchmakerServiceMapper` 新增 `countActiveByUserId`(非终态口径与 `findActiveByOperatorAndUser` 一致),
|
||||
`checkCanWithdraw` 接真实计数(blocker 首次真正生效);原 `notifyMatchmaker` TODO 空转改为
|
||||
`terminateActiveMatchmakerServices`(竞态兜底:残留非终态服务置 cancelled;**不发通知**——
|
||||
Phase 18 D2 的 `notifications.user_id→users(id)` FK 教训)。
|
||||
另发现历史遗留:`countInProgressByOperator` 用了白名单外的 `'processing'`(已登记,另行处置)。
|
||||
(原文「全仓搜索为空」很可能是只在 `db/migration/` 内搜了表名的另一种写法 —— 该表在
|
||||
`demo-seed-*.sql` 与 `V009` 中都有;凡「全仓无 X」这类断言必须给出**搜索命令与范围**,
|
||||
否则无法复核,本项目已多次因此产生失实结论。)
|
||||
@@ -402,12 +404,13 @@
|
||||
`startupLoadHookIsDeclared`),`FeatureFlagControllerTest` 7 例不受影响;
|
||||
还原后 md5 逐字节一致、`NEG-VAL` 残留 0。
|
||||
|
||||
### Task 3.3: 任务级 ⏳ 清偿
|
||||
### Task 3.3: 任务级 ⏳ 清偿 ✅(2026-09-19 全部关闭)
|
||||
|
||||
- [ ] **P16-T13**:互选超时接线(`expires_at` 已由 V041 提供)。
|
||||
- [ ] **P13A-T31**:随访审计(`counseling_followups` 访问需审计)。
|
||||
- [ ] **P13A-T33**:`RiskEvent source=counseling` 来源扩展。
|
||||
- [ ] **P04-T10**:Onboarding 本地资格步骤。
|
||||
- [x] **P16-T13**:互选超时接线 → **缺陷本体**:`expires_at` 全仓无人写入(48h 配置在、confirm 过滤在,唯独创建不赋值 → 过滤恒真)。修复:创建时写 `expires_at` = 活动结束时间 + `ActivityConfig.mutualDeadlineHours`(已确认口径「截止后48小时」),缺失回退创建时刻。守卫 2 用例,负向验证(摘掉写入)恰 2 红。
|
||||
- [x] **P13A-T31**:随访审计 → `getDetailForCounselor` 接线 `recordSensitiveAccess(counseling_followup)`;本人/manager 摘要视图不审计。守卫含两个不审计分支断言。
|
||||
- [x] **P13A-T33**:`RiskEvent source=counseling` 来源扩展 → `detectCounselingRisk` 此前只扫申请摘要;`addFollowup` 正文接入同一检测(INV-013 加固:不记正文只记级别)。守卫含正常内容不误报断言。
|
||||
守卫:`CounselingFollowupAuditAndRiskGuardTest` 4 用例(真实落库回查),全绿。
|
||||
- [x] **P04-T10**:Onboarding 本地资格步骤 → **复核确认早已实现**(首页 onboarding 消息/动作覆盖 `not_declared`/`needs_evidence` 并路由本地资格页,`eligStatus` 取自 `/me/status.localEligibilityStatus`);JIRA 行滞后已回写 ✅;同轮清除语义错位的死状态 `isVerified`(`miniapp tsc` EXIT=0)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ Page({
|
||||
loadError: false,
|
||||
userState: null,
|
||||
isOnboarding: false,
|
||||
isVerified: false,
|
||||
isPaused: false,
|
||||
isSuccessful: false,
|
||||
onboardingMessage: '',
|
||||
@@ -112,7 +111,9 @@ Page({
|
||||
const isOnboarding = !userState || !userState.verified || (profileStatus !== 'approved' && profileStatus !== 'completed')
|
||||
const isPaused = relStatus === 'paused'
|
||||
const isSuccessful = relStatus === 'matched_successfully'
|
||||
const isVerified = eligStatus === 'verified'
|
||||
// 注意:本地资格核验通过与否由 checks 里的「本地资格」项表达(eligStatus === 'verified')。
|
||||
// 此前曾有一个 isVerified = eligStatus === 'verified' 的死状态 —— 名字像「实名」实为本地资格,
|
||||
// WXML/WXSS 零引用且语义错位(实名判定是 userState.verified),已移除以防未来误用。
|
||||
|
||||
const checks = [
|
||||
{ label: '已实名', done: userState?.verified || false },
|
||||
@@ -123,7 +124,7 @@ Page({
|
||||
this.setData({
|
||||
loading: false, loadError: false,
|
||||
userState,
|
||||
isOnboarding, isVerified, isPaused, isSuccessful,
|
||||
isOnboarding, isPaused, isSuccessful,
|
||||
onboardingMessage: this.buildOnboardingMessage(userState, profileStatus, eligStatus),
|
||||
onboardingActions: this.buildOnboardingActions(userState, profileStatus, eligStatus),
|
||||
statusChecks: checks,
|
||||
|
||||
Reference in New Issue
Block a user