feat: new
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
## Why
|
||||
|
||||
The August 2026 customer API document (`docs/产品迭代8月份/11.md`) freezes the customer-side authentication contracts used by H5. The behavioral contract changes are:
|
||||
|
||||
- `need_bind_phone` widens to a three-state decision: no main phone, or main phone exists but the current asset is unassociated -> `true`; already associated -> `false`; global switch off -> always `false`. The frontend still uses it only to decide whether to guide the user into phone verification.
|
||||
- `POST /api/c/v1/auth/bind-phone` becomes idempotent: when the account already has a main phone, submitting the same main phone plus a valid code creates the association instead of rejecting it.
|
||||
- `POST /api/c/v1/auth/change-phone` migrates all valid phone-asset associations in one transaction and rolls back the whole operation on the 10-asset limit or an existing same-asset relation.
|
||||
|
||||
The current H5 bind page starts with an empty phone input and has no prefill. Existing users who have a main phone but whose current asset is unassociated are guided to verify, yet every submitted number is rejected - a deadlock. Homepage-gate and login routing must also follow the widened `need_bind_phone` semantics instead of raw bound-phone presence.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Bind page prefills the phone input with the account main phone from `GET /api/c/v1/asset/info` -> `bound_phone` and allows sending a `bind_phone` verification code to that number
|
||||
- Bind submission treats `bind-phone` as idempotent for the account main phone; other numbers show the backend `msg` and keep the user on the page
|
||||
- Keep the existing bind-completion flow: ordinary entry returns back, mandatory login-gate entry triggers the manual re-login flow
|
||||
- `change-phone` keeps the old/new phone and verification-code inputs with the `change_phone_old` / `change_phone_new` send-code scenes; failures show backend rollback copy (10-item limit and same-asset conflict) and keep the user on the page
|
||||
- Login and homepage entry keep `need_bind_phone` as the only phone-verification guide signal and follow the three-state semantic
|
||||
- `send-code` request/response stays unchanged (`cooldown_seconds`); the new `verify-asset` fields `miniapp_app_id` / `oa_app_id` are a backend confirm item, not consumed yet
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `phone-bind-association-prefill`: Define bind-page prefill of the account main phone and idempotent bind submission behavior
|
||||
- `phone-change-migration`: Define change-phone transaction-migration behavior and backend rollback copy display
|
||||
|
||||
### Modified Capabilities
|
||||
- `index-phone-bind-gate`: Widen the bind-phone gate to the three-state `need_bind_phone` semantic
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected code: `pages/bind/bind.vue`, `pages/change-phone/change-phone.vue`, `pages/index/index.vue`, `pages/login/login.vue`
|
||||
- API module: `api/modules/auth.js` unchanged - endpoints and response shapes already match `11.md`
|
||||
- Backend contract deltas (per `11.md`): bind-phone idempotency, change-phone transactional migration, three-state `need_bind_phone`
|
||||
- Backend decisions (confirmed 2026-09-15):
|
||||
- `need_bind_phone` stays wechat-login-only; `asset/info` and `verify-asset` do not add the field. The homepage gate keeps evaluating the per-entry association state via `asset/info.bound_phone`.
|
||||
- No new prefill field: bind-page prefill keeps using `asset/info.bound_phone`.
|
||||
- `verify-asset`'s new `miniapp_app_id` / `oa_app_id` are not consumed; H5 login keeps using `/api/c/v1/wechat/appid`, and `/api/c/v1/auth/wechat-login` remains the login authority.
|
||||
@@ -0,0 +1,23 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Index entry SHALL enforce the bind-phone gate from the asset association state
|
||||
The system SHALL determine whether phone-verification guidance is required whenever the homepage is entered, using the current asset association state returned by `GET /api/c/v1/asset/info` -> `bound_phone` (empty means the asset is not associated and binding is required). The widened `need_bind_phone` decision stays wechat-login-only: no main phone -> required; main phone exists but the current asset is unassociated -> required; already associated -> not required; global switch off -> never required. The frontend still uses the signal only to decide whether to guide the user, and the backend does not block any business interface on the missing relation.
|
||||
|
||||
#### Scenario: User has no main phone
|
||||
- **WHEN** the account has no main phone and the user enters `pages/index/index`
|
||||
- **THEN** the system SHALL treat phone verification as required
|
||||
- **AND** the system SHALL route the user into the bind-phone guide
|
||||
|
||||
#### Scenario: User has a main phone but the current asset is unassociated
|
||||
- **WHEN** the account has a main phone but the current asset is not associated with it
|
||||
- **THEN** the system SHALL treat phone verification as required
|
||||
- **AND** the bind page SHALL prefill the account main phone from `asset/info.bound_phone`
|
||||
|
||||
#### Scenario: User is already associated
|
||||
- **WHEN** the current asset is already associated with the account main phone
|
||||
- **THEN** the system SHALL keep the user on the homepage
|
||||
- **AND** the system SHALL NOT route the user into the bind-phone guide
|
||||
|
||||
#### Scenario: Global switch off
|
||||
- **WHEN** the global phone-bind switch is off
|
||||
- **THEN** the system SHALL never route the user into the bind-phone guide regardless of account state
|
||||
@@ -0,0 +1,36 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Bind page SHALL prefill the account main phone
|
||||
The system SHALL prefill the bind-phone input with the logged-in account's main phone when one exists, using `GET /api/c/v1/asset/info` -> `bound_phone`, and SHALL allow sending a `bind_phone` verification code to that number.
|
||||
|
||||
#### Scenario: Existing account with a main phone enters the bind page
|
||||
- **WHEN** the account already has a main phone and the user enters `pages/bind/bind`
|
||||
- **THEN** the phone input SHALL be prefilled with the main phone
|
||||
- **AND** the user SHALL be able to request a `bind_phone` verification code for that number without being rejected
|
||||
|
||||
#### Scenario: New account without a main phone enters the bind page
|
||||
- **WHEN** the account has no main phone
|
||||
- **THEN** the phone input SHALL remain empty
|
||||
- **AND** the user SHALL enter a new number and follow the normal bind flow
|
||||
|
||||
### Requirement: Bind submission SHALL be idempotent for the account main phone
|
||||
When `POST /api/c/v1/auth/bind-phone` is submitted with the account main phone and a valid code, the system SHALL treat it as a successful idempotent association instead of rejecting because the phone is already in use.
|
||||
|
||||
#### Scenario: Main phone plus valid code
|
||||
- **WHEN** the submitted phone equals the account main phone and the code is valid
|
||||
- **THEN** the bind request SHALL succeed
|
||||
- **AND** the response SHALL keep the existing shape (`phone`, `bound_at`)
|
||||
- **AND** the existing bind-completion routing SHALL apply unchanged
|
||||
|
||||
#### Scenario: Number different from the main phone
|
||||
- **WHEN** the submitted phone differs from the account main phone
|
||||
- **THEN** the bind request SHALL be rejected
|
||||
- **AND** the system SHALL display the backend `msg` and keep the user on the bind page
|
||||
|
||||
### Requirement: Bind failures SHALL display backend messages
|
||||
The system SHALL present the backend-provided error message for all bind-phone failures instead of a generic failure text, and SHALL keep the user on the bind page.
|
||||
|
||||
#### Scenario: Backend rejection with message
|
||||
- **WHEN** `bind-phone` returns a business error
|
||||
- **THEN** the bind page SHALL show the returned `msg`
|
||||
- **AND** the page SHALL NOT navigate away
|
||||
@@ -0,0 +1,29 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Change-phone SHALL follow transactional full migration
|
||||
The system SHALL rely on `POST /api/c/v1/auth/change-phone` to migrate all valid phone-asset associations in one transaction, and SHALL treat any failure as a rollback of the whole operation.
|
||||
|
||||
#### Scenario: Successful migration
|
||||
- **WHEN** the old-phone code and the new-phone code are valid and no limit or conflict occurs
|
||||
- **THEN** the change request SHALL succeed
|
||||
- **AND** the response SHALL keep the existing shape (`phone`, `changed_at`)
|
||||
- **AND** the user SHALL return to the previous page and the homepage SHALL refresh the bound state
|
||||
|
||||
#### Scenario: New number exceeds the association limit
|
||||
- **WHEN** the new number would exceed 10 valid associated assets
|
||||
- **THEN** the whole operation SHALL be rolled back
|
||||
- **AND** the system SHALL display the backend copy: 该手机号最多关联10项有效资产
|
||||
|
||||
#### Scenario: New number conflicts with an existing same-asset relation
|
||||
- **WHEN** the new number already has a valid association with an asset being migrated
|
||||
- **THEN** the whole operation SHALL be rolled back
|
||||
- **AND** the system SHALL display the backend copy: 新手机号已存在与待迁移资产相同的有效关联,换绑已回滚
|
||||
|
||||
### Requirement: Change-phone failures SHALL keep the user on the page
|
||||
The system SHALL stay on the change-phone page and show the backend error message when migration fails so the user can correct the input and retry.
|
||||
|
||||
#### Scenario: Migration failure with message
|
||||
- **WHEN** `change-phone` returns a business error
|
||||
- **THEN** the page SHALL show the returned `msg`
|
||||
- **AND** the page SHALL NOT navigate away
|
||||
|
||||
29
openspec/changes/update-phone-bind-association-flow/tasks.md
Normal file
29
openspec/changes/update-phone-bind-association-flow/tasks.md
Normal file
@@ -0,0 +1,29 @@
|
||||
## 1. Bind Page Prefill and Idempotent Bind
|
||||
|
||||
- [x] 1.1 Load the account main phone on bind-page mount via `assetApi.getInfo` and prefill the phone input when present
|
||||
- [x] 1.2 Allow sending a `bind_phone` verification code to the prefilled main phone
|
||||
- [x] 1.3 Keep ordinary bind success returning to the previous page
|
||||
- [x] 1.4 Keep mandatory login-gate bind success returning to the login page for manual re-login
|
||||
- [x] 1.5 Show backend `msg` on bind rejection and stay on the page
|
||||
|
||||
## 2. Change-Phone Transactional Migration Display
|
||||
|
||||
- [x] 2.1 Keep old/new phone and verification-code inputs with `change_phone_old` / `change_phone_new` scenes
|
||||
- [x] 2.2 Show backend rollback copy for the 10-item limit and the same-asset conflict
|
||||
- [x] 2.3 Stay on the change-phone page on failure
|
||||
- [x] 2.4 Refresh the homepage bound state after success (existing `onShow` reload)
|
||||
|
||||
## 3. Three-State Need-Bind-Phone Routing
|
||||
|
||||
- [x] 3.1 Keep `need_bind_phone` as the only phone-verification guide signal in login success
|
||||
- [x] 3.2 Evaluate the three-state semantic in the homepage bind gate
|
||||
- [x] 3.3 Re-check the binding state on every homepage entry, not only after login
|
||||
- [x] 3.4 Confirm the homepage gate signal source with backend - decision: keep `asset/info.bound_phone`; `need_bind_phone` stays wechat-login-only
|
||||
|
||||
## 4. Regression Verification
|
||||
|
||||
- [ ] 4.1 New user without a main phone still binds a fresh number
|
||||
- [ ] 4.2 Existing user with a main phone and an unassociated asset can prefill, send code, and bind idempotently
|
||||
- [ ] 4.3 Bind with a number different from the main phone shows the backend rejection message
|
||||
- [ ] 4.4 Change-phone limit/conflict errors show the fixed backend copy
|
||||
- [ ] 4.5 Global-switch-off keeps the bind guide hidden
|
||||
Reference in New Issue
Block a user