docs(openspec): propose 8 tigshop migration changes (P0-P7) + migration plan
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Merchant application submission
|
||||
A prospective seller SHALL submit one merchant onboarding application as either a personal (个人) or an enterprise (企业) entity. Each kind SHALL require its own entity information, one or more operating categories referenced from the published category tree, contact details, and qualification materials submitted as URL fields. The API MUST reject submissions with missing kind-specific fields, unknown categories, or malformed qualification URLs. The form MAY be filled anonymously, but submission SHALL require an authenticated user.
|
||||
|
||||
#### Scenario: enterprise submission accepted
|
||||
- **WHEN** an authenticated user submits an enterprise application with entity information, operating categories, contact details, and qualification URLs
|
||||
- **THEN** the application is stored with status `pending` and returned to the applicant
|
||||
|
||||
#### Scenario: personal submission missing identity document
|
||||
- **WHEN** a user submits a personal application without the required identity document URL
|
||||
- **THEN** the API returns a validation error and stores no application row
|
||||
|
||||
#### Scenario: anonymous submit requires sign-in
|
||||
- **WHEN** a signed-out visitor submits the completed form
|
||||
- **THEN** no application is stored and the visitor must register or sign in before submitting
|
||||
|
||||
### Requirement: One active application per user
|
||||
Submission SHALL be deduplicated per user: a user holding a `pending` or `approved` application MUST NOT create another one, enforced by service validation backed by a database partial unique index so concurrent submissions cannot both succeed. A user whose application was `rejected` MAY apply again.
|
||||
|
||||
#### Scenario: duplicate pending submission
|
||||
- **WHEN** a user with a `pending` application submits again
|
||||
- **THEN** the API rejects the request with a conflict and exactly one application row exists
|
||||
|
||||
#### Scenario: re-apply after rejection
|
||||
- **WHEN** a user whose application was `rejected` submits a new application
|
||||
- **THEN** a new `pending` application row is created
|
||||
|
||||
### Requirement: Review state machine
|
||||
An application SHALL move only from `pending` to `approved` or `rejected`, executed as guarded updates matching the `pending` state so concurrent or repeated reviews of the same application fail with a conflict instead of overwriting each other. Rejecting SHALL require a non-empty reason recorded on the row, and `approved` and `rejected` are terminal states that MUST NOT transition again.
|
||||
|
||||
#### Scenario: double review conflict
|
||||
- **WHEN** two platform admins review the same `pending` application concurrently
|
||||
- **THEN** exactly one transition succeeds and the other receives a conflict
|
||||
|
||||
#### Scenario: rejection records a reason
|
||||
- **WHEN** a platform admin rejects a `pending` application with a reason
|
||||
- **THEN** the application becomes `rejected` with the reason stored on the row
|
||||
|
||||
#### Scenario: terminal state is immutable
|
||||
- **WHEN** a platform admin reviews an already `approved` or `rejected` application
|
||||
- **THEN** the API returns a conflict and the stored state is unchanged
|
||||
|
||||
### Requirement: Transactional approval provisioning
|
||||
Approving an application SHALL, within a single database transaction, create the shop, create a dedicated `shop_owner` account scoped to that shop, and mark the application `approved` referencing the created shop. The generated initial password SHALL be returned exactly once in the approve response and MUST NOT be retrievable through any later read. If any step fails, the status change and all provisioning SHALL roll back so the application remains `pending`.
|
||||
|
||||
#### Scenario: approval provisions shop and account
|
||||
- **WHEN** a platform admin approves a `pending` application
|
||||
- **THEN** one transaction results in an `approved` application, an active shop, and a working `shop_owner` login scoped to that shop
|
||||
|
||||
#### Scenario: credentials shown once
|
||||
- **WHEN** the approver reads the application again after approval
|
||||
- **THEN** the initial password is absent from every subsequent response
|
||||
|
||||
#### Scenario: provisioning failure rolls back
|
||||
- **WHEN** shop or account creation fails during approval
|
||||
- **THEN** no shop or account persists and the application remains `pending`
|
||||
|
||||
### Requirement: Application visibility
|
||||
An applicant SHALL read only their own application history, including status, submitted data, timestamps, and rejection reason. Platform admins SHALL list all applications with status filtering and pagination and read any application detail. Other users' applications MUST NOT be readable through customer routes.
|
||||
|
||||
#### Scenario: applicant checks status
|
||||
- **WHEN** a signed-in applicant requests their application status
|
||||
- **THEN** their own application state and rejection reason are returned
|
||||
|
||||
#### Scenario: other applicant is hidden
|
||||
- **WHEN** one authenticated user requests another user's application through customer routes
|
||||
- **THEN** the API returns no data about the other user's application
|
||||
Reference in New Issue
Block a user