## ADDED Requirements ### Requirement: Admin Notification Contract The admin notification frontend SHALL use the actual notification contract returned by `GET /api/admin/notifications`. Each item SHALL preserve `id`, `title`, `body`, `category`, `type`, `severity`, `is_read`, `created_at`, `read_at`, `ref_type`, `ref_id`, and `ref_key`. #### Scenario: Display actual notification fields - **WHEN** 管理端通知列表返回通知项 - **THEN** 页面 MUST display `title` and `body` - **AND** 页面 MUST use `is_read` for read state - **AND** 页面 MUST preserve `read_at` and `ref_key` ### Requirement: Admin Notification List Filters The notification center SHALL query `GET /api/admin/notifications` with `category`, `type`, `severity`, `is_read`, `page`, and `page_size`. The frontend SHALL not send `read_status` as a replacement for `is_read`. #### Scenario: Filter unread notifications - **WHEN** 用户选择未读筛选 - **THEN** 前端 MUST send `is_read=false` - **AND** 页面 MUST render the paginated `data.items` response #### Scenario: Filter read notifications - **WHEN** 用户选择已读筛选 - **THEN** 前端 MUST send `is_read=true` ### Requirement: Unread Count And Summary The admin header and notification drawer SHALL use `GET /api/admin/notifications/unread-count` and `GET /api/admin/notifications/unread-summary`. The unread count response SHALL preserve `count` and `display_count`; the summary response SHALL preserve `approval`, `expiry`, `sync`, `system`, and `total`. #### Scenario: Display backend unread badge - **WHEN** 未读数接口返回 `count` and `display_count` - **THEN** 顶部铃铛 MUST display the backend `display_count` - **AND** shared notification state MUST preserve the numeric `count` #### Scenario: Load drawer notifications - **WHEN** 用户打开顶部通知抽屉 - **THEN** 前端 MUST use the summary endpoint for category counts - **AND** 前端 MUST query the notification list endpoint with `page=1` and `page_size=10` for recent notifications ### Requirement: Read State Operations The admin frontend SHALL mark notifications read through `PUT /api/admin/notifications/{id}/read` and mark notifications read in bulk through `PUT /api/admin/notifications/read-all`. The bulk request SHALL support an optional JSON `category` field. #### Scenario: Mark one notification read - **WHEN** 用户点击通知 - **THEN** 前端 MUST call the single-read PUT endpoint before target resolution - **AND** after success MUST refresh the shared unread count and relevant notification state #### Scenario: Mark all notifications read - **WHEN** 用户点击全部已读 - **THEN** 前端 MUST call `PUT /api/admin/notifications/read-all` with an object body - **AND** after success MUST refresh the list, summary and unread count ### Requirement: Controlled Notification Target The admin frontend SHALL resolve notification navigation through `GET /api/admin/notifications/{id}/target`. It SHALL map only recognized `target_type` or `target_key` values to registered internal routes and SHALL use `target_id` as a route parameter when required. #### Scenario: Navigate to recognized target - **WHEN** 目标接口返回可用的受支持 `target_type`、`target_key` 和 `target_id` - **THEN** 前端 MUST navigate to the corresponding registered internal route - **AND** 前端 MUST not execute an arbitrary URL from the response #### Scenario: Handle unknown target safely - **WHEN** 目标类型未知、目标不可用或当前路由未注册 - **THEN** 前端 MUST not navigate - **AND** 页面 MUST display the notification body or an unavailable-target message ### Requirement: Admin-Only Notification Scope This notification capability SHALL apply only to the admin APIs under `/api/admin/notifications` and the admin `/notifications` interface. It SHALL not add or modify C-end `/api/c/v1/notifications` APIs or pages. #### Scenario: Exclude C-end notifications - **WHEN** this change is implemented - **THEN** C-end notification APIs and pages MUST remain outside the change scope