Files
danyang-match/docs/superpowers/plans/2026-10-23-v12-account-lifecycle-matchmaker-dashboard.md
T
WorkBuddy 377429995c
CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Waiting to run
CI/CD Pipeline / Backend Build & Test (push) Waiting to run
CI/CD Pipeline / Admin Web Build (push) Waiting to run
CI/CD Pipeline / Mini Program Compile Check (push) Waiting to run
CI/CD Pipeline / Migration Validation (push) Blocked by required conditions
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Waiting to run
CI/CD Pipeline / E2E (live stack) (push) Blocked by required conditions
release: freeze V1.2 demo acceptance 2026-10-25
2026-10-25 14:29:29 +08:00

30 KiB
Raw Blame History

V1.2 账号生命周期、红娘分配与工作台实施计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 在保留 V1.1 核心业务和现有红娘分配权限的前提下,补齐 V1.2 的用户注册/建档/审核/账号发放/首次授权闭环,确保认证后的资料变更重新审核后才重新展示和匹配,并让普通红娘、红娘组长和管理员使用一致且不可越权的六项工作台统计。

Architecture: 继续使用 Spring Boot 模块化单体、PostgreSQL Source of Truth、Redis 只保存验证码/登录失败状态。用户账号生命周期、授权门禁、导入批次和红娘工作台范围分别建模;业务服务通过现有 CapabilityService、ServiceAssignmentPolicy 和 DataScopeGuard 接入,不重建权限体系。工作台采用一个服务端聚合接口,依据当前登录主体推导 scope,卡片和详情列表复用同一组查询条件。

Tech Stack: Java 21 / Spring Boot 3 / MyBatis-Plus / PostgreSQL / Redis / Flyway / Vue 3 / TypeScript / 微信原生小程序 / Maven / pnpm / Python pytest。

Spec: C:\Users\13070\.codex\attachments\155243ba-d394-45a0-b100-8c44baf9094d\已粘贴的文本.txt;审计基线:docs/audits/V1.2-现状审计与差距矩阵-2026-10-23.md(若该审计文件尚未写入,则以本计划中的审计结论为准)。

Global Constraints

  • 用户永久免费;不新增 VIP、会员、金币或收费路径。
  • PostgreSQL 是 Source of Truth;Redis 不保存业务状态,不覆盖数据库状态。
  • 所有权限范围由后端从认证主体、角色、组织和有效分配关系推导;不信任请求体中的 userId、matchmakerId、teamId 或角色字段。
  • 审核状态、账号状态、手机号核验、授权、服务资格、凭据发放必须独立存储,禁止合并为一个完成字段。
  • 用户完成实名认证后,任何个人资料变更都生成新版本并进入 pending_review;新版本审核通过前,不得在推荐、搜索、活动匹配、红娘推荐或其他用户可见资料中使用。
  • 资料重新审核期间,后端按“未通过审核”处理;不能只在前端隐藏,也不能继续使用未审核的新资料计算匹配。
  • 未确认的登录标识、密码发放渠道、授权正式文案、重复资料处理、自动分配算法和看板统计口径在 Gate 0 前不得进入业务代码。
  • 不重写 V001-V061;V1.2 新迁移从 V062 开始,所有迁移向前兼容已有数据。
  • 不增加第三方依赖;批量导入首版使用 UTF-8/UTF-8 BOM CSV,.xlsx 作为明确不支持格式返回可读错误。
  • Mock 短信/微信只能在显式测试或演示 profile 启用;生产配置不得把 Mock 验证当作真实核验。
  • 每个任务先写失败测试,再写最小实现;任务完成后输出阶段 Completion Report,不自动进入下一任务。
  • 任何外部短信、微信、生产数据库和真实用户 UAT 都不是本地测试的替代证据。

Gate 0:产品和数据决策冻结

Files:

  • Modify: docs/governance/open-questions.md
  • Modify: docs/governance/decision-register.md
  • Modify: docs/governance/config-register.md
  • Create: docs/v12/V1.2-状态机与接口契约.md
  • Create: docs/v12/V1.2-字段与统计口径表.md

必须确认的决策:

  1. 用户登录标识:手机号 + 密码,或平台发放的独立用户名 + 密码。
  2. 初始密码的实际发放渠道;失败时由谁、通过什么双人复核流程人工发放。
  3. 两份授权书的正式文本、版本号、拒绝后的服务状态和重新授权规则。
  4. 历史微信用户的补授权、手机号核验和账号关联策略。
  5. 重复手机号/重复资料的拒绝、合并或人工队列规则。
  6. 自动分配算法、跨组规则、无可用红娘时的待分配队列行为。
  7. 六项看板的状态、时间范围、去重规则和“有效匹配”正式口径。
  8. 红娘组长是否可建档、导入、直接分配及调整组内红娘关系。

验收: 所有决策进入 decision-register.md;仍未确认的内容进入 open-questions.md,并在代码计划中标记为配置或阻断,不写成默认业务规则。


Task 1: 建立 V1.2 状态模型和迁移

Files:

  • Create: backend/src/main/resources/db/migration/V062__add_v12_user_account_lifecycle.sql
  • Create: backend/src/main/resources/db/migration/V063__add_v12_import_batches.sql
  • Create: backend/src/main/resources/db/migration/V064__add_v12_consent_and_service_state.sql
  • Modify: backend/src/test/resources/schema-h2.sql
  • Create: backend/src/test/java/com/danyang/match/platform/deployment/V12MigrationContractTest.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/entity/UserCredential.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/entity/UserAccountLifecycle.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/entity/UserConsentState.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/entity/UserImportBatch.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/entity/UserImportRow.java

Interfaces:

  • Produces independent fields for profile_review_status, profile_revision, published_profile_revision, account_creation_status, credential_delivery_status, phone_verification_status, service_consent_status, and service_eligibility_status.

  • Produces password hash, must_change_password, password version, credential issued/used timestamps, and delivery channel/status; never stores plaintext passwords.

  • Produces import batch and row status/error fields with a unique idempotency key per batch.

  • Preserves existing users, operators, review_tasks, consent_records rows and existing V1.1 status values.

  • Step 1: Write migration contract tests for new tables/columns, allowed status values, indexes, uniqueness, and absence of plaintext credential columns.

  • Step 2: Run the contract tests; initial run failed because V062-V064 did not exist, then passed after implementation.

  • Step 3: Add V062-V064 migrations with backfill-safe columns, batch row uniqueness, and indexes for status/scope queries.

  • Step 3a: Add profile revision storage: retain the last approved/published revision and backfill approved users; atomic profile-write transition is implemented in Task 4 at the service boundary.

  • Step 4: Mirror required tables and constraints in schema-h2.sql and keep PostgreSQL-specific DDL covered by migration contract tests.

  • Step 5: Add lifecycle entities without changing existing V1.1 entity semantics; profile write behavior remains a Task 4 concern.

  • Step 6: Run migration and entity tests; no modification to V001-V061.

  • Step 7: Write docs/v12/V1.2-状态机与接口契约.md with allowed transitions, terminal states, idempotency behavior, and actor/audit rules.

验收: Empty PostgreSQL can migrate V001-V064; existing demo data remains readable; duplicate active credential/phone/batch rows are rejected by database constraints.

Task 2: 实现用户自主注册、手机号核验和历史账号关联

Files:

  • Create: backend/src/main/java/com/danyang/match/platform/user/dto/UserRegistrationRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/dto/PhoneVerificationRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/service/UserRegistrationService.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/service/PhoneVerificationService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/controller/AuthController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/service/AuthService.java
  • Create: backend/src/main/java/com/danyang/match/platform/auth/provider/SmsVerificationProvider.java
  • Create: backend/src/main/java/com/danyang/match/platform/auth/provider/MockSmsVerificationProvider.java
  • Create: backend/src/main/java/com/danyang/match/platform/auth/provider/ConfiguredSmsVerificationProvider.java
  • Create: backend/src/test/java/com/danyang/match/platform/user/UserRegistrationServiceTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/auth/PhoneVerificationGuardTest.java
  • Modify: miniapp/services/authService.js
  • Modify: miniapp/pages/login/login.ts
  • Create: miniapp/pages/register/register.ts
  • Create: miniapp/pages/register/register.wxml
  • Create: miniapp/pages/register/register.wxss
  • Create: miniapp/pages/register/register.json

Interfaces:

  • POST /api/v1/auth/register consumes name, organization, organizationPhone, phone, and verification transaction; returns a pending user reference, never an active service token.

  • POST /api/v1/auth/phone/send-code and POST /api/v1/auth/phone/verify use a provider abstraction and one-time Redis transaction; production provider must fail closed when unconfigured.

  • POST /api/v1/auth/wechat/login remains compatible, but new and historical users receive explicit lifecycle state in the response.

  • Duplicate phone returns a stable conflict code and does not overwrite existing records.

  • Step 1: Add failing tests for phone validation, code expiry/replay, rate limits, duplicate phone, and provider refusal outside test/demo profiles.

  • Step 2: Run targeted tests and confirm failure before implementation.

  • Step 3: Implement provider and Redis transaction with hashed code storage, expiry, attempt limit, cooldown, and audit-safe logs; never log the code or full phone.

  • Step 4: Implement registration transaction that writes the registration application and marks phone verification separately.

  • Step 5: Preserve WeChat login compatibility; ambiguous historical account association remains blocked until its explicit association flow is implemented in a later task.

  • Step 6: Add miniapp registration and error/loading states using existing API and UI conventions.

  • Step 7: Run backend tests and miniapp type-check.

验收: Unverified users cannot enter the service flow; duplicate phone cannot overwrite existing data; the same verification transaction cannot be replayed; real-provider configuration is required for production.

Task 3: 实现后台建档、CSV 导入和审核后账号发放

Files:

  • Create: backend/src/main/java/com/danyang/match/platform/user/dto/OperatorCreateUserRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/dto/UserImportPreviewRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/dto/UserImportPreviewResponse.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/service/UserOnboardingService.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/service/UserImportService.java
  • Create: backend/src/main/java/com/danyang/match/platform/user/service/UserCredentialService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/user/controller/UserController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/review/service/ReviewService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/review/controller/ReviewController.java
  • Create: backend/src/test/java/com/danyang/match/platform/user/UserImportServiceTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/user/UserAccountLifecycleTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/review/ReviewAccountIssuanceTest.java
  • Create: admin-web/src/modules/user/UserCreateView.vue
  • Create: admin-web/src/modules/user/UserImportView.vue
  • Modify: admin-web/src/modules/user/UserManagementView.vue
  • Modify: admin-web/src/router/index.ts

Interfaces:

  • POST /api/v1/operator/users creates a draft profile only; it does not bypass phone verification, authorization, or review.

  • POST /api/v1/operator/users/import/preview accepts CSV bytes and returns row-level normalized values/errors without writes.

  • POST /api/v1/operator/users/import/commit consumes a preview batch id plus Idempotency-Key, writes valid rows only, and records every row result.

  • POST /api/v1/operator/users/{id}/issue-account is idempotent and allowed only after approved profile + verified phone + required consent policy.

  • Account issuance returns a masked delivery result and one-time credential reference; plaintext initial password is never persisted or written to logs.

  • Step 1: Write failing tests for permission, CSV encoding/header validation, row errors, duplicate rows within a file, duplicate database phone, preview no-write, commit idempotency, and retry behavior.

  • Step 2: Run targeted tests and confirm failure.

  • Step 3: Implement manual create and CSV preview with explicit required columns: name, organization, organizationPhone, phone; unsupported formats are rejected by the CSV-only endpoint.

  • Step 4: Implement commit transaction with row-level success/failure persistence, Redis idempotency, and no partial overwrite of an existing user.

  • Step 5: Connect review approval to account issuance eligibility and profile publication; approval publishes the reviewed revision while rejection/need-edit preserves the previous published revision.

  • Step 6: Implement secure random initial password generation and hash storage with must_change_password=true; only a credential reference is returned.

  • Step 7: Add admin UI manual-create and CSV preview/commit workflow with permission-based visibility.

  • Step 8: Run backend tests and admin type-check.

验收: Preview performs no database write; commit can be safely retried; failed rows are explainable; approval, phone verification, consent, account status and profile publication remain separate; no plaintext credential is stored; a changed authenticated profile is excluded from matching until its new revision is approved.

Task 4: 实现用户/红娘登录、首次改密和授权门禁

Files:

  • Create: backend/src/main/java/com/danyang/match/platform/auth/dto/PasswordLoginRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/auth/dto/InitialPasswordChangeRequest.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/service/UserCredentialService.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/service/ServiceConsentService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/service/AuthService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/controller/AuthController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/service/OperatorAuthService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/auth/controller/OperatorAuthController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/profile/controller/ProfileController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/profile/service/UserProfileService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/profile/mapper/UserProfileMapper.java
  • Modify: backend/src/main/java/com/danyang/match/platform/capability/service/CapabilityService.java
  • Create: backend/src/main/java/com/danyang/match/platform/account/controller/ServiceConsentController.java
  • Create: backend/src/test/java/com/danyang/match/platform/auth/InitialPasswordGuardTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/account/ServiceConsentGateTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/account/ConsentVersionAuditTest.java
  • Create: miniapp/pages/initial-password/initial-password.ts
  • Create: miniapp/pages/initial-password/initial-password.wxml
  • Create: miniapp/pages/initial-password/initial-password.wxss
  • Create: miniapp/pages/service-consent/service-consent.ts
  • Create: miniapp/pages/service-consent/service-consent.wxml
  • Create: miniapp/pages/service-consent/service-consent.wxss
  • Modify: miniapp/stores/authStore.js
  • Modify: miniapp/app.js

Interfaces:

  • POST /api/v1/auth/password/login authenticates the confirmed login identifier and returns mustChangePassword, consentRequired, and serviceActive state.

  • POST /api/v1/auth/password/change-initial is the only non-essential endpoint allowed while must_change_password=true; success rotates credential version and invalidates old sessions.

  • GET /api/v1/account/service-consent returns the two required document versions and current user decisions.

  • POST /api/v1/account/service-consent requires explicit positive confirmation for each required document and records version, actor, timestamp, IP, user agent, and audit event.

  • All match, chat, matchmaker, counseling, appointment and activity service entry points call a shared ServiceConsentService.requireActive(userId) or equivalent policy check.

  • Step 1: Write failing tests for initial-login restriction, wrong password rate limiting, password complexity, old credential invalidation, unchecked consent rejection, version mismatch, withdrawal, and reactivation.

  • Step 2: Run targeted tests and confirm failure.

  • Step 3: Implement password login and initial-change flow with the existing JWT/Redis conventions; never expose password hashes or plaintext credentials.

  • Step 4: Implement consent state and audit using the formal versions from Gate 0; do not treat silence or a pre-checked UI box as consent.

  • Step 5: Add profile revision gate to profile update endpoints: after authentication, every personal-profile write creates a new revision and moves the profile to pending_review; fields that are not personal-profile data must be explicitly classified rather than silently bypassing review.

  • Step 6: Add shared backend gate to each service boundary. The gate must require the latest profile revision to equal the published approved revision, not just trust the front-end capability response.

  • Step 7: Add miniapp first-login and profile-update routing for change-password, consent, profile confirmation, pending-review, rejection and resubmission states.

  • Step 8: Run negative permission, profile-revision and service-block tests plus miniapp type-check.

验收: Refusal sets the confirmed inactive/suspended service state; protected service APIs reject the user server-side; changing the initial password and accepting both documents are separately auditable; an authenticated profile edit immediately leaves the new revision unpublished and excluded from matching until review approval.

Task 5: 接入红娘自动分配前置条件和账号管理闭环

Files:

  • Create: backend/src/main/java/com/danyang/match/platform/matchmaker/service/MatchmakerEligibilityPolicy.java
  • Modify: backend/src/main/java/com/danyang/match/platform/matchmaker/service/MatchmakerAssignmentService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/matchmaker/service/ServiceAssignmentPolicy.java
  • Modify: backend/src/main/java/com/danyang/match/platform/operator/service/OperatorManagementService.java
  • Modify: backend/src/main/java/com/danyang/match/platform/operator/controller/OperatorController.java
  • Create: backend/src/test/java/com/danyang/match/platform/matchmaker/MatchmakerAssignmentEligibilityTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/matchmaker/ProfileRevisionAssignmentGuardTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/operator/OperatorCredentialLifecycleTest.java
  • Modify: backend/src/main/resources/db/migration/V065__add_v12_assignment_eligibility_audit.sql

Interfaces:

  • MatchmakerEligibilityPolicy.assertEligible(userId) checks, in order: approved profile, verified phone, required consent, normal account status, confirmed service eligibility.

  • Existing MatchmakerAssignmentService.create/transfer remains the write boundary and calls the policy before creating an active assignment.

  • Operator creation requires an explicit approved role (matchmaker or matchmaker_leader), organization scope, secure credential issuance state, and audit record.

  • Disabling a matchmaker cannot silently drop active assignments; it follows the Gate 0 decision for transfer queue/leader handling.

  • Step 1: Write failing tests for each missing eligibility condition, concurrent assignment, cross-organization leader denial, disabled target, and re-enable behavior.

  • Step 2: Run targeted tests and confirm failure.

  • Step 3: Implement MatchmakerEligibilityPolicy by reusing CapabilityService, consent policy and the published-profile-revision check; do not duplicate status rules in controllers.

  • Step 4: Connect policy to create/transfer within the existing transaction and preserve database unique-index race protection.

  • Step 5: Harden operator creation with request validation, role binding, audit, password policy and initial-change flag.

  • Step 6: Implement disabled-operator assignment handling exactly as decided at Gate 0, with an audit event and no data loss.

  • Step 7: Run the existing matchmaker suite plus new eligibility tests.

验收: No ineligible user can receive an active automatic/manual assignment; ordinary matchmakers cannot claim or browse unassigned users; group leaders remain organization-scoped; disabling a matchmaker leaves an auditable, recoverable assignment state.

Task 6: 重建六项范围看板和详情一致性

Files:

  • Create: backend/src/main/java/com/danyang/match/platform/matchmaker/dashboard/MatchmakerDashboardScope.java
  • Create: backend/src/main/java/com/danyang/match/platform/matchmaker/dashboard/MatchmakerDashboardMapper.java
  • Create: backend/src/main/java/com/danyang/match/platform/matchmaker/dashboard/MatchmakerWorkbenchService.java
  • Create: backend/src/main/java/com/danyang/match/platform/matchmaker/dashboard/MatchmakerWorkbenchController.java
  • Modify: backend/src/main/java/com/danyang/match/platform/analytics/AnalyticsService.java
  • Create: backend/src/test/java/com/danyang/match/platform/matchmaker/MatchmakerWorkbenchScopeTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/matchmaker/MatchmakerDashboardConsistencyTest.java
  • Create: backend/src/test/java/com/danyang/match/platform/matchmaker/MatchmakerDashboardAuthorizationTest.java
  • Modify: admin-web/src/services/dashboard.ts
  • Modify: admin-web/src/types/dashboard.ts
  • Modify: admin-web/src/views/DashboardView.vue
  • Modify: admin-web/src/router/index.ts

Interfaces:

  • GET /api/v1/operator/matchmaker/workbench/dashboard returns { scope, metrics, availability, generatedAt } for the six cards and shared query metadata.

  • MatchmakerDashboardScope is derived server-side: ordinary matchmaker = active assignments owned by principal; group leader = same organization; administrator = platform scope.

  • The six metric keys remain pending_reviews, matchmaker_todos, counseling_todos, station_appointments, effective_matches, and activity_registrations to preserve the existing UI contract.

  • Detail list endpoints receive only pagination/time filters; they cannot receive an alternate operator/team scope. They call the same scope builder and status predicates as the aggregate query.

  • User/profile-backed metrics and drill-down records exclude rows where profile_revision != published_profile_revision; an unreviewed profile revision must not leak through the dashboard or matching data.

  • Step 1: Freeze metric definitions in docs/v12/V1.2-字段与统计口径表.md, including included/excluded statuses, timezone Asia/Shanghai, time window, and deduplication.

  • Step 2: Write failing authorization/consistency tests for ordinary matchmaker, same-team leader, other-team leader, administrator, empty data, permission denied, and aggregate/detail equality.

  • Step 3: Run targeted tests and confirm failure.

  • Step 4: Implement scope builder and SQL filters at query level; do not fetch global rows and filter in Vue. Add the published-profile-revision predicate to every user/profile-backed metric and detail query.

  • Step 5: Implement one aggregate endpoint while preserving older analytics endpoints for existing analytics pages.

  • Step 6: Update dashboard.ts to use the aggregate response for six cards; keep loading, empty, forbidden, partial-failure states distinct.

  • Step 7: Add detail navigation tests showing a card click cannot broaden the scope.

  • Step 8: Run backend scope tests, admin type-check, build, and UI contract tests.

验收: Six cards show 0 for real empty data, a distinct no-permission state for forbidden data, and a distinct failure state for query failure; ordinary matchmaker, leader, and administrator counts match their permitted detail lists; changing request parameters cannot change scope.

Task 7: 活栈 E2E、文档收口和发布门禁

Files:

  • Create: tests/e2e/v12_account_lifecycle_test.py
  • Create: tests/e2e/v12_import_and_review_test.py
  • Create: tests/e2e/v12_matchmaker_dashboard_test.py
  • Modify: tests/e2e/conftest.py
  • Modify: backend/src/test/resources/application-test.yml
  • Modify: docs/STATUS.md
  • Create: docs/Phase-V12-Completion-Report.md
  • Modify: docs/api/API_INVENTORY.md
  • Modify: docs/database/MIGRATION_GUIDE.md
  • Modify: README.md
  • Modify: .github/workflows/ci.yml

Interfaces:

  • E2E uses a clean PostgreSQL/Redis stack and explicit test providers; it never treats H2-only results as release evidence.

  • CI runs migration validation, backend tests, admin type-check/build, miniapp type-check, and V1.2 E2E; any failed gate blocks completion.

  • Completion report records current commit, migration version, test counts, skipped tests/reasons, runtime configuration, and unresolved production evidence.

  • Step 1: Add E2E fixtures for a user, duplicate phone, pending/approved review, ordinary matchmaker, same-team leader, other-team leader, and administrator.

  • Step 2: Add the account lifecycle path: register or import → preview → commit → review → account issue → password login → forced change → two consents → service capability.

  • Step 2a: Add the profile revision path: approved user edits personal profile → new revision becomes pending → old approved revision remains the only published revision → review approval publishes the new revision → matching and display resume.

  • Step 3: Add negative paths: duplicate phone, expired code, repeated commit, refused consent, pending/rejected profile excluded from search/recommendation/matchmaker recommendation, cross-team dashboard query, and disabled matchmaker.

  • Step 4: Add dashboard consistency checks for all six cards and corresponding detail lists under all three role scopes, including exclusion of unpublished profile revisions.

  • Step 5: Run the full local gate:

    mvn -B -f backend/pom.xml test
    pnpm --dir admin-web type-check
    pnpm --dir admin-web build
    npm --prefix miniapp run type-check
    python -m pytest tests/e2e -q
    
  • Step 6: Fix environment blockers separately if spawn EPERM, locked target/classes, missing Redis, or missing production-provider credentials occur; do not weaken tests.

  • Step 7: Write Completion Report with PASS/PARTIAL/FAIL/NOT_IMPLEMENTED/NOT_VERIFIED evidence and stop for user acceptance.

验收: Clean-stack E2E proves the complete V1.2 path and role isolation; CI is green; no historical test count is reused as current evidence; production remains NO-GO until real SMS/WeChat, TLS, backup/restore, monitoring, rollback and user UAT are separately proven.

Dependency Order and Release Gates

Gate 0 product decisions
        |
        v
Task 1 state model and migrations
        |
        +--> Task 2 registration and phone verification
        |          |
        |          v
        +--> Task 3 admin create/import/review/issuance
                   |
                   v
             Task 4 first login/password/consent gate
                   |
                   +--> Task 5 assignment eligibility
                   |
                   +--> Task 6 scoped dashboard
                              |
                              v
                         Task 7 E2E and release gate

Phase completion rules:

  • Gate 0: all mandatory product decisions recorded.
  • Task 1: V062-V064 migrate on a clean database and existing data remains readable.
  • Task 2: phone verification cannot be bypassed or replayed.
  • Task 3: import is previewable, idempotent, auditable and cannot bypass review/consent.
  • Task 4: initial password, consent and unpublished profile revisions are backend-enforced.
  • Task 5: assignment eligibility and role scope are negative-tested.
  • Task 6: cards and details share scope and metric definitions.
  • Task 7: full current test evidence is recorded and user acceptance is requested.

Explicitly Deferred

  • Direct .xlsx parsing; first release accepts UTF-8 CSV and returns a clear unsupported-format error for .xlsx.
  • A new automatic assignment algorithm before the product decision; the existing explicit assignment path remains available.
  • Any payment, VIP, AI代聊, community feed, microservice, Kubernetes, or unrelated V1.2 expansion.
  • Production SMS/WeChat provider integration, real credentials, production TLS, backup/restore rehearsal and real-user UAT until their environment and owners are available.

Plan Self-Check

  • Registration fields, phone verification, duplicate handling: Task 2.
  • Manual create, CSV preview/commit, row errors, review linkage: Task 3.
  • Independent account/credential/consent/service states: Task 1 and Task 4.
  • Initial password rules, hash-only storage, forced change: Task 3 and Task 4.
  • Authenticated profile update creates a new revision and blocks display/matching until approval: Task 1, Task 3, Task 4, Task 5, Task 6 and Task 7.
  • Administrator-only matchmaker account opening and group scope: Task 5.
  • Automatic assignment prerequisites and no-available-matchmaker behavior: Gate 0 and Task 5.
  • Six dashboard cards, role scopes, empty/error/forbidden states, card/detail consistency: Task 6.
  • Tests, migrations, frontend builds, clean-stack E2E, documentation and completion report: Task 7.

Execution Handoff

Plan complete and saved to docs/superpowers/plans/2026-10-23-v12-account-lifecycle-matchmaker-dashboard.md. Execute it task-by-task with review checkpoints; implementation must begin at Gate 0 and stop after each phase Completion Report.