## ADDED Requirements

### Requirement: Page through active phone assets
The system SHALL provide `GET /api/phone-assets` and return only records whose `delete_time` equals `0`, ordered by descending ID, inside `ApiResponse.data` as `records`, `total`, `page`, and `size`.

#### Scenario: Default page is requested
- **WHEN** a client requests `GET /api/phone-assets` without paging parameters
- **THEN** the system returns page `1`, size `20`, and only active phone-asset records

#### Scenario: Indexed filters are supplied
- **WHEN** a client supplies valid `phoneNumber`, `iccid`, `cardType`, `managementType`, `disposalStatus`, or `deviceId` query parameters
- **THEN** the system returns only active records matching every supplied condition

#### Scenario: Page parameters are invalid
- **WHEN** a client supplies a page below `1` or a size outside `1` through `100`
- **THEN** the system returns HTTP `400` with the standard error response and performs no query write

### Requirement: Read one active phone asset
The system SHALL provide `GET /api/phone-assets/{id}` and return the requested active record or a standard not-found response.

#### Scenario: Active record exists
- **WHEN** a client requests an existing active phone-asset ID
- **THEN** the response is HTTP `200` and contains the editable fields, audit times, read-only relation snapshots, and relation sync time

#### Scenario: Record is deleted or absent
- **WHEN** a client requests an absent ID or a soft-deleted ID
- **THEN** the system returns HTTP `404` and does not reveal the deleted record

### Requirement: Create a phone asset safely
The system SHALL provide `POST /api/phone-assets`, validate all client-writable fields, and insert exactly one active `as_phone_asset` record when the phone number is not already active.

#### Scenario: Valid asset is created
- **WHEN** a client submits a phone number that normalizes to exactly 11 digits with optional valid asset fields
- **THEN** the system returns HTTP `200`, writes audit times, sets `delete_time` to `0`, and initializes each linked-account snapshot to JSON `[]`

#### Scenario: Input is invalid
- **WHEN** a client submits an invalid phone number, overlong text, invalid ICCID length, or negative device ID
- **THEN** the system returns HTTP `400` and inserts no record

#### Scenario: Active phone number is duplicated
- **WHEN** a client creates a phone asset whose phone number already belongs to an active record
- **THEN** the system returns HTTP `409` and preserves the existing record

### Requirement: Edit only client-writable fields
The system SHALL provide `PUT /api/phone-assets/{id}` and update only the documented client-writable fields of an active phone asset.

#### Scenario: Valid edit is submitted
- **WHEN** a client submits valid values for an existing active record
- **THEN** the system updates the editable fields and `update_time` while preserving all linked snapshots and `relation_synced_at`

#### Scenario: Edited phone number conflicts
- **WHEN** a client changes a phone number to another active record's number
- **THEN** the system returns HTTP `409` and does not partially update the target record

### Requirement: Soft-delete a phone asset
The system SHALL provide `DELETE /api/phone-assets/{id}` and mark only the target active record deleted without physically deleting its row.

#### Scenario: Active record is deleted
- **WHEN** a client deletes an existing active phone asset
- **THEN** the system writes a nonzero Unix-millisecond `delete_time` and a new `update_time`, returns success, and excludes the record from later reads

#### Scenario: Record is already unavailable
- **WHEN** a client deletes an absent or already-deleted phone asset
- **THEN** the system returns HTTP `404` and does not change another record

### Requirement: Keep relation snapshots server-managed
The system SHALL not accept linked-account snapshot fields or `relationSyncedAt` from create or update clients, and SHALL expose valid snapshots as read-only numeric ID arrays.

#### Scenario: Client attempts to write a relation field
- **WHEN** a client includes any linked-account snapshot or relation sync field in a save request
- **THEN** the system ignores that field and retains server-managed snapshot values

#### Scenario: New asset has no known relationships
- **WHEN** a phone asset is created before relation-sync modules exist
- **THEN** each response relation array is empty and the relation sync time is unset

### Requirement: Apply confirmed input and deletion rules
The system SHALL normalize a phone number by trimming whitespace and removing one leading `+86` before requiring exactly 11 digits. The system SHALL enforce the confirmed dropdown values, default a missing create disposal status to `正常使用`, accept null management type and device ID, and SHALL NOT verify that a provided device ID exists.

#### Scenario: Number includes a country code
- **WHEN** a client submits ` +8613812345678 `
- **THEN** the system stores `13812345678`

#### Scenario: Dropdown values are saved
- **WHEN** a client creates or edits using the confirmed dropdown values
- **THEN** card type and management type remain optional, while disposal status is required and defaults to `正常使用` on create

#### Scenario: Active associations block deletion
- **WHEN** a client deletes a phone asset with an active wecom account, wechat account, douyin account, domain account, or merchant reference
- **THEN** the system returns HTTP `409` with the blocking relation type and leaves the record active