Meldungen: eine Tabelle, 27 fehlende Saetze, und die Pruefung sagt jetzt wo

pruef-meldungen war rot, und zwar schon vor der Arbeit dieser Woche
(mit einer zweiten Arbeitskopie auf HEAD belegt). Gemeldet waren "27
Kennungen ohne deutschen Satz" und drei Seiten, die eine Kennung roh
anzeigen. Nachgemessen war die Lage anders -- und das ist der Kern:

  18 Kennungen hatten NIRGENDS einen Satz. Wer sie traf, las den
     Ersatzsatz "Das hat nicht geklappt" und erfuhr damit nicht, dass
     die Karte entfernt wurde oder dass es zu einer Kachel nur eine
     geben kann.

   9 hatten einen Satz -- aber nur in einer privaten Tabelle in
     manager-ziele.js. Ueber ihr stand als Begruendung woertlich: "An
     EINER Stelle: Stuende jeder dort, wo er gebraucht wird, hiesse
     dieselbe Absage an zwei Stellen verschieden." Der Satz war
     richtig; nur war diese Tabelle selbst inzwischen die zweite
     Stelle. Drei Kennungen standen in BEIDEN mit verschiedenem
     Wortlaut.

ZWEI DER DREI ROHANZEIGEN WAREN FEHLALARME: manager-ziele.js:888 und
:1322 riefen satzZu(d.fehler) -- eine echte Uebersetzung, die die
Pruefung nur nicht kannte. Echt war chat.js:3542 mit
`Ging nicht: ${d.fehler}`.

Gemacht:
  - 27 Saetze nach meldung.js (157 -> 184). Der Wortlaut der neun ist
    aus manager-ziele.js uebernommen, nicht neu erfunden.
  - Zwei Haussaetze seitenneutral gemacht: name_fehlt sprach von einer
    "Karte", nicht_deins von einem "Stueck" -- beide Kennungen kommen
    gemessen von Seiten, die weder Karte noch Stueck haben. Ohne das
    waere das Aufloesen der Zweittabelle eine VERSCHLECHTERUNG gewesen.
  - FEHLERTEXT und satzZu in manager-ziele.js weg, 8 Aufrufe auf
    sagWas umgestellt (gleiche Form: sagWas(fehler, ersatz)).
    manager-ziele.html laedt meldung.js jetzt vor der Seite.
  - chat.js zeigt einen Satz statt der Kennung.

An der Pruefung:
  - PRUEFUNG 4 (neu): Nur die Haustabelle uebersetzt Serverkennungen.
    Ausnahmen werden benannt, mit Gegenwache, dass jede noch existiert.
    Der Sucher ist eng gefasst, weil ein weicherer vier Treffer meldete
    und zwei davon Fehlalarme waren (`leer:` in den Spaltenlisten von
    aufgaben.js und chat.js) sowie einer kein Fehler war (reaktion.js
    uebersetzt schreib_grund in einen Platzhaltertext, nicht fehler:).
  - PRUEFUNG 1 nennt jetzt die Zweitstelle. Ohne das schickt der Befund
    in die falsche Richtung -- wer "27 ohne Satz" liest, schreibt 27
    neue und hat danach drei Tabellen.
  - Die Kommentar-Entfernung steht auf Modulebene, mit Selbsttest und
    drittem Ausgang: raeumt sie alles weg, ist jede Suche darueber
    gruen.

10 Pruefungen, 0 Fehler (vorher 8 mit 2 Fehlschlaegen) -- die Zahl ist
gestiegen, nichts ist stillschweigend weggefallen.

SECHS GEGENPROBEN, alle sechs schlagen an. Drei waren im ersten Lauf
falsch gebaut (CRLF-Anker, Variable statt Schluessel umbenannt, eine
Sabotage die nichts tat) -- das ist jeweils als Begruendung vermerkt,
weil eine blinde Sabotage genauso aussieht wie eine blinde Pruefung.
Gegenprobe 1 hat dabei einen ECHTEN Fehler in meinem neuen Pruefcode
gefunden: woSonst() griff auf `skripte` zu, das erst spaeter angelegt
wird. Im gruenen Zustand laeuft diese Zeile nie -- der Absturz waere
genau dann gekommen, wenn ein Satz fehlt, also wenn man die Meldung am
noetigsten braucht.

Geprueft: meldungen 10, manager-ziele 229, struktur 102, chat 80,
chat-optik 84, chat-anhaenge 168, workspace-seiten 37, formulare 23,
entwicklung 79, xlsx 75, lesbarkeit 14, zeichen 8, deutsche-texte 12 --
alle gruen, keine Zahl gesunken.
This commit is contained in:
2026-10-08 21:15:36 +02:00
parent 0784ad61ce
commit 04cfb06d33
52 changed files with 1081 additions and 744 deletions
+7 -1
View File
@@ -3539,7 +3539,13 @@
});
if (!a.ok) {
const d = await a.json().catch(() => ({}));
melde(d.fehler ? `Ging nicht: ${d.fehler}` : 'Ging nicht.');
/* EIN SATZ, KEINE KENNUNG (08.10.2026). Hier stand
`Ging nicht: ${d.fehler}` -- im schlimmsten Fall also
„Ging nicht: nachricht_zu_lang" auf dem Bildschirm. Der
Ersatzsatz nennt die Stelle, damit er mehr sagt als „Das
hat nicht geklappt": sagWas nimmt ihn nur, wenn es zur
Kennung keinen Satz gibt. */
melde(sagWas(d.fehler, 'Die Nachricht ist nicht rausgegangen.'));
return;
}
const d = await a.json().catch(() => ({}));
+32 -26
View File
@@ -51,25 +51,31 @@
body: JSON.stringify(rumpf),
});
/* Die Sätze zu den Absagen des Servers. An EINER Stelle: Stünde
jeder dort, wo er gebraucht wird, hieße dieselbe Absage an zwei
Stellen verschieden. */
const FEHLERTEXT = {
datum_fehlt: 'Bitte ein Datum angeben.',
datum_zukunft: 'Das Datum liegt in der Zukunft – eintragen kannst du nur, was schon war.',
datum_fremder_monat: 'Das Datum gehört nicht in diesen Monat.',
name_fehlt: 'Bitte den TikTok-Namen angeben.',
link_ungueltig: 'Das sieht nicht nach einer gültigen Internetadresse aus (mit https:// davor).',
art_fehlt: 'Bitte eine Art auswählen.',
schon_eingetragen: 'Das steht diesen Monat schon in deiner Liste.',
monat_gesperrt: 'Dieser Monat ist abgeschlossen und lässt sich nicht mehr ändern.',
nicht_deins: 'Das ist nicht dein Eintrag.',
nicht_erlaubt: 'Dafür fehlt dir die Berechtigung.',
nicht_gespeichert: 'Gespeichert wurde nichts – bitte erneut versuchen.',
ziel_ungueltig: 'Zielzahlen müssen zwischen 0 und 99 liegen.',
};
const satzZu = (schluessel, ersatz) =>
FEHLERTEXT[schluessel] || ersatz || 'Das hat nicht geklappt.';
/* ---- DIE SÄTZE STEHEN IM HAUS, NICHT HIER (08.10.2026) -------
Hier stand eine eigene Tabelle `FEHLERTEXT` mit zwölf Sätzen,
und über ihr als Begründung: „An EINER Stelle: Stünde jeder
dort, wo er gebraucht wird, hieße dieselbe Absage an zwei
Stellen verschieden." Der Satz war richtig -- nur war die
Tabelle selbst inzwischen die zweite Stelle: Das Haus hat seit
dem 19.09.2026 `meldung.js` mit 184 Sätzen.
WAS DAS GEKOSTET HAT, GEMESSEN: Neun Kennungen hatten ihren
Satz NUR hier. `pruef-meldungen` vergleicht gegen die
Haustabelle und meldete sie deshalb als „ohne Satz" -- zu
Recht, denn jede andere Seite, die dieselbe Absage bekommt,
hätte den Ersatzsatz gezeigt. Drei weitere (`name_fehlt`,
`nicht_deins`, `nicht_erlaubt`) standen in BEIDEN Tabellen, mit
verschiedenem Wortlaut -- dieselbe Absage hieß auf zwei Seiten
Verschiedenes, genau das, was der alte Kommentar verhindern
wollte.
`sagWas(fehler, ersatz)` hat dieselbe Form wie das frühere
`sagWas(schluessel, ersatz)`: zweites Argument ist der Satz für
den Fall, dass die Kennung unbekannt ist. Der Tausch ist also
kein Umbau, sondern eine Abschrift weniger. `manager-ziele.html`
lädt `meldung.js` dafür vor dieser Datei -- ohne sie wäre
`sagWas` nicht definiert und aus einer Absage ein Absturz. */
const MONATSNAME = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli',
'August', 'September', 'Oktober', 'November', 'Dezember'];
@@ -440,7 +446,7 @@
if (!antwort.ok && !d.angelegt?.length) {
const erster = d.abgelehnt?.[0];
gelungen(erster?.text || satzZu(erster?.fehler || d.fehler));
gelungen(erster?.text || sagWas(erster?.fehler || d.fehler));
return;
}
@@ -454,7 +460,7 @@
const teile = [n === 1 ? 'Eingetragen' : `${n} eingetragen`];
if (d.abgelehnt?.length) {
teile.push(d.abgelehnt.length === 1
? `1 nicht: ${d.abgelehnt[0].text || satzZu(d.abgelehnt[0].fehler)}`
? `1 nicht: ${d.abgelehnt[0].text || sagWas(d.abgelehnt[0].fehler)}`
: `${d.abgelehnt.length} nicht übernommen (schon vorhanden oder ungültig)`);
}
if (d.warnungen?.length) teile.push(d.warnungen[0].text);
@@ -723,7 +729,7 @@
try {
const a = await hole(`${BASIS}/eintrag/${e.id}`, { method: 'DELETE' });
const d = await a.json().catch(() => ({}));
if (!a.ok) { gelungen(satzZu(d.fehler)); return; }
if (!a.ok) { gelungen(sagWas(d.fehler)); return; }
standSetzen(d.stand);
gelungen('Eintrag gelöscht.');
} catch {
@@ -885,7 +891,7 @@
if (!a.ok) {
/* DER DIALOG BLEIBT OFFEN und behält alles. Vorlage: „Bei
Speicherfehlern geht keine Eingabe verloren." */
fehler.textContent = d.text || satzZu(d.fehler);
fehler.textContent = d.text || sagWas(d.fehler);
knopf.disabled = false;
return;
}
@@ -1257,7 +1263,7 @@
async function zieleOeffnen() {
try {
const a = await hole(`${BASIS}/ziele`);
if (!a.ok) { gelungen(satzZu('nicht_erlaubt')); return; }
if (!a.ok) { gelungen(sagWas('nicht_erlaubt')); return; }
const d = await a.json();
$('ziele-gilt').textContent =
`Die Zahlen gelten ab ${monatText(d.naechsterMonat)}. Der laufende Monat bleibt, wie er ist.`;
@@ -1310,7 +1316,7 @@
for (const feld of $('ziele-felder').querySelectorAll('input[data-rolle]')) {
const wert = Number(feld.value);
if (!Number.isInteger(wert) || wert < 0 || wert > 99) {
fehler.textContent = satzZu('ziel_ungueltig');
fehler.textContent = sagWas('ziel_ungueltig');
feld.focus();
return;
}
@@ -1319,7 +1325,7 @@
try {
const a = await hole(`${BASIS}/ziele`, alsJson({ method: 'PUT' }, { ziele }));
const d = await a.json().catch(() => ({}));
if (!a.ok) { fehler.textContent = satzZu(d.fehler); return; }
if (!a.ok) { fehler.textContent = sagWas(d.fehler); return; }
zieleDlg.close();
gelungen(`Gilt ab ${monatText(d.monat)}.`);
} catch {
+119 -5
View File
@@ -289,8 +289,15 @@
betrag_unklar:
'Diese Zahl ergibt keinen Sinn. Schreib sie in Dogen, '
+ 'zum Beispiel 0,5 oder 2,5.',
/* SEITENNEUTRAL FORMULIERT (08.10.2026). Vorher stand hier
„Ohne Namen keine Karte – er steht ja darauf." Gemessen
schicken diese Kennung aber nur zwei Stellen, und keine von
beiden hat eine Karte: der Monatseintrag (TikTok-Name) und
die Spendenliste (Name der Person). Ein Satz in EINER
Tabelle muss auf jeder Seite wahr sein, die ihn auslösen
kann -- sonst braucht man doch wieder zwei Tabellen. */
name_fehlt:
'Ohne Namen keine Karte – er steht ja darauf.',
'Ohne einen Namen geht es nicht – bitte den Namen eintragen.',
nicht_offen:
'Diese Meldung wartet nicht mehr – jemand hat sie schon entschieden.',
@@ -467,10 +474,13 @@
Er nennt bewusst keine Rollennamen: Wer darf, entscheidet der
Server, und diese Datei lädt jeder herunter. */
/* AUCH SEITENNEUTRAL (08.10.2026). Das Wort „Stück" gibt es nur
im Material; dieselbe Kennung kommt aber auch von den
Monatszielen, wo es „Eintrag" heißt. */
nicht_deins:
'Das darfst du hier nicht ändern. Sag kurz DogFather oder einer '
+ 'der Hände Bescheid — sie können jedes Stück bearbeiten und '
+ 'entfernen.',
'Das ist nicht dein Eintrag – ändern darf ihn nur, wer ihn '
+ 'angelegt hat. DogFather und die Hände können jeden '
+ 'bearbeiten und entfernen.',
/* ---- SICH BEWERBEN STATT SELBST NEHMEN (22.09.2026) ---------
Filipe: „die modis und linke hand sollen da nichts uebernehmen
@@ -536,7 +546,111 @@
dauerhafte_aufgabe:
'Das ist eine dauerhafte Aufgabe — sie wird nicht fertig, sie '
+ 'gehört dazu. Wenn sie nicht mehr gelten soll, kann DogFather '
+ 'oder die rechte Hand sie beenden.'
+ 'oder die rechte Hand sie beenden.',
/* ---- Anleitung pflegen (08.10.2026) -------------------------
Acht Kennungen ohne Satz, gefunden von `pruef-meldungen`. Wer
sie traf, las „Das hat nicht geklappt" -- und erfuhr damit
NICHT, dass die Karte inzwischen entfernt wurde oder dass es
zu einer Kachel nur eine Karte geben kann. Der Ersatzsatz ist
kein Fehler, er ist nur das Letzte, was bleibt. */
serverfehler:
'Da ist im Haus etwas schiefgegangen, nicht bei dir. Versuch es '
+ 'in einer Minute noch einmal — bleibt es dabei, sag DogFather '
+ 'Bescheid; im Protokoll steht, was passiert ist.',
keine_nummer:
'Dieser Aufruf trägt keine brauchbare Nummer. Geh einmal zurück '
+ 'und öffne die Stelle neu, dann stimmt sie wieder.',
kein_schritt:
'Diesen Schritt gibt es für deine Rolle nicht mehr. Lade die '
+ 'Seite neu — dann steht da, was gerade gilt.',
keine_karte:
'Diese Karte gibt es nicht mehr. Vermutlich hat sie jemand '
+ 'entfernt, während du sie offen hattest. Lade die Seite neu, '
+ 'dann siehst du den aktuellen Stand.',
unbekannte_rolle:
'Diese Rolle gibt es in diesem Haus nicht. Nimm eine aus der '
+ 'Liste, dann passt die Zuordnung.',
keine_kachel:
'Ohne eine Kachel lässt sich die Karte nicht zuordnen. Bitte '
+ 'eine auswählen.',
gibt_es_schon:
'Zu dieser Kachel gibt es für diese Rolle schon eine Karte. '
+ 'Bearbeite die vorhandene, statt eine zweite anzulegen — sonst '
+ 'wäre nicht entschieden, welche gilt.',
keine_zeile:
'Diese Zeile gibt es nicht mehr. Lade die Seite neu, dann siehst '
+ 'du, was noch dasteht.',
/* ---- Monatsziele (08.10.2026) -------------------------------
NEUN DAVON HATTEN EINEN SATZ -- in einer zweiten Tabelle in
`manager-ziele.js`. Dort stand als Begründung sogar „An EINER
Stelle: Stünde jeder dort, wo er gebraucht wird, hieße dieselbe
Absage an zwei Stellen verschieden." Genau das war eingetreten:
Die Tabelle WAR die zweite Stelle, und die Prüfung meldete die
Kennungen zu Recht als „ohne Satz" -- sie vergleicht gegen
diese Tabelle hier, und das ist die richtige Frage.
Der Wortlaut ist von dort übernommen, nicht neu erfunden. */
datum_fehlt:
'Bitte ein Datum angeben.',
datum_zukunft:
'Das Datum liegt in der Zukunft – eintragen kannst du nur, was '
+ 'schon war.',
datum_fremder_monat:
'Das Datum gehört nicht in diesen Monat.',
link_ungueltig:
'Das sieht nicht nach einer vollständigen Internetadresse aus – '
+ 'sie fängt mit https:// an.',
art_fehlt:
'Bitte eine Art auswählen.',
schon_eingetragen:
'Das steht diesen Monat schon in deiner Liste.',
monat_gesperrt:
'Dieser Monat ist abgeschlossen und lässt sich nicht mehr ändern.',
nicht_gespeichert:
'Gespeichert wurde nichts – bitte noch einmal versuchen.',
ziel_ungueltig:
'Zielzahlen müssen zwischen 0 und 99 liegen.',
aufgabe_unbekannt:
'Diese Art von Leistung steht nicht in der Liste. Wähle eine aus '
+ '— lade notfalls die Seite neu, dann ist die Liste aktuell.',
nichts_angegeben:
'Es war nichts zum Eintragen dabei. Füll mindestens ein Feld aus.',
nicht_geloescht:
'Das Löschen ist nicht durchgegangen – es steht also noch da. '
+ 'Versuch es noch einmal.',
/* ZWEI ABSAGEN, DIE ABSICHTLICH WENIG SAGEN. Der Server
antwortet hier 404 und nicht 403, damit man nicht erahnen
kann, was es auf einer anderen Adresse gibt (Trennung der zwei
Häuser, 24.09.2026). Der Satz darf das nicht verraten -- aber
er darf auch nicht ratlos machen, deshalb sagt er, an wen man
sich wendet. */
nicht_hier:
'Das gibt es auf dieser Adresse nicht. Wenn du hier etwas '
+ 'erwartet hast, frag kurz DogFather.',
nicht_zustaendig:
'Diese Übersicht gehört zu den Rollen, die Monatsziele haben. '
+ 'Für deine Rolle gibt es sie nicht.',
unbekannt:
'Diese Person gibt es nicht mehr. Wähle sie noch einmal aus der '
+ 'Liste aus.',
/* ---- Event-Kachel: ein Haken an einer Aufgabe (08.10.2026) -- */
punkt_unbekannt:
'Diese Aufgabe steht nicht mehr in der Liste des Events. Lade '
+ 'die Seite neu, dann stimmen die Haken wieder.',
/* ---- Vorlagen: Frist einer Aufgabe (08.10.2026) ------------- */
frist_ungueltig:
'Die Frist ist kein brauchbares Datum. Nimm den Kalender im '
+ 'Feld, dann stimmt die Schreibweise von allein.',
frist_vergangen:
'Diese Frist liegt schon hinter uns. Eine Aufgabe, die bei der '
+ 'Vergabe bereits abgelaufen ist, hilft niemandem — nimm einen '
+ 'Tag ab heute.',
dauerhaft_nicht_erlaubt:
'Eine dauerhafte Aufgabe können nur DogFather und die rechte '
+ 'Hand anlegen. Mit einer Frist geht es für dich.'
};
/* Sieht das wie eine Maschinenkennung aus?