Objective
- Make inspector mobile push mentions usable for client care: the recipient can tell which job the note refers to without opening the app blindly.
- Make tap-to-open land on the correct inspection notes (including past jobs) whenever the underlying data supports it, instead of leaving the user on whatever screen they had open.
- Preserve or improve sender context in the push title when the author is not stored as an inspector record.
Background
- SE feedback: pushes feel like “generic mentions”; address / job identity is missing unless it happens to appear in the first part of the note body.
- Deep linking today depends on
inspectionIdbeing present in the push data payload; if it is missing, the app does not navigate to the mentioned job—behavior that matches “opens the last work order I had open.” - @inspectors expands to whoever is assigned on the inspection at note-save time only; reassignment later does not create new mention notifications (separate product expectation some users may assume).
- @office group rows use
_membershipId: nulland are skipped by the current push stream handler—out of scope for this story unless product explicitly expands scope. - Mention notifications are only created on note create (
POST /note); PATCH updates do not callcreateMentionNotifications, so edits that add mentions do not re-run that path today.
Scope
Backend — note create and mention fan-out
- New notes and mention handling live in
attik-backend/src/routes/notes.ts: afterNotesave,createMentionNotificationsinattik-backend/src/util/notifications/notificationService.tsruns formentionson the body. Individual@users and@inspectorsboth callcreateNotification, which persistsmetadataincludinginspectionIdfromnote._relatedInspectionIds?.[0],noteId,quoteId,senderId, andmentionType. @inspectorsresolves recipients viagetInspectorMemberships, which readsInspectionand active inspectorMembershiprows—snapshot at create time only.- The
PATCH /:idhandler in the samenotes.tsfile updates fields and saves but does not invokecreateMentionNotifications. - Web and other clients that create notes must supply
_relatedInspectionIdsconsistently when the note belongs to a job; activity-feed patterns appear in e.g.attik-frontend/src/components/activityFeed/NotesInput.tsxandActivityFeed.tsx(related job ids passed when posting).
Backend — push payload
Notificationinserts are watched inattik-backend/src/models/notificationSchema.ts, which forwards inserts tohandleNotificationStreaminattik-backend/src/events/streamHandlers/notificationStream.ts.- That handler builds title via
buildPushTitle(sender name fromInspector.findById(metadata.senderId)), body viastripMentionson the stored message, assembles data (type,notificationId,noteId,target, optionalinspectionId,senderId), and enqueues viaqueuePushfromattik-backend/src/events/bullmq/pushWorker.tsintodispatchPushinattik-backend/src/util/functions/push/pushDispatchService.ts. - Push worker uses a rate limiter (10 jobs per second); large
@inspectorsfan-out can stagger delivery slightly but is orthogonal to missinginspectionId.
Mobile — tap handling
MentionPushDataandgetMentionNavigationPathinattik-mobile/hooks/usePushNotifications.tsrequiretype === "mention"and a truthyinspectionIdto return/inspection/{id}/notes.PushNotificationTapHandlerinattik-mobile/app/_layout.tsxlistens for notification opens (foreground and cold start) androuter.pushes when a path is returned; otherwise it does nothing for navigation.- Token registration uses
POST push/registerinattik-backend/src/routes/push.ts(same queue path conceptually).
Decision needed
- Exact UX for job context on the banner (title vs subtitle vs richer copy) and whether to support fallback routes (e.g.
noteId-only) wheninspectionIdis absent—product and eng should align before implementation.
References
- Expo / device push behavior as configured in
attik-mobile/hooks/usePushNotifications.tsand tap routing inattik-mobile/app/_layout.tsx. - Mention notification metadata shape in
attik-backend/src/models/notificationSchema.ts(metadata.inspectionId,noteId, etc.). - Entry:
attik-backend/src/util/notifications/notificationService.ts(createMentionNotifications,createNotification). - Entry:
attik-backend/src/events/streamHandlers/notificationStream.ts(handleNotificationStream).