## Context

系统已经存在 `ArtNotification` 顶部通知组件，但组件中的通知、消息和待办列表都是静态数据，顶部通知按钮处于注释状态。新的通知能力需要同时服务顶部快速查看和完整通知中心，并确保用户在任一入口执行已读操作后未读数与列表状态一致。

## Goals / Non-Goals

- Goals: 提供余额预警、临期提醒、审批结果和系统告警统一的站内通知入口。
- Goals: 在顶部快速查看最近 10 条通知，并提供进入通知中心的入口。
- Goals: 支持通知分类、类型、严重级别和已读状态筛选。
- Goals: 将通知点击导航限制在前端认可的业务目标内，禁止任意 URL 跳转。
- Goals: 单条已读、全部已读、抽屉和通知中心共享同一份未读状态。
- Non-Goals: 不实现 C 端通知页面。
- Non-Goals: 不实现推送通道或服务端通知生成规则。
- Non-Goals: 不让前端根据通知正文推断跳转地址。

## Decisions

- Decision: 通知铃铛放在顶部全局导航的设置按钮和用户头像菜单附近。
- Rationale: 该区域已承载全局设置和用户级入口，适合放置跨页面可访问的通知入口，也符合产品指定位置。

- Decision: 顶部抽屉只加载最近 10 条，完整通知中心使用独立路由 `/notifications`。
- Rationale: 顶部入口保持轻量，筛选和完整历史查询放在独立页面，避免挤占全局导航空间。

- Decision: 未读数使用独立接口获取，单条通知和全部已读成功后立即更新本地共享状态，并以接口返回值为最终结果。
- Rationale: 未读数是全局状态，不能依赖当前抽屉或列表的局部数量推导。

- Decision: 点击通知先调用单条已读接口，再调用目标接口，根据返回的受控 route name/route params 跳转。
- Rationale: 已读状态必须在导航前落库，目标由后端业务引用解析，前端不执行通知携带的任意 URL。

- Decision: 未知 `ref_type` 或目标接口无可用目标时只展示通知正文和状态，不跳转。
- Rationale: 保证安全，同时让无法关联页面的系统通知仍然可读。

- Decision: `unread-summary` 为顶部抽屉分类提供数据，`notifications` 为通知中心筛选列表提供数据。
- Rationale: 顶部快速查看与完整列表的数据量和筛选职责不同，避免顶部加载完整历史数据。

## Data Contract

- Notification item: id, title, content, category, type, severity, read status, created time and optional `ref_type`/reference ID.
- Unread count: non-negative integer; frontend formats it as `0`, `1`-`99` or `99+`.
- Unread summary: category counts and recent notification items, limited to the latest 10 items for the drawer.
- Notification list: paginated items plus total count, with category, type, severity and read-state filters.
- Target response: controlled internal route information, such as route name/path and route params; no arbitrary executable URL.

## Risks / Trade-offs

- Risk: 后端通知字段或枚举名称与文档不一致。
- Mitigation: 在任务阶段先确认字段契约，类型层保留稳定的可选字段和未知值占位展示。

- Risk: 用户在多个标签页同时读通知，单页本地未读数短暂不一致。
- Mitigation: 操作成功后刷新未读数和当前列表；跨标签实时同步不作为本期强制目标。

- Risk: 目标记录已删除或用户权限发生变化。
- Mitigation: 目标接口返回不可跳转时只展示正文，并处理权限/不存在状态，不回退到任意 URL。

## Migration Plan

1. 确认通知列表、摘要、未读数和目标接口字段及枚举。
2. 新增通知 API service、类型和共享状态。
3. 将顶部通知按钮放入设置/头像区域，接入未读数和最近通知抽屉。
4. 新增 `/notifications` 路由及通知中心页面。
5. 实现筛选、单条已读、全部已读和受控目标跳转。
6. 删除或替换 `ArtNotification` 中的静态 mock 数据，并验证四类通知展示一致。

## Open Questions

- 通知中心是否需要分页参数名称 `page/page_size`，以及默认每页数量需要后端确认。
- `category`、`type`、`severity` 和 `read_status` 的枚举值及展示名称需要后端确认。
- 目标接口返回 route name、path 还是 route key + params，需要与路由菜单契约确认。
- 未读数是否需要页面进入时定时刷新或仅在打开抽屉/完成操作时刷新，本期默认按接口调用时机刷新。
- 通知中心菜单权限和按钮权限编码需要后端权限表确认。
