## MODIFIED Requirements ### Requirement: Personal notification list SHALL preserve backend ordering The system SHALL display personal notifications in the backend-fixed order (created time and notification id descending) and SHALL NOT re-sort items client-side by severity or priority. #### Scenario: Backend returns a fixed order - **WHEN** the notification list is loaded - **THEN** the items SHALL be rendered in the returned order ### Requirement: Notification items SHALL pass through popup fields and types The system SHALL render items with the new `type` values `h5.popup.risk_exchange` and `h5.popup.operation` (category `system`) and SHALL keep `popup_snapshot` available for popup-related actions without treating it as a route. #### Scenario: List contains a popup notification - **WHEN** an item has `type` `h5.popup.risk_exchange` or `h5.popup.operation` - **THEN** the item SHALL render as a normal system-category notification ### Requirement: Unread badge SHALL reflect popup notifications The system SHALL count popup notifications in the unread badge and collapse the badge to `99+` above 99 per the `display_count` contract. #### Scenario: Popup notification unread - **WHEN** a popup notification is unread - **THEN** the unread badge SHALL increase accordingly ### Requirement: Mark-read SHALL include the notification id and be idempotent The system SHALL send the notification `id` in the mark-read request body and SHALL treat success responses idempotently. #### Scenario: Mark-read an already-read notification - **WHEN** the notification is already read or owned by another customer - **THEN** the request SHALL still succeed ### Requirement: read-all SHALL NOT close popups implicitly in the popup chain The system SHALL NOT call `read-all` from any popup display path because it also marks today's popup notifications read. #### Scenario: Popup display flow - **WHEN** the popup candidate flow runs - **THEN** the system SHALL NOT call `read-all`