1.9 KiB
Persistent operation notifications
Updated: 2026-08-02
UserNotifications provides durable, owner-scoped visibility for terminal UserOperations. It is not an email outbox: no SMTP or provider delivery is triggered by this record.
Each operation may have one current notification, enforced by a unique nullable OperationId. Success, permanent failure and cancellation update the operation and insert a generic notification in one relational database transaction. Retryable failures do not notify. Manually retrying a failed or cancelled operation removes its previous terminal notification so its next terminal outcome can create one. Duplicate terminal calls make no change.
Notification text never includes operation inputs, provider diagnostics, failure messages, CV/email/job content or result data. Read and dismiss mutations use the normal owner query filter; dismissed notifications are excluded from lists and unread counts. Authenticated APIs expose list/unread/read/dismiss under /api/notifications.
The frontend /operations page polls only while mounted, shows loading/empty/error/progress/cancellation/retry states and dispatches a local refresh event after notification mutations. The application shell polls only the unread count every 60 seconds; the reminders badge remains separate. The bell links to /operations and has an accessible name.
Migration 20260802225941_AddUserNotifications is EF-owned and absent from startup reconciliation. SQLite uses native scaffolded types; MariaDB uses bounded char/varchar and datetime(6) columns with a foreign key that sets OperationId null if operation history is deleted.
Rollback requires stopping producers/workers, retaining any required notification evidence elsewhere, then applying the migration Down. An older application can run with this additive table still present, which is the safer application rollback. Dropping the table loses notification state.