Expand description
notifications.* method types — paginated history + ack +
push for incoming notifications.
The notification lifecycle (SPEC §2.12.8 emergency example):
- Operator publishes via backend HTTP API → backend writes to
NATS
NOTIFICATIONSJetStream. - Agent consumes the stream, fans out to connected clients via
notifications.newpush. - User clicks “確認” → client sends
notifications.ack→ agent writesnotifications_readKV (keyed by{pc_id}.{user_sid}.{notification_id}) AND publishesevents.notifications.acked.{pc_id}.{user_sid}.{notification_id}so the SPA can show per-user confirmation status. - Past notifications stay queryable via
notifications.list— that’s the recovery path when the agent missed a push during a network blip.
Structs§
- Audience
Pc - One targeted PC’s confirmation state, for the detail page’s “who
hasn’t confirmed” roster (④). Resolved by expanding the notification’s
fan-out subjects (
all/group.X/pc.Y) to the fleet’s PCs and joining against the recorded acks. - Edit
Notification Request - Operator-facing request body for
PATCH /api/notifications/{id}— edit an already-sent notification’s content (fix a typo, shorten/extend the expiry, change priority / require_ack / toast) without re-sending it. - Notification
- Notification body — used both for
NotificationsListResultentries and theNotificationNewParamspush. - Notification
AckEntry - One recipient’s confirmation record for a notification.
- Notification
AckStatus - Response of
GET /api/notifications/{id}/ack_status— every(pc_id, user_sid, acked_at)tuple recorded for the notification, powering the SPA’s “who confirmed when” view. - Notification
Acked - Body of the
events.notifications.acked.{pc_id}.{user_sid}.{notif_id}event the agent publishes when a user acks a notification. The backend’s notification-acks projector reads these fields from the JSON body (not by parsing the subject) so an id / SID containing a.can’t desync the projected row from its subject tokens. - Notification
Amend - A post-send amendment to an already-fanned-out notification, broadcast
fleet-wide on the ephemeral
crate::subject::NOTIFICATIONS_AMEND_SUBJECTchannel so every connected client showing the notification can react in real time. Carries only the notificationidplus the operation — a client applies it only if it currently holds that id (an id it never received is a no-op), so the single broadcast needs no audience routing. - Notification
Amended Params - Params of the
notifications.amendedpush (Agent → Client) — the flattenedNotificationAmend({ "id", "kind": "recall" }). - Notification
Detail - Response of
GET /api/notifications/{id}— one sent notification’s full content (so the SPA can show “what was sent”, including thebodythe history table truncates away) paired with its per-recipient confirmation list. Powers the deep-linkable/notifications/{id}detail page, which an operator opens in a new tab from the history list (Ctrl/⌘ click), mirroring the Activity → result-detail deep link. - Notification
NewParams - Push payload for
notifications.new. The full notification body inline — no second round-trip needed. - Notification
Target - The audience a notification was addressed to (the
target:of the publish), reconstructed from its fan-out subjects (notifications.{all|group.X|pc.Y}). Distinct from the resolved per-PCAudiencePcroster: this is the operator’s intent (“sent to the it-admins group + PC minipc”), not the expanded PC list. - Notification
Unacked - Body of the
events.notifications.unacked.{pc_id}.{user_sid}.{notif_id}event the agent publishes when a user retracts a confirmation. Mirror ofNotificationAcked; the projector reads these body fields (not the subject) and, in the same stream-ordered consumer, appends akind = 'unacked'row tonotification_ack_eventsand stampsnotification_acks.unacked_atso the SPA roster flips the recipient from confirmed back to “未確認” while the audit log keeps the original ack. - Notifications
AckParams notifications.ackparams — mark this notification read for the caller’s user (SID derived from the OS at connect time, NOT from the payload). SPEC §2.12.4 forbids ack-ing other users’ notifications even on a shared PC — the agent rejects withUnauthorizedif the notification’s audience doesn’t include the caller.- Notifications
AckResult notifications.ackresponse — confirms the agent persisted the ack and published theevents.notifications.acked.>event.- Notifications
List Params notifications.listparams — paginated history of notifications this user has received (per-user, scoped via OS SID).- Notifications
List Result notifications.listresponse.- Notifications
Subscribe Params - Notifications
Subscribe Result - Notifications
Unack Params notifications.unackparams — retract this user’s prior ack (the read↔unread toggle): the user clicked “確認” by mistake and wants the notification back as unread. Same SID-from-the-OS / audience guard asNotificationsAckParams; a user may only unack their own confirmation.- Notifications
Unack Result notifications.unackresponse — confirms the agent deleted thenotifications_readKV entry and publishedevents.notifications.unacked.>. Carries the instant the revoke was recorded (the agent’s wall clock), so the operator’s audit view can show “confirmed at X, retracted at Y”.- Notifications
Unsubscribe Params - Publish
Notification Request - Operator-facing request body for
POST /api/notifications(and the equivalentnotifications/*.yamlmanifest, SPEC §2.4.1). The backend mints theNotification::id(whenidis omitted) andNotification::issued_at, resolvestargetinto thenotifications.{all|group.X|pc.Y}fan-out subjects, and publishes oneNotificationper resolved subject into theNOTIFICATIONSstream. - Publish
Notification Response - Response of
POST /api/notifications— the minted/echoed id plus the subjects the notification fanned out to, so the operator UI can confirm the resolved audience.
Enums§
- Notification
Amend Op - The operation an
NotificationAmendapplies. Tagged onkindso future data-carrying variants (e.g.Update { notification }) stay wire-compatible. - Notification
Priority - Severity ladder. Drives the SPA color, toast/dialog choice, and
whether the Client App grabs window focus on push arrival.
#[non_exhaustive]so a future SPEC can add severities (e.g.Criticalabove Emergency) without a wire bump. - Notifications
Filter - History-list filter selector.