feat: add notification feature
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
## Context
|
||||
|
||||
The notification API returns the response payload through the existing request wrapper, so frontend API methods should expose the typed `data` payload directly. The home page is shared by agent and enterprise accounts and is loaded after login through `/pages/agent-system/home/index`.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
- Goals: expose notifications, show the newest unread message after login, and keep server read state aligned with what the user has actually seen.
|
||||
- Non-Goals: notification target resolution, controlled-resource routing, push notifications, or a separate manual read button.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Decision: add a dedicated notification page for the notification entry. The entry is placed in the home page's top user-information card, and the page renders notification content only; notification rows have no click navigation.
|
||||
- Decision: the login page writes a short-lived pending-reminder marker after storing a valid session. The home page consumes the marker after loading the authenticated user and requests the newest unread notification.
|
||||
- Decision: use `GET /api/admin/notifications/unread-count` for the entry badge and `GET /api/admin/notifications?is_read=false&page=1&page_size=1` for the login reminder. The notification page requests the newest notification page with `page_size=50`.
|
||||
- Decision: call `PUT /api/admin/notifications/{id}/read` as soon as an unread notification becomes visible in the reminder or notification list, update local state optimistically, and treat the API as idempotent.
|
||||
- Decision: if the unread-count or reminder request fails, keep the home page usable and do not show a fabricated notification. The normal request interceptor continues to handle authentication failures.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Marking on render means a message can become read before the user finishes reading it; this follows the requested “seen means read” behavior.
|
||||
- A notification page displays the first 50 newest records; additional pagination is outside this change unless the API data requires it.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
No data migration is needed. Deploy the frontend after the notification endpoints and icon asset are available. Rolling back removes the entry and UI without changing notification records.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- None for the stated behavior. The entry opens the notification page, while notification content itself never navigates to a controlled target.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Change: Add notification entry and unread reminder
|
||||
|
||||
## Why
|
||||
|
||||
The backend notification contract is documented in `docs/通知.md`, but the frontend does not expose notifications to authenticated agent or enterprise users. Users also have no immediate way to notice newly issued unread messages after signing in.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a notification shortcut to the home page using `src/static/icons/通知.png`.
|
||||
- Add a notification page that lists the current account's notifications in newest-first order.
|
||||
- Show the newest unread notification in a reminder modal after a successful login redirects to the home page.
|
||||
- Mark a notification as read when it is rendered as visible to the user; no manual “mark as read” action is required.
|
||||
- Do not resolve `target` data and do not navigate from a notification to any controlled resource.
|
||||
- Display the unread count on the home-page notification entry when it is available.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: `notifications` (new capability)
|
||||
- Affected code: `src/api/notifications.ts`, `src/pages/agent-system/home/index.vue`, `src/pages/agent-system/notifications/index.vue`, `src/pages.json`, and the login-to-home session flow
|
||||
- Existing user-supplied assets remain in place: `docs/通知.md` and `src/static/icons/通知.png`
|
||||
@@ -0,0 +1,91 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Home notification entry
|
||||
|
||||
The authenticated home page SHALL expose a notification entry for both supported account types. The entry MUST use `src/static/icons/通知.png`, display the current unread count when available, and open the notification page. Notification content MUST NOT resolve controlled targets or navigate to business resources.
|
||||
|
||||
#### Scenario: Agent sees notification entry
|
||||
|
||||
- **GIVEN** an authenticated agent is viewing the home page
|
||||
- **WHEN** the unread-count request succeeds
|
||||
- **THEN** the home page shows the notification icon and the returned unread badge text
|
||||
- **AND** activating the entry opens the notification page without resolving a target
|
||||
|
||||
#### Scenario: Enterprise sees notification entry
|
||||
|
||||
- **GIVEN** an authenticated enterprise user is viewing the home page
|
||||
- **WHEN** the home page renders its shortcuts
|
||||
- **THEN** the notification entry is available with the same icon and behavior
|
||||
|
||||
#### Scenario: Unread-count failure does not block home
|
||||
|
||||
- **GIVEN** the authenticated home page has loaded
|
||||
- **WHEN** the unread-count request fails
|
||||
- **THEN** the home page remains usable
|
||||
- **AND** no fabricated unread count is displayed
|
||||
|
||||
### Requirement: Notification list display
|
||||
|
||||
The notification page SHALL request the current account's non-expired notifications from `GET /api/admin/notifications`, display them newest first using the server order, and show each notification's title, body, category, severity, and creation time. Notification rows MUST be display-only and MUST NOT invoke `GET /api/admin/notifications/{id}/target` or navigate to another business page.
|
||||
|
||||
#### Scenario: Latest notifications are displayed
|
||||
|
||||
- **GIVEN** the notification page is opened
|
||||
- **WHEN** the notification list request succeeds
|
||||
- **THEN** the newest notification is rendered first
|
||||
- **AND** each rendered notification shows its text content and read state
|
||||
|
||||
#### Scenario: No notifications
|
||||
|
||||
- **GIVEN** the notification page is opened
|
||||
- **WHEN** the server returns an empty item list
|
||||
- **THEN** the page shows an empty state
|
||||
- **AND** it does not attempt target resolution
|
||||
|
||||
### Requirement: Post-login unread reminder
|
||||
|
||||
After a successful login redirects to the home page, the system SHALL request the newest unread notification and show it in a reminder modal when one exists. The newest unread notification MUST be the default displayed message. The reminder MUST not navigate to a controlled target.
|
||||
|
||||
#### Scenario: Newest unread notification is shown after login
|
||||
|
||||
- **GIVEN** a user has successfully logged in and is redirected to the home page
|
||||
- **AND** at least one unread notification exists
|
||||
- **WHEN** the home page finishes loading the authenticated session
|
||||
- **THEN** a reminder modal displays the newest unread notification's title and body by default
|
||||
|
||||
#### Scenario: No unread notification
|
||||
|
||||
- **GIVEN** a user has successfully logged in and is redirected to the home page
|
||||
- **WHEN** the unread notification query returns no items
|
||||
- **THEN** no reminder modal is shown
|
||||
|
||||
#### Scenario: Reminder query failure
|
||||
|
||||
- **GIVEN** a user has successfully logged in and is redirected to the home page
|
||||
- **WHEN** the newest unread notification query fails
|
||||
- **THEN** the home page remains usable
|
||||
- **AND** no reminder modal is shown
|
||||
|
||||
### Requirement: Read on visibility
|
||||
|
||||
The system SHALL mark an unread notification as read when its content becomes visible in the reminder modal or notification list. The UI MUST NOT require a manual read button, and it MUST update the local read state after initiating the read request.
|
||||
|
||||
#### Scenario: Reminder marks visible notification read
|
||||
|
||||
- **GIVEN** the newest unread notification is shown in the post-login reminder modal
|
||||
- **WHEN** the modal becomes visible
|
||||
- **THEN** the client calls `PUT /api/admin/notifications/{id}/read` for that notification
|
||||
- **AND** the notification is treated as read locally without a manual action
|
||||
|
||||
#### Scenario: List marks visible unread notifications read
|
||||
|
||||
- **GIVEN** the notification page renders one or more unread notifications
|
||||
- **WHEN** those notification rows become visible
|
||||
- **THEN** the client initiates an idempotent read request for each visible unread notification
|
||||
- **AND** no manual read control is rendered
|
||||
|
||||
#### Scenario: Read request is idempotent
|
||||
|
||||
- **GIVEN** a notification has already been marked read
|
||||
- **WHEN** the client repeats the read request
|
||||
- **THEN** the UI remains in the read state and the repeated request does not create a user-visible error
|
||||
@@ -0,0 +1,18 @@
|
||||
## 1. API and session flow
|
||||
|
||||
- [x] 1.1 Add typed notification models and list, unread-count, and single-read API methods from `docs/通知.md`.
|
||||
- [x] 1.2 Set a pending notification-reminder marker after a valid login session is stored.
|
||||
|
||||
## 2. Notification UI
|
||||
|
||||
- [x] 2.1 Add the notification page and register it in `src/pages.json`.
|
||||
- [x] 2.2 Add the notification shortcut and unread badge to the top user-information card using `src/static/icons/通知.png`.
|
||||
- [x] 2.3 Render notification content without target resolution or controlled-resource navigation.
|
||||
- [x] 2.4 Show the newest unread notification in a post-login home-page reminder modal.
|
||||
- [x] 2.5 Mark each notification read when it becomes visible and remove the manual read action.
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Run `pnpm type-check`.
|
||||
- [x] 3.2 Run the relevant ESLint and style checks.
|
||||
- [x] 3.3 Verify the login-to-home reminder, newest-first display, entry badge, and read-on-visible behavior.
|
||||
Reference in New Issue
Block a user