What is missing
A customer with an open support ticket only learns about a reply by opening the app and looking. The chat itself is now a chat — bubbles, day separators, delivery ticks, paste, retry — but it still waits for the customer to come to it. That is the one structural difference to any messenger they use, and no amount of polish inside the screen closes it.
Today the only nudge is the notification mail, and answering it means clicking back into the app.
Why this is not a frontend addition
Checked against develop in both repositories:
DFXswiss/services has no service worker. No service-worker.ts, no registration in index.tsx. Web Push needs one, and CRA needs it configured explicitly.
DFXswiss/api has no push path at all. web-push, vapid and pushSubscription return zero hits across src/. There is nothing to extend — subscriptions have to be stored, addressed and sent to.
So the work spans:
| Where |
What |
| api |
entity for a push subscription + migration, endpoint to register and revoke one, sending on a new support message |
| api ↔ server repo |
VAPID keys as deployment configuration — read at boot, so fail-loud; needs the same handover as any other boot-critical variable |
| services |
service worker, registration, permission prompt, and a way to turn notifications off again |
The product decision that comes first
When does the app ask for permission? Asking on first load is the reliable way to collect a "no" that the browser then remembers — and a denied permission is hard to recover from. Asking after the customer sends their first support message is the moment they actually want to be reached. This is a decision to make before anything is built, not after.
Second decision: what the notification says. A support reply can contain personal details, and a notification is visible on a locked screen. "You have a new message about ticket #8412" is safe; the message text is not.
Not a substitute, but cheap
The notification mail already exists. Making its link land directly in the right ticket is a fraction of the work and helps the same customer on a second device. The chat currently drops the ticket id from the address after opening (chat.screen.tsx, navigate('/support/chat', { replace: true })), so today that link cannot work even if the mail carried it.
Scale
No production measurement of how many customers use the chat rather than answering the mail — that number should be pulled before the api work is scheduled, since it decides whether this is worth a migration. What is known: /support/chat is the only in-app way to follow a ticket, and every ticket goes through it.
Where this comes from
Found while making the customer chat behave like a chat in #1297. Four gaps were closed there — colours and day separators, pasting screenshots, keeping the reader's place, reporting the errors the customer sees. This is the fifth and the only one that needs a backend.
What is missing
A customer with an open support ticket only learns about a reply by opening the app and looking. The chat itself is now a chat — bubbles, day separators, delivery ticks, paste, retry — but it still waits for the customer to come to it. That is the one structural difference to any messenger they use, and no amount of polish inside the screen closes it.
Today the only nudge is the notification mail, and answering it means clicking back into the app.
Why this is not a frontend addition
Checked against
developin both repositories:DFXswiss/serviceshas no service worker. Noservice-worker.ts, no registration inindex.tsx. Web Push needs one, and CRA needs it configured explicitly.DFXswiss/apihas no push path at all.web-push,vapidandpushSubscriptionreturn zero hits acrosssrc/. There is nothing to extend — subscriptions have to be stored, addressed and sent to.So the work spans:
The product decision that comes first
When does the app ask for permission? Asking on first load is the reliable way to collect a "no" that the browser then remembers — and a denied permission is hard to recover from. Asking after the customer sends their first support message is the moment they actually want to be reached. This is a decision to make before anything is built, not after.
Second decision: what the notification says. A support reply can contain personal details, and a notification is visible on a locked screen. "You have a new message about ticket #8412" is safe; the message text is not.
Not a substitute, but cheap
The notification mail already exists. Making its link land directly in the right ticket is a fraction of the work and helps the same customer on a second device. The chat currently drops the ticket id from the address after opening (
chat.screen.tsx,navigate('/support/chat', { replace: true })), so today that link cannot work even if the mail carried it.Scale
No production measurement of how many customers use the chat rather than answering the mail — that number should be pulled before the api work is scheduled, since it decides whether this is worth a migration. What is known:
/support/chatis the only in-app way to follow a ticket, and every ticket goes through it.Where this comes from
Found while making the customer chat behave like a chat in #1297. Four gaps were closed there — colours and day separators, pasting screenshots, keeping the reader's place, reporting the errors the customer sees. This is the fifth and the only one that needs a backend.