30 KiB
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
必须确认的决策:
- 用户登录标识:手机号 + 密码,或平台发放的独立用户名 + 密码。
- 初始密码的实际发放渠道;失败时由谁、通过什么双人复核流程人工发放。
- 两份授权书的正式文本、版本号、拒绝后的服务状态和重新授权规则。
- 历史微信用户的补授权、手机号核验和账号关联策略。
- 重复手机号/重复资料的拒绝、合并或人工队列规则。
- 自动分配算法、跨组规则、无可用红娘时的待分配队列行为。
- 六项看板的状态、时间范围、去重规则和“有效匹配”正式口径。
- 红娘组长是否可建档、导入、直接分配及调整组内红娘关系。
验收: 所有决策进入 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, andservice_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_recordsrows 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.sqland 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-状态机与接口契约.mdwith 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/registerconsumes name, organization, organizationPhone, phone, and verification transaction; returns a pending user reference, never an active service token. -
POST /api/v1/auth/phone/send-codeandPOST /api/v1/auth/phone/verifyuse a provider abstraction and one-time Redis transaction; production provider must fail closed when unconfigured. -
POST /api/v1/auth/wechat/loginremains 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/userscreates a draft profile only; it does not bypass phone verification, authorization, or review. -
POST /api/v1/operator/users/import/previewaccepts CSV bytes and returns row-level normalized values/errors without writes. -
POST /api/v1/operator/users/import/commitconsumes a preview batch id plusIdempotency-Key, writes valid rows only, and records every row result. -
POST /api/v1/operator/users/{id}/issue-accountis 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/loginauthenticates the confirmed login identifier and returnsmustChangePassword,consentRequired, andserviceActivestate. -
POST /api/v1/auth/password/change-initialis the only non-essential endpoint allowed whilemust_change_password=true; success rotates credential version and invalidates old sessions. -
GET /api/v1/account/service-consentreturns the two required document versions and current user decisions. -
POST /api/v1/account/service-consentrequires 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/transferremains the write boundary and calls the policy before creating an active assignment. -
Operator creation requires an explicit approved role (
matchmakerormatchmaker_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
MatchmakerEligibilityPolicyby reusingCapabilityService, 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/dashboardreturns{ scope, metrics, availability, generatedAt }for the six cards and shared query metadata. -
MatchmakerDashboardScopeis 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, andactivity_registrationsto 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, timezoneAsia/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.tsto 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, lockedtarget/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_VERIFIEDevidence 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
.xlsxparsing; 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.