Benachrichtigungen wecken das Telefon wieder: Urgency je Art

Diene hat gemeldet: "Die Benachrichtigungen werden nicht angezeigt,
wenn neue Nachrichten reinkommen. Erst, wenn man die App oeffnet."

Alles Messbare war gruen: Der Service Worker zeigt die Meldung bei
geschlossener App (pruef-push-zu, 13 Pruefungen), jede Anmeldung im
Haus stand auf fehler = 0, der Push-Dienst quittierte mit 201. Nur
den Kopf auf der Leitung hat nie jemand gemessen:

    Urgency: normal

Beide Dienste behandeln das ausdruecklich als "darf warten".
Android/FCM haelt solche Meldungen zurueck, solange das Telefon
doest, und stellt sie zu, wenn es aufwacht -- typischerweise beim
Entsperren oder Oeffnen der App. Apple/APNs nennt es "verzoegert,
gebuendelt oder gedrosselt". Das ist Dienes Satz, Wort fuer Wort,
und es stand als Vorgabe im eigenen Quelltext.

zuletzt_ok konnte das nie zeigen: Es beweist, dass der DIENST
angenommen hat, nicht dass das GERAET etwas angezeigt hat.

Bis hierher hing die Dringlichkeit an der Ruheregel (dringend =
regel === "nie"), mit der Begruendung, "darf das nachts stoeren?"
und "darf das warten?" haetten dieselbe Antwort. Haben sie nicht:
Ein Chat um 3 Uhr soll schweigen, um 14 Uhr aber nicht vierzig
Minuten liegen bleiben. Jetzt zwei Felder -- in DERSELBEN Zeile
derselben Artenliste, damit sie nicht auseinanderlaufen koennen.

10 von 19 Arten sind eilig (Anruf, Chat, Erwaehnung, Support, Hilfe,
Termin, Wecker, zweimal Live, Probe). Die anderen neun duerfen
warten -- waere alles eilig, waere nichts mehr eilig.

DIE FALLE BEIM BEHEBEN: dringend steuerte auch die Haltbarkeit
(TTL 150). Ein einfach auf "dringend" gestellter Chat waere nach
150 s verfallen -- wer sein Telefon drei Minuten aus hat, haette die
Nachricht GAR nicht mehr bekommen. Aus "zu spaet" waere "nie"
geworden. Deshalb sind eilig und kurzlebig getrennt; kurzlebig
bleibt genau beim Anruf und der Probe.

Der alte Name kracht jetzt, statt still "normal" zu liefern.

pruef-push-eilig.mjs (neu, 13 Pruefungen): die Entscheidung je Art
unabhaengig notiert statt aus der Artenliste abgelesen, jede Art
muss eine Entscheidung haben, und der Kopf wird durch
benachrichtige() hindurch an einem nachgebauten Push-Dienst
gemessen. Gegenprobe gelaufen: ohne das Feld meldet sie
"chat_nachricht geht mit Urgency: normal hinaus", 4 Fehler.
Die Uhr ist dort eine Eingabe, keine Annahme -- die Zeitzone wird so
gewaehlt, dass der Lauf immer auf 12 Uhr faellt, sonst waere die
Pruefung nachts rot ohne Befund.

pruef-anruf-klingelt 25 -> 26. Dabei aufgefallen: Eine ihrer
Pruefungen war gruen, obwohl die Zeile aus dem Code verschwunden war
-- sie stand nur noch in einem Kommentar, der die alte Fassung
zitiert. Quelltextpruefungen lesen dort jetzt ohne Kommentare.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-03 12:58:01 +02:00
co-authored by Claude Opus 5
parent db8dd2fbea
commit 73f9b24793
4 changed files with 420 additions and 36 deletions
+19 -3
View File
@@ -223,7 +223,21 @@ export function vapidKopf(endpunkt, paar, absender, stunden = 12) {
* soll NICHT nachtraeglich aufploppen. Deshalb bekommt er eine kurze
* TTL -- ist er vorbei, verfaellt auch die Meldung. */
export async function schicken(anmeldung, text, paar, absender,
{ ttl = 3600, dringend = false } = {}) {
{ ttl = 3600, eilig = false, kurzlebig = false,
...rest } = {}) {
/* DER ALTE NAME MUSS KRACHEN, NICHT DURCHRUTSCHEN (03.10.2026).
Bis heute hiess beides zusammen `dringend`. Wer den alten Namen
weitergibt, bekaeme sonst klaglos `Urgency: normal` -- also genau
den Fehler zurueck, der gerade behoben wurde, und niemand saehe
es. Ein unbekannter Schluessel ist hier deshalb ein Absturz. */
const unbekannt = Object.keys(rest);
if (unbekannt.length) {
throw new Error(
`schicken(): unbekannte Angabe ${unbekannt.join(", ")} -- ` +
`aus "dringend" wurden "eilig" (weckt das Geraet) und ` +
`"kurzlebig" (verfaellt nach 150 s).`);
}
try {
const koerper = verschluesseln(text, anmeldung.p256dh, anmeldung.auth);
const kopf = vapidKopf(anmeldung.endpunkt, paar, absender);
@@ -232,8 +246,10 @@ export async function schicken(anmeldung, text, paar, absender,
method: "POST",
headers: {
...kopf,
TTL: String(dringend ? Math.min(ttl, 150) : ttl),
Urgency: dringend ? "high" : "normal",
/* Haltbarkeit und Dringlichkeit sind zwei Fragen -- siehe
`eiligRegel` in workspace-push.js. */
TTL: String(kurzlebig ? Math.min(ttl, 150) : ttl),
Urgency: eilig ? "high" : "normal",
},
body: koerper,
/* Ein haengender Push-Dienst darf den Lauf nicht aufhalten. */