e378514bb4ba97a39702bdce7543a0068cdf8ffc
26
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2a26a49f91 |
Mit "@" jemanden im Chat ansprechen
Filipe: "ich will das man die leute mit @ markieren kann im chat."
MARKIEREN IST KEINE FARBE, SONDERN EINE ANSPRACHE. Sie funktioniert
nur, wenn drei Dinge zusammen stimmen: Der Richtige ist gemeint, er
MERKT es, und man sieht es im Satz. Fehlt eines davon, ist es eine
Attrappe -- und zwar eine, die gut aussieht.
WER GEMEINT IST, ENTSCHEIDET DER SERVER. Der Browser schickt nur Text.
Damit wirkt ein von Hand getipptes "@VanVan" genauso wie eines aus der
Auswahlliste, und niemand kann jemanden ansprechen, der gar nicht im
Raum sitzt -- auch nicht ueber die Schnittstelle.
Die Regeln stehen in server/chat-erwaehnung.js, jede mit Begruendung.
Zwei davon sind keine Feinheit, sondern der Unterschied zwischen
brauchbar und laestig:
* Das Zeichen VOR dem "@" darf kein Buchstabe sein. Sonst piepst
jede E-Mail-Adresse im Chat jemanden an
("[email protected]").
* Das Zeichen DANACH auch nicht, und der laengste Name gewinnt.
Sonst spricht "@Tilikum" Tili an.
MAN MERKT ES AUCH OHNE OFFENEN RAUM. Eine Zahl in der Gespraechsliste
sagt "hier ist etwas" -- nicht, ob es an dich war. Wer morgens vier
Raeume mit Zahlen sieht, macht den lautesten zuerst auf, und dort
steht selten das, was auf ihn wartet. Jetzt steht ein "@" daneben.
UND DIE MELDUNG AUFS HANDY SAGT ES: "VanVan hat dich erwaehnt" statt
"Nachricht von VanVan". Als EIGENE Art, die sich getrennt abschalten
laesst -- wer den lauten Chat stumm stellt, will trotzdem wissen, wenn
ihn jemand direkt anspricht. Ohne Ausnahme von der Ruhezeit: Ein Anruf
wartet auf eine Antwort, ein "@Anna" nicht.
DIE AUSWAHL BEIM TIPPEN loest drei Dinge, die man sonst selbst wissen
muesste: wie die Person genau heisst, wer ueberhaupt im Raum ist, und
ob man sich vertippt hat. Tastatur zuerst (Pfeile, Enter, Tab, Escape).
Sie erzwingt nichts -- wer weitertippt, schreibt einfach weiter.
ZWEI RECHNUNGEN, EINE ANTWORT: Der Browser braucht dieselbe Aufloesung,
um sofort hervorzuheben. Genau dort laufen Dinge auseinander, und dann
haette die Seite jemanden hervorgehoben, den niemand benachrichtigt
hat. pruef-erwaehnung LIEST die Browserfassung aus der Datei und fuehrt
sie aus -- ein Nachbau wuerde pruefen, ob ich zweimal dasselbe
schreiben kann.
---- DABEI GEFUNDEN: "gelesen bis 999999" ----------------------------
Der Server nahm fuer den Lesestand JEDE ganze Zahl an. Wer einmal eine
Zahl hinter allem Vorhandenen schickte, sah in diesem Gespraech nie
wieder einen Zaehler und nie wieder ein @-Zeichen: Alles Kuenftige galt
als gelesen, bevor es geschrieben war. Das faellt niemandem als
Zusammenhang auf -- man merkt nur, dass "die Benachrichtigungen nicht
gehen".
Der Browser schickt heute immer die letzte gesehene Nummer, ist also
nicht der Grund. Aber eine Grenze, die nur davon lebt, dass der
Aufrufer sich benimmt, ist keine. Jetzt wird auf die juengste
Nachricht des Raums begrenzt -- abgeleitet, nicht geraten.
Gefunden hat es meine eigene Pruefung: Sie setzte zum Aufraeumen 99999
und wunderte sich danach, warum das frische "@" nicht leuchtete.
WOHER MAN ERFAEHRT, DASS ES DAS GIBT: Im Chat gibt es keinen
Hilfeknopf. Der Hinweis steht deshalb im Leersatz einer neuen Gruppe --
dort, wo man beim ersten Oeffnen ohnehin hinsieht, und nur ab drei
Leuten. In einem Zweiergespraech waere er Ballast.
GEPRUEFT: pruef-erwaehnung 67/0 (neu) -- 13 Regelfaelle ohne Server,
der Weg durch die Schnittstelle, das Zeichen in der Liste samt
Gegenprobe bei jemandem, der dabei aber nicht gemeint war, beide
Aufloesungen nebeneinander, und der ganze Ablauf am echten Bildschirm
bis "Enter waehlt und schickt NICHT ab".
Dazu pruef-chat 48/0, pruef-chat-optik 36/0, pruef-treffchat 110/0,
pruef-chat-kanaele 79/0, pruef-glocke 31/0, pruef-push 24/0,
pruef-anruf-klingelt, pruef-css-klassen, pruef-meldungen,
pruef-nachfrage, pruef-tippziele.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
0f5faf7ee6 |
Eine Seite, die nicht laedt, sagt es -- und bietet einen Weg zurueck
Fuenf Suchlaeufe parallel, ihre Funde selbst nachgemessen und behoben.
DER GROESSTE: 13 VON 21 SEITEN SCHLUCKTEN JEDEN NETZFEHLER.
Jede Seite beginnt mit `try { await hole('/api/ich') } catch { return; }`.
Faellt das Netz aus -- Aufzug, U-Bahn, Funkloch --, bricht der Block ab,
und die Seite bleibt fuer immer auf "wird geladen …" stehen. Gemessen:
0 von 32 Stellen setzten `aria-busy` im Fehlerfall zurueck, und es gab
KEINEN EINZIGEN "Nochmal versuchen" auf allen 21 Seiten.
Im Code stand der richtige Satz dazu -- an genau einer Stelle:
"Ein Platzhalter, der nie ersetzt wird, ist eine Luege mit
Fortschrittsanzeige." Er galt ueberall ausser dort.
Neu: window.ladefehler() in meldung.js. Sie ersetzt alles, was gerade
"laedt", durch drei Dinge: was los ist, was das bedeutet, und einen
Knopf, der es noch einmal versucht -- ohne die Seite neu zu laden.
21 Dateien angeschlossen. Neu: server/pruef-ladefehler.mjs, 26/0, mit
abgeklemmtem Netz im echten Browser.
UND DIE STARTSEITE WARF BEI EINEM FUNKLOCH AUF DIE ANMELDUNG.
`catch { location.assign('/workspace/') }` -- der Mensch glaubt, er sei
rausgeworfen, und tippt seinen Code neu. Dabei haelt seine Sitzung 12
Stunden; nur die Anfrage kam nicht durch. Umgeleitet wird jetzt nur
noch bei einer ANTWORT, die das sagt (401).
DER ANMELDEHINWEIS FUEHRTE MODIS IN DIE SPERRE.
Nach zwei Fehlversuchen stand: "Stimmt die Auswahl oben? Ein Code
gehoert immer zu genau einer davon." Auf der Crew-Wand ist das FALSCH
-- `stillerZugang()` sucht ueber die Codekennung, die angetippte
Kachel spielt fuer hand/modi keine Rolle. Sie probieren alle vier
durch, sammeln vier Fehlversuche, und nach acht in zehn Minuten ist
ihre Adresse gesperrt. Ein Hinweis, der die Sperre herbeifuehrt, gegen
die er helfen soll. Auf der Agenturwand stimmt der Satz weiter --
deshalb wird gefragt, auf welcher Wand man steht.
Dazu: Die Crew-Wand nannte nur der Community einen Weg ("Frag im Live
nach"). Wer zum Team gehoert und dessen Code nicht geht, fand dort
niemanden.
SACKGASSE AUF DER KERNSEITE EINES MODI.
treff-moderation sagte: "Zugaenge legst du in 'Personen & Zugaenge'
an" -- eine Seite, die ein Modi nicht oeffnen darf. Am ersten Tag, bei
leerer Community, war das der einzige Satz im Abschnitt. Jetzt fragt
die Seite ueber `window.__ich.seiten`, ob es den Weg fuer DIESEN
Menschen gibt. Und ein 404 wirft ihn nicht mehr wortlos auf die
Startseite.
TOTE KNOEPFE AN FREMDEN KARTEN.
"◀ zurueck" und "▶ In Arbeit" standen an JEDER Aufgabenkarte, auch an
fremden. Ein Modi sieht das Brett des ganzen Teams; er tippt, der
Server lehnt mit 403 ab, und die Meldung erscheint GANZ OBEN. Bei
einer Karte weiter unten sieht er nichts. Zwei Zeilen tiefer stand die
Regel im Klartext: "niemandem etwas anzubieten, das dann abgelehnt
wird." Der Server schickt jetzt `darf_aendern` mit.
13 STELLEN ROLLTEN GEGEN DEN WILLEN DES NUTZERS.
`scrollIntoView({ behavior: 'smooth' })` beachtet "Animationen
reduzieren" NICHT. Wer das eingestellt hat, hat es meist wegen
Schwindel getan. Zwei Stellen fragten vorher, dreizehn nicht.
Jetzt `window.sanft()`, einmal statt dreizehnmal.
DAS WORT UEBER DEN BRETTERN EINES MODI HIESS "BETREUUNG".
Fest im HTML, ueberschrieben nur bei Brettern mit eigenem `ober` --
sechs haben keines. Jetzt faellt es auf die GRUPPE der Kachel zurueck,
ueber die er hergekommen ist. Je Rolle richtig, ohne zweite Liste.
DER HINWEIS-ZU-KACHEL-WEG WAR DOPPELT KAPUTT.
`bereichZu` suchte nur in GRUPPEN -- der Liste der AGENTUR. Die
Kacheln von Team Dogi schickt der Server; fuer einen Modi fand die
Zeile entweder nichts oder eine fremde Kachel und uebernahm deren
Farbe. Und sie suchte ueber den NAMEN: "LIVE-Analyse" heisst auf der
Crew-Adresse "Live-Ablauf". Beim Beheben erst den Namen umgedreht --
und damit die Agenturseite kaputt gemacht (pruef-start-ansicht sofort
rot). Jetzt ueber das ZIEL, das in beiden Haeusern dasselbe ist.
UND EIN BRETT WAR SEIT GESTERN GESPERRT.
`TREFF_BRETTER` wird aus Kachelzielen abgeleitet. Als die Kachel
"Regeln & Hilfe" am 19.09. auf `treff-regeln.html` umgelenkt wurde,
fiel `regeln` heraus -- und `treff-regeln.html` verweist weiterhin
darauf ("Haeufige Fragen stehen auf dem Brett Regeln & Hilfe").
Gefunden hat es pruef-treff, die seit gestern rot war. 72/0.
NEBENBEI 7 SEITEN LEICHTER: meldung.js wird jetzt abgeleitet
eingebunden -- nur dort, wo sagWas/ladefehler/sanft wirklich
gebraucht werden. Die Anmeldewand traegt es nicht mehr.
Gruen: pruef-ladefehler 26/0, pruef-sackgassen 11/0 (582 Wege, 0 ins
Leere), pruef-start-ansicht, pruef-treff 72/0, pruef-treffchat,
pruef-community-sicht 10/0, pruef-aufgabenbrett, pruef-code 17/0,
pruef-chat-optik, pruef-nachfrage 49/0, pruef-meldungen 8/0,
pruef-css-klassen, pruef-tippziele 11/0, pruef-leerzustand 13/0,
pruef-rechtetafel.
|
||
|
|
cc39552b4f |
Eine Eingabe geht nicht mehr wortlos verloren
Filipe: "Was passiert, wenn jemand eine Funktion abbricht?" GEMESSEN: Acht Dialoge im Workspace enthalten Eingabefelder -- "Aufgabe bearbeiten" (10 Felder), der Tageseintrag in der Leistung (8), Ziele, Netzwerk, Import, ein neuer Chat-Raum, ein Creator. Bei allen galt: Esc, Klick daneben oder "Abbrechen" wirft ALLES weg, wortlos. Wer zehn Felder ausgefuellt hat und mit dem Daumen den Rand trifft, faengt von vorn an. Neu: window.verwurfWache() in nachfrage.js. BEIDE SCHLIESSWEGE, denn sie laufen verschieden: Esc / Klick daneben loest `cancel` aus, close() wird NICHT gerufen "Abbrechen"-Knopf ruft close(), loest kein `cancel` aus Wer nur einen abfaengt, hat eine halbe Sicherung -- und die ist schlimmer als keine, weil man ihr vertraut. NICHT VON HAND VERTEILT: Jeder Dialog mit Feldern bekommt sie automatisch (ausser dem Nachfrage-Dialog selbst -- er wuerde beim Schliessen nach sich selbst fragen, in sich selbst, und haenge fuer immer). Wer morgen einen neunten baut, hat sie, ohne daran zu denken. UND SIE FRAGT NUR BEI WIRKLICHER AENDERUNG. Beim Oeffnen wird ein Abbild der Felder genommen, beim Schliessen verglichen. Wer einen Dialog aufmacht und gleich wieder zu, merkt nichts. ZWEI SACHEN BEIM BAUEN GEMESSEN STATT VERMUTET: MEINE EIGENE "ROBUSTHEIT" HAT DIE WACHE STILL AUSGESCHALTET. Gegen den Fall "Felder werden erst nach dem Oeffnen gefuellt" hatte ich einen zweiten Schnappschuss beim Hineinklicken (`focusin`) eingebaut. Gemessen: Der entstand NACH dem Tippen -- Fokus und Werteingabe passieren im selben Atemzug. `beimOeffnen` war danach gleich dem getippten Text, und der Dialog ging wortlos zu. Die Sicherung sah eingebaut aus und tat nichts. Jetzt wird im naechsten BILD nachgetragen: Was das Skript beim Oeffnen nachtraegt, ist drin; getippt haben kann in derselben Sechzehntelsekunde niemand. (Nachgemessen: Alle acht Dialoge fuellen heute VOR showModal.) ZWEIMAL ESC HINTEREINANDER SCHLIESST TROTZDEM. Das ist Chromiums "close watcher": Eine Seite darf den Nutzer nicht mit Esc einsperren. Die Regel ist richtig; dagegen anzubauen waere falsch. Sie steht deshalb im Code und in der Pruefung -- festgehalten, nicht umgangen. Der Knopf unterliegt ihr nicht, und am Handy gibt es ohnehin kein Esc. Elf Speicherwege rufen `vergessen()`, damit nach erfolgreichem Speichern nicht gefragt wird. Eine Warnung nach dem Speichern waere genau die, die man wegklickt -- und danach auch die echte. pruef-nachfrage 49/0 (war 33), davon zehn am Bildschirm: unberuehrt geht er ohne Nachfrage zu nach einer Aenderung fragt Esc nach, der Dialog bleibt offen "Weiter bearbeiten" laesst ihn offen UND der Text steht noch da auch der Abbrechen-Knopf fragt -- jedes Mal "Verwerfen" schliesst wirklich, und der Text steht nirgends pruef-aufgabenbrett, -leistung, -uebersicht-browser, -chat-optik, -css-klassen gruen, pruef-tippziele 11/0. |
||
|
|
0a2363374c |
Eine Nachricht, die nicht ankommt, sieht man jetzt -- und schickt sie neu
DER KOMMENTAR STAND DA, DIE SACHE NICHT. Im Chat stand woertlich: "NICHT STILL VERSCHWINDEN LASSEN. Wer etwas schreibt und es sieht, glaubt, es sei angekommen." Gemessen: `markiereAlsGescheitert` setzte `n.gescheitert = true` -- und gelesen hat das Merkmal NIEMAND, weder das Skript noch das CSS. Eine gescheiterte Nachricht sah exakt aus wie eine zugestellte. Im CSS stand an der Stelle eine leere Regel mit dem Kommentar "Platzhalter, damit :has unterstuetzt bleibt". Ein Kommentar, der eine Absicht beschreibt, erfuellt sie nicht. Jetzt: sichtbare Kante an der Blase, blasse Darstellung solange sie unterwegs ist, und ein Knopf "Nochmal senden" daneben. Der Satz in der Meldezeile bat vorher ums Kopieren -- fuenf Handgriffe fuer etwas, das die Seite in einem tun kann; den Text hat sie ja noch. KEIN ZWEITER SENDEWEG: Der Knopf legt den Text zurueck ins Feld, stellt das Antwortziel wieder her und ruft `abschicken`. Ein eigener Weg waere morgen anders als dieser, und der Unterschied fiele erst auf, wenn er zaehlt. "ZUM NEUESTEN" STAND AUF EINER RECHNUNG VON GESTERN: `bottom: 96px` -- die Hoehe der Schreibleiste an dem Tag, an dem der Knopf gebaut wurde. Das Textfeld waechst aber bis 160. Wer lange tippt und gleichzeitig oben liest, hatte den Knopf HINTER der Leiste. Und darueber koennen noch das Nachtruhe-Band und der Hochlade-Balken stehen. Jetzt misst die Seite den ganzen Unterbau selbst -- ueber einen Beobachter statt einer Liste von Ausloesern, denn das Band erscheint um Mitternacht von selbst. Kommt morgen ein viertes Bauteil dazu, rechnet es von allein mit. NEUE PRUEFUNG FUER EINEN WEG, DEN NIE ETWAS GEPRUEFT HAT: pruef-chat-optik faengt die Sendeanfrage jetzt einmal ab und geht den ganzen Fehlerweg durch -- 10 Aussagen, darunter: der Unterschied ist auch zu SEHEN, nicht nur im Merkmal (Rand 1px) die Nachricht steht danach GENAU EINMAL da, nicht doppelt und sie ist beim Gegenueber angekommen Der letzte ist der eigentliche: Alles davor koennte gut aussehen und trotzdem nichts zugestellt haben. pruef-treffchat war seit gestern rot -- 8 Fehler ueber "undefined". Sie suchte die Kachel mit `ziel === "chat.html"`, seit dem 19.09. heisst es `chat.html?raum=treff` (sie fuehrt direkt in den Raum). Kein Befund ueber das Haus, sondern einer ueber sich selbst. Sie sucht jetzt nach der SEITE und prueft statt des Wortlauts das, worauf es ankommt: Man erkennt den Chat, und der Name kommt genau einmal vor. 110/0 statt 108 mit 8 Fehlern. pruef-chat, -anhaenge, -kanaele, -optik, -ausbau gruen, pruef-start-ansicht 151/0, pruef-tippziele 11/0, pruef-nachfrage 33/0, pruef-leerzustand 13/0, pruef-meldungen 8/0, pruef-css-klassen gruen. |
||
|
|
1207b79a33 |
Hochladen sieht man jetzt, Leerzustaende sagen was hingehoert
DREI BLOECKE AUS DEM PERFEKTIONSLAUF.
1. HOCHLADEN MIT FORTSCHRITT UND ABBRUCH
Alle fuenf Wege (Dateien, Chat-Anhang, Wissen-PDF, Aufgaben-Anhang,
Profilbild) benutzten `fetch`. Das kann beim SENDEN nicht sagen, wie
weit es ist -- sichtbar war "wird hochgeladen …", von der ersten bis
zur letzten Sekunde gleich. Bei 40 MB im Mobilfunknetz zwei Minuten.
Wer das sieht, drueckt noch einmal und laedt dieselbe Datei doppelt.
Neu: workspace/assets/js/hochladen.js (XMLHttpRequest, das Einzige,
was `upload.onprogress` kann) samt gemeinsamer Anzeige.
Drei Ausgaenge: fertig / abgebrochen / schiefgegangen -- und ein
Abbruch ist KEIN Fehler und bekommt keine rote Meldung.
DABEI AUFGEFALLEN: KEINE EINZIGE PRUEFUNG im Haus laedt eine Datei
ueber die Oberflaeche hoch. Der ganze Umbau waere gruen gewesen,
ohne dass ein Byte je den Weg der Nutzer gegangen waere.
Neu: server/pruef-hochladen.mjs -- 18/0, mit echter Datei.
Zwei Irrtuemer beim Bauen, beide gemessen statt vermutet:
Ohne Drosselung gibt es auf localhost EINEN Fortschritt-Stand.
Das sah nach Befund aus und war keiner. Jetzt 2 MBit/s ueber
CDP -- derselbe Verlauf wie bei den Modis im Mobilfunk, 57
gemessene Zwischenstaende.
Gewartet wurde auf den Dateinamen "irgendwo im Dokument" -- der
stand auch im Fortschrittsbalken. Die Bedingung war erfuellt,
bevor etwas angekommen war.
2. LEERZUSTAENDE
Elf von 18 Brettern fielen auf "Noch kein Eintrag in diesem
Bereich" zurueck. Am ersten Tag ist ALLES leer -- wer da achtzehn
Bretter oeffnet und achtzehnmal denselben Satz liest, lernt nichts
ueber die Bretter, sondern dass das System kaputt ist. Jeder Satz
sagt jetzt, was hier hingehoert UND was der naechste Schritt ist.
Neu: server/pruef-leerzustand.mjs -- 13/0, leitet die Bretter aus
BEREICHE ab; ein neunzehntes ohne Satz macht sie rot.
3. ABMELDEN UND KONTRASTMODUS
Abmelden war am Handy ein 44-Pixel-Zeichen neben Glocke und Suche,
sofort wirksam. Teurer als es aussieht: Zum Wiederanmelden braucht
man den Zugangscode, und den gibt es EINMAL. Jetzt mit Rueckfrage,
die genau das sagt -- und dazu, dass Zumachen reicht (12 Stunden).
Kontrastmodus: 68 Regeln zeigen einen Zustand NUR ueber Farbe
(35x aria-pressed, 33x data-an). Der Modus ersetzt alle Farben und
entfernt box-shadow -- gedrueckt sah aus wie nicht gedrueckt.
14 CSS-Dateien hatten gar keinen Block. Statt 14 Bloecke zu pflegen
eine Regel in gate.css, die den ZUSTAND trifft statt die Datei.
Gemessen mit forcedColors: active -- vorher ununterscheidbar,
jetzt `solid 2px Highlight`.
Was seinen Zustand als WORT traegt (.marke-status, .t-stufe,
.spalte), braucht nichts -- nachgesehen, nicht vermutet.
PRUEFUNGEN, DIE AUF confirm() WARTETEN: Fuenf Dateien benutzten
`seite.once("dialog", d => d.accept())`. Playwright faengt confirm()
selbst ab, einen <dialog> nicht -- pruef-chat-anhaenge meldete acht
Fehler, keiner davon im Code. Neu: server/helfer-nachfrage.mjs, der
beide Wege kennt (auch den Notnagel fuer Safari vor 15.4).
pruef-chat-anhaenge, -ausbau, -optik und pruef-code wieder gruen.
hilfeAufraeumen bleibt ausgeschaltet -- das loescht echte Daten und
ist Filipes Entscheidung.
|
||
|
|
c516aad4ed |
Nichts verschwindet mehr ohne eine Nachfrage, die sagt was passiert
Filipe: "Es darf vor allem keine Stellen geben, an denen ein Benutzer
etwas falsch machen kann, nur weil die Seite es nicht verstaendlich
genug erklaert."
Gemessen: 30 Stellen in 16 Dateien benutzten confirm() oder prompt().
Das Haus hatte die richtige Bauweise laengst -- einen <dialog>, in
aufgaben.html sogar ausfuehrlich begruendet -- aber sie stand IN EINER
SEITE. Wer anderswo etwas loeschen liess, hatte sie nicht.
confirm('Wirklich loeschen?') stellt die falsche Frage: Es fragt, ob
man sicher ist, und nennt nicht, WAS passiert, was BLEIBT und ob es
ZURUECK geht. Jetzt beantwortet jeder der 41 Dialoge alle drei.
Neu: workspace/assets/js/nachfrage.js -- window.frageNach() mit
Pflichtgrund, Zahlenfeld, einzeiliger Eingabe und Abtippsicherung.
Drei Ausgaenge: <dialog> / confirm()-Notnagel fuer Safari vor 15.4 /
Abbruch (Esc, Klick daneben, "Doch nicht" -- immer false).
DREIMAL DERSELBE FALLSTRICK, dreimal nachgemessen statt vermutet:
.dialog stand in aufgaben.css und leistung.css -> auf dateien.html
waere der Dialog ein weisser Systemkasten gewesen. 14 Regeln
klammergenau nach module.css verschoben (Klammern gezaehlt, nicht
per Muster geschnitten -- heute frueh hat ein nicht-gieriges
Muster schon einmal CSS zerrissen).
Das Formular trug .neu neu--blank -- und .neu gibt seine Abstaende
nur in aufgaben.css. Gemessen: padding 0px, und die Felder
verloren ihre height:44px. Jetzt steht alles unter
.nachfrage__form in module.css; der Dialog borgt nichts mehr.
Die erste Fassung der Pruefung zaehlte nachfrage.js SELBST als
Nutzer -- damit war jede Seite trivialerweise "Nutzer" und die
Pruefung gruen ohne Inhalt. Jetzt ausdruecklich ausgenommen.
ZWEI FUNDE NEBENBEI:
hilfeAufraeumen() wird im Betrieb NIE aufgerufen. Der Kommentar
behauptete "wird beim Start aufgerufen (siehe index.js)" -- das
war nie wahr; einziger Aufrufer ist die eigene Pruefung. Folge:
geschlossene vertrauliche Faelle bleiben unbegrenzt stehen. NICHT
eingeschaltet (das loescht echte Daten und ist Filipes
Entscheidung), sondern der Kommentar richtiggestellt.
Einen Hilfe-Fall zu schliessen ist endgueltig -- es gibt keine
Route, die ihn wieder oeffnet. Vorher stand darueber nur die
Frage nach einem Schlusswort. Jetzt sagt der Dialog es.
pruef-struktur hat meine eigene Pruefung von heute Nachmittag
erwischt: Sie bildete ihr Datum aus UTC. Beim Beheben erst
heuteLokal(datum) genommen -- die Funktion nimmt gar kein Argument
und haette still "heute" statt "+3 Tage" geliefert. Jetzt tagLokal(3),
nachgerechnet: Abstand 3 Tage.
Am Bildschirm angesehen (Rechner 1280, Handy 390): passt rein, Esc
ergibt false, Fokus liegt auf dem harmlosen Knopf, Knoepfe 44px auf
Touch. Der Platzhalter im Abtippfeld zeigte den erwarteten Namen --
das sah aus wie ein schon ausgefuelltes Feld, entfernt.
Neu: server/pruef-nachfrage.mjs -- 17/0, mit sechs Gegenproben und
beiden Richtungen (wer fragt, laedt die Datei; wer nie fragt, laedt
sie nicht -- sonst truege die Anmeldewand 4,8 KB fuer nichts).
pruef-meldungen 8/0, pruef-css-klassen gruen, pruef-struktur gruen,
pruef-leistung gruen.
|
||
|
|
d6df590224 |
Telefonieren ging nur ueber UDP -- und die Seite sprang immer hoch
=== 1. WARUM TELEFONIEREN NICHT GING ===
Filipe: "es klingelt erscheint auch alles bei jedem aber telefonieren
klappt immer noch nicht."
GEMESSEN, BEVOR ETWAS GEAENDERT WURDE -- und alles war gruen:
coturn laeuft aktiv
STUN von aussen antwortet, nennt meine oeffentliche Adresse
echte Zuteilung von aussen 7/7, Testpaket kam an (Port 49183)
Dreier-Anruf im Prueflauf verbindet, alle hoeren alle
Vier Messungen, vier Mal in Ordnung -- und das Telefon ging trotzdem
nicht. Der Grund: Der Prueflauf faehrt BEIDE Seiten auf demselben
Rechner. Dort finden sie sich ueber die direkte Adresse, und die
Vermittlung wird nie gebraucht. Draussen sitzen sie in verschiedenen
Netzen.
DER FUND: Eingetragen war eine einzige Adresse --
turn:159.195.212.167:3478
Ein `turn:` OHNE `?transport=` heisst UDP, und nur UDP. Nachgemessen
hoert coturn aber auf beidem: 3478/UDP offen, 3478/TCP offen (5349/TLS
ist zu). Angeboten wurde nur der halbe Server.
Wer in einem Netz sitzt, das UDP nach draussen sperrt -- Mobilfunk mit
strengem Profil, Gast-WLAN, Firmennetz --, bekam damit KEINEN
Vermittlungsweg. Es klingelt (das laeuft ueber die Website, also ueber
443), und danach passiert nichts. Genau das gemeldete Bild.
Aus einem Eintrag werden jetzt drei Wege:
stun:host:port die eigene Adresse finden, ohne Vermittlung
turn:host:port?transport=udp der schnelle Weg
turn:host:port?transport=tcp der Weg durch fast jede Sperre
ABGELEITET, NICHT EINGETRAGEN: Drei Zeilen von Hand waeren drei
Stellen, an die beim naechsten Serverumzug jemand denken muesste --
die abgeschriebene Liste, die hier schon zweimal teuer war. Ein
Eintrag MIT `?transport=` bleibt unangetastet, ein fremder Dienst mit
eigenem Passwort sowieso.
pruef-turn-wege (neu, 15/0) sichert beides: dass jeder Weg herauskommt
UND dass jeder turn:-Weg Zugangsdaten traegt. Das Zweite ist das
wichtigere -- auffaechern ohne anmelden haette den Fehler nur
verschoben.
=== 2. DIE SEITE SPRANG BEIM ZURUECKGEHEN IMMER HOCH ===
Filipe: "das nervt man muss dan immer wieder runter scrollen bis man
da ist wo man vorher war."
Der Browser versucht es sogar -- scrollRestoration steht ab Werk auf
"auto". Nur: Jede Seite hier kommt fast leer an und holt ihren Inhalt
danach per Abruf. In dem Moment, in dem der Browser die alte Position
wiederherstellen will, ist das Dokument ein paar hundert Pixel hoch.
Er kann nicht auf Zeile 900 springen, die es noch nicht gibt -- und er
versucht es kein zweites Mal.
Jetzt macht es kopf.js selbst (gilt damit auf allen 21 Seiten): Stelle
merken beim Verlassen, beim Oeffnen zurueckholen und jeden Bildaufbau
lang versuchen, bis das Dokument hoch genug ist. Nach drei Sekunden
wird aufgegeben.
Drei Dinge sind Absicht:
- NUR beim Zurueckgehen, nicht bei jedem Oeffnen. Wer eine Kachel
anklickt, will oben anfangen.
- WER SELBST SCROLLT, GEWINNT. Rad, Wisch oder Taste beenden das
Nachspringen sofort.
- Nach einer Stunde vergessen -- auf Zeile 900 zu landen, weil man
gestern dort war, ist keine Hilfe.
=== 3. DIE LISTE IST NACH ROLLE GETRENNT ===
Filipe: "die rechte hand rolle immer zuerst und dan die modis. die
sollen auch schoen getrennt sein und verschieden aussehen also die
rechte hand viel spezieller."
Die Reihenfolge macht der Server ueber ROLLEN_SORTIERUNG -- dieselbe
Konstante wie ueberall sonst im Haus, nicht eine zweite. Eine
Sortierung nach ROLLE ist ausdruecklich keine Rangliste: Sie sagt
nichts darueber, wie gut jemand ist, nur welche Aufgabe er hat.
Deshalb steht ueber jeder Gruppe ein Satz und keine Zahl.
"Spezieller" heisst hier Material, nicht Groesse: eigener Farbton als
Kante und Schimmer, hellere Flaeche, kraeftigerer Name. Beide Karten
sind GLEICH GROSS und tragen dieselben Zeilen -- zwei Sorten Aufgabe,
keine Rangfolge. Im Kontrastmodus traegt eine doppelte Kante die
Unterscheidung, weil dort keine Farbe mehr wirkt.
=== 4. DER ANRUFKASTEN ===
Vorher: vier gleich aussehende Pillen nebeneinander, darunter eine
Geraeteauswahl, die das breiteste Element war. Kein Name, keine
Ordnung, und der einzige Knopf mit Folgen sah aus wie die anderen.
- MAN SAH NICHT, MIT WEM. Der wichtigste Satz eines Telefonats fehlte.
Der Chat kennt den Namen und gibt ihn jetzt mit; wer rangeht, sieht
den Anrufer.
- "MIKRO AN" WAR ZWEIDEUTIG -- "ist an" oder "schalt an"? Wer falsch
raet, sitzt stumm da. Jetzt traegt ein durchgestrichenes Zeichen
den Zustand, das Wort nur die Sache. aria-pressed bleibt die
Wahrheit, auch fuer Vorleseprogramme.
- DIE GERAETEAUSWAHL liegt hinter einem kleinen Knopf, der nur
erscheint, wenn es ueberhaupt etwas zu waehlen gibt.
- AUFLEGEN ist als einziger Knopf farbig und steht immer rechts.
- Ein ruhiger Puls atmet, solange die Verbindung aufbaut, und haelt
an, sobald sie steht. Bei prefers-reduced-motion steht er still.
=== NEBENBEFUND, DEN DIE PRUEFUNG GEFUNDEN HAT ===
pruef-anruf wurde durch die Auffaecherung an vier Stellen rot: Sie
griff `adressen[0]` und erwartete dort Zugangsdaten. Das ist jetzt der
STUN-Weg, und der hat richtigerweise keine. Gesucht wird nicht mehr
nach PLATZ, sondern nach ART -- ein Index ist eine Annahme darueber,
wie die Liste aussieht, und die hat sich gerade geaendert.
Dazu angepasst: Die Pruefung "die Uhr laeuft" verlangte, dass die Uhr
schon beim Klingeln zaehlt. Seit heute frueh beginnt sie beim
Rangehen (sonst standen im Kasten und im Chat zwei verschiedene
Zahlen). Sie prueft jetzt das Gegenteil -- statt sie zu streichen,
denn eine Zeile weniger haette den Fehler beim naechsten Umbau wieder
durchgelassen.
GEMESSEN: pruef-anruf 114/0 (vorher 111 -- drei MEHR, weil die
Auffaecherung mitgeprueft wird), pruef-turn-wege 15/0,
pruef-meldungen 8/0, pruef-css-klassen ALLES IN ORDNUNG,
pruef-rechtetafel 19/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
273318dd9c |
Vier Sackgassen, zwei Kacheln namens "Chat" -- und eine Seite ohne Kopf
Durchgang durch die Team-Dogi-Seiten aus der Sicht von jemandem, der
sie zum ersten Mal sieht. Alles hier ist am Code belegt und nachgemessen.
1. "KLINGELT NICHTS?" WARF ALLE DREI TEAM-ROLLEN AUF DIE STARTSEITE.
anruf-probe.html erklaert, WARUM das Telefon stumm bleibt. Sie steht in
der Rechtetafel offen, und aus dem Chat zeigen zwei Knoepfe darauf. Nur
hatte sie nie eine Kachel -- absichtlich, sie ist kein Bereich. Seit die
Adressregel vom 15.09. eine Kachel VERLANGT, landete jeder Klick wortlos
auf start.html.
Das ist die schlimmste Sorte Sackgasse: Man ruft sie auf, WEIL schon
etwas nicht geht, und sie wirft einen hinaus.
Mit derselben Zeile geheilt: Die Hinweisleiste wirft jeden Hinweis weg,
dessen Ziel es auf dieser Adresse nicht gibt -- "Bei dir klingelt nichts"
wurde auf crew deshalb NIE angezeigt. Ausgerechnet der Hinweis, der acht
von elf Leuten betrifft.
2. UND DIESE SEITE HATTE GAR KEINE GESTALTETE KOPFLEISTE.
.kopfleiste, __zurueck, __mitte, __titel stehen in KEINER Stilvorlage --
sie leben in start.css, die diese Seite absichtlich nicht laedt. Die
Leiste war nackter Text. Auf einer Seite, die man im Stoerfall aufruft,
sieht unfertig aus wie kaputt. Jetzt im <style>-Block der Seite, aus
demselben Grund wie ihr uebriges CSS.
3. EIN MODI KAM NICHT AN SEINE EIGENE AUSWERTUNG.
entwicklung.html und werdegang.html haben BEIDE eine ausgearbeitete
Eigensicht, und die Rechtetafel laesst ihn hinein. In seiner Kachelliste
stand keine von beiden -- der Weg existierte fuer ihn nicht. Die ganze
Eigensicht war toter Code, ausgerechnet fuer den, fuer den sie ist.
Mein eigener Fehler vom Vortag.
Zwei eigene Kacheln in "Fuer dich", aus den Leitungskacheln abgeleitet.
Sie loesen zugleich eine Namenskollision: Bis heute setzten BEIDE Seiten
fuer ihn die Ueberschrift "Deine Entwicklung".
4. DER KALENDER-LINK WAR FUER DIE COMMUNITY EINE SACKGASSE.
Auf jeder Brettkarte mit Termin stand "Im Kalender am 24.09." als Link.
kalender.html steht auf ALLE -- und ALLE ist ausdruecklich ohne "gast".
Jetzt fragt der SERVER die beiden Schranken (kalender_offen) und die
Karte zeigt den Termin als Text statt als Link. Die Auskunft bleibt, nur
der Weg ins Leere faellt weg. Die Regel im Browser nachzubauen waere die
vierte Stelle fuer dieselbe Frage gewesen.
5. EIN MODI KAM AN DIE TALENTE-NOTIZEN, DIE IHM VERWEHRT SIND.
BRETTER_UEBER_SEITEN war eine feste Liste ("wer die Seite darf, muss
auch dorthin kommen") und fragte nie, WER fragt. Ueber
bereich.html?b=talente kam er an Notizen zu Zuschauern, obwohl
talente.html fuer ihn gesperrt ist -- Begruendung dort: "Hier stehen
Namen von Menschen, die nichts davon wissen."
Aus der Liste wurde eine Zuordnung Brett -> Seite, gefragt wird
darfSeite(). Nachgemessen: modi/talente 404, modi/entwicklung darf,
hand+admin unveraendert.
Dazu stand in workspace-bereiche.js ein Kommentar, der das GEGENTEIL des
Codes behauptete ("entwicklung, talente bleiben 404"). Ein falscher
Kommentar an einer Rechtestelle ist schlimmer als keiner.
6. ZWEI KACHELN "CHAT", BEIDE AUF DIESELBE SEITE.
Seit dem Treff-Chat von gestern sahen Modi und rechte Hand zweimal
"Chat" mit demselben Ziel. Jetzt "Treff-Chat" mit ?raum=treff, das den
Raum direkt oeffnet -- gesucht an denselben zwei Merkmalen, an denen ihn
der Rest der Datei erkennt.
7. VERTRAUEN: "WIE GEHT'S DIR?" VERSPRACH MEHR, ALS ES HALTEN KANN.
Dort stand: "Niemand aus dem Team sieht deine Antworten -- auch
DogFather nicht." Punkt. Fast wahr und deshalb gefaehrlich: Aus
denselben Antworten entsteht eine namenlose Ampel fuer die Leitung.
Der ehrliche Satz war laengst geschrieben und wurde vom Server sogar
mitgeliefert (block.text) -- nur hat ihn nie jemand angezeigt. Er steht
jetzt im HTML, nicht im Skript: Wer die Seite oeffnet, soll ihn lesen,
BEVOR er tippt.
8. DIE NEUE AUSWERTUNG, AUS BENUTZERSICHT NACHGEBESSERT.
- Der Streifen hatte keine Zeichenerklaerung. Im Dateikopf stand "wer
Farben schlecht unterscheidet, liest dasselbe Zeichen" -- das stimmt
nur, wenn irgendwo steht, was die Zeichen heissen. Jetzt eine Legende,
aus `stufen` gebaut statt abgeschrieben.
- "nie gesetzt" war ein Mittelpunkt, "Kann ich nicht sagen" ein
Halbgeviertstrich. Zwei kurze Striche nebeneinander fuer den
Unterschied zwischen "niemand hat hingesehen" und "jemand hat
hingesehen und konnte es nicht sagen". Leer ist jetzt wirklich leer,
mit gestricheltem Rahmen.
- Die Aufschluesselung der Balken stand nur im Mausueberfahren -- am
Handy also nie, und dort steht jemand damit im Stream. Jetzt als Text.
- Die Modi-Sicht bekam Balken ohne Erklaerung, ein "Frag danach" ohne
Adressaten und bei fehlender Bewegung ein LEERES Element. Jetzt
Lesehilfe, ein Leerkasten mit Satz und zwei Wege weiter.
9. NEBENBEFUNDE, DIE DIE PRUEFUNG GEFUNDEN HAT.
pruef-css-klassen war schon VOR dieser Arbeit rot (nachgemessen mit
git stash). Alle drei Befunde behoben:
- hilfe.html und unsere-seiten.html luden ihre Seitendatei NACH
module.css und haus.css und ueberschrieben damit das Haus.
- Zwei Schriftgroessen unter 11,5 px aus dem gestrigen Bau
(.71rem Monatsbeschriftung, .68rem Marke) auf .75 und .72 gehoben.
- Die Pruefung selbst war blind fuer <style>-Bloecke in der Seite und
meldete deshalb dauerhaft drei Fehler an einer Seite, die ihre
Stile mit Absicht selbst traegt. Eine Warnung, die immer kommt, ist
keine Warnung mehr -- jetzt sieht sie hin, statt die Seite
auszunehmen.
Kleinkram nebenbei: "die Antworten sieht nur du" -> "siehst nur du" auf
der Kachel zur empfindlichsten Seite des Hauses. "Bewertet wird dort" ->
"Eingeschaetzt wird dort" in teamlage.html, zwei Zeilen unter "keine
Bewertung von Menschen". "1 Aufgabe(n) angelegt" ausgeschrieben.
GEMESSEN: pruef-css-klassen ALLES IN ORDNUNG (vorher 3 Fehler),
pruef-meldungen 8/0, pruef-rechtetafel 19/0, alle Module laden,
keine doppelten Kachelnamen/-ziele/-farben mehr in allen vier Rollen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
461d41943a |
Keine Maschinensprache mehr auf dem Bildschirm
Filipe: "keine kryptischen oder technischen fehlermeldungen, sondern
klare aussagen darueber, was passiert ist und wie man das problem
loesen kann."
DAS PROBLEM, NACHGEMESSEN.
Der Server antwortet im Fehlerfall mit { fehler: "..." }. Darin stehen
ZWEI verschiedene Dinge, und von aussen sehen sie gleich aus:
Maschinenkennungen (nicht_verfuegbar, nicht_gefunden, ungueltig -- 43
verschiedene) und fertige deutsche Saetze.
An 84 Stellen stand `textContent = d.fehler` -- ungefiltert. Wer beim
Hochladen einer Datei Pech hatte, las woertlich "nicht_verfuegbar" auf
dem Bildschirm und wusste nicht einmal, ob er selbst schuld war.
Gezaehlt: 474 Antworten mit "nicht_verfuegbar", 392 mit
"nicht_gefunden", 125 mit "ungueltig".
DREI AUSGAENGE, NICHT ZWEI.
`sagWas()` in workspace/assets/js/meldung.js:
bekannte Kennung -> ihr Satz
unbekannte Kennung -> der Ersatzsatz der Stelle, NIE die Kennung
(sie geht in die Konsole, wo sie jemandem
auffaellt, der sie beheben kann)
fertiger Satz -> unveraendert durch
Erkannt wird eine Kennung daran, dass sie nur aus Kleinbuchstaben,
Ziffern und Unterstrichen besteht. Ein deutscher Satz hat immer
Leerzeichen; eine Kennung nie. Die Unterscheidung ist entschieden,
nicht geraten.
UND WARUM DIE TABELLE NICHT ALTERN KANN.
Eine von Hand gepflegte Liste ist hier schon zweimal teuer geworden
(die abgeschriebene Spaltenliste, die feste Umbruchschwelle). Deshalb
rechnet pruef-meldungen.mjs die Kennungen AUS DEM SERVER aus statt sie
zu kennen -- eine neue ohne Satz macht sie rot. Man kann es nicht mehr
vergessen.
Sie prueft drei Dinge und beweist zu jedem, dass sie auch "nicht in
Ordnung" sagen kann:
1. vollstaendig -- jede Kennung hat einen Satz
2. angeschlossen -- keine Rohanzeige, und jede Seite, deren Skript
sagWas benutzt, laedt auch meldung.js
3. lesbar -- kein Satz enthaelt Kennung, Zahl oder englisches Wort
GEFUNDEN HAT SIE SOFORT EINEN ECHTEN FEHLER: leistung.html laedt seine
Skripte ohne `defer` und fiel damit durch meinen Einbau. Dort waere
sagWas nicht definiert gewesen -- aus einer Fehlermeldung waere ein
Absturz geworden, also schlimmer als vorher.
NEBENBEFUND, DER MICH FAST EINE FALSCHE MELDUNG GEKOSTET HAETTE:
"alter_offen" heisst NICHT "etwas Aelteres ist offen", sondern
"Altersbestaetigung steht noch aus" (workspace.js:4864). Geraten
haette ich es falsch uebersetzt.
GEMESSEN: pruef-meldungen 8/0, alle 46 Skripte syntaktisch in Ordnung.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
7be85c265b |
Der Treff bekommt einen Chat -- mit Nachtruhe, ohne Telefon
Filipe, auf die Frage ob die Community einen Chat bekommen soll:
"eine geile mischung von punkt 2 und drei. mach es perfekt so das quasi
nach mitternacht bis morgens 6 uhr keiner schreiben kann damit auch die
privatsphaere beruecksichtig wird ueber nacht ... und die sollen nicht
anrufen koennen. nur schreiben."
Zur Auswahl standen "gar kein Chat", "nur mit Oeffnungszeiten" und
"offen wie im Team". Seine Antwort ist eine vierte, die nicht auf dem
Zettel stand, und sie ist die bessere.
1. WARUM DIE NACHTRUHE MEHR IST ALS EINE EINSTELLUNG
Sein Grund war Privatsphaere -- und zwar die der Leute, die moderieren.
Die Forschung zu ehrenamtlichen Moderatoren sagt genau das: Die beiden
meistgenannten Gruende fuers Aufhoeren sind ZU WENIG ZEIT und STREIT IM
TEAM. Ein Chat, der nachts um drei weiterlaeuft, erzeugt beides.
SIE GILT FUER ALLE, AUCH FUER DIE LEITUNG. Das ist die unbequeme
Entscheidung: Der bequeme Weg waere, DogFather auszunehmen. Aber wenn er
um halb vier schreibt, liest es jemand -- und wer liest, fuehlt sich
zustaendig. Eine Nachtruhe, von der die Leitung ausgenommen ist, ist
keine, sondern eine Bitte.
MODERIEREN GEHT WEITER. Verbergen, loeschen, herausnehmen sind keine
Nachrichten. Wer nachts etwas Schlimmes sieht, kann es wegnehmen -- er
kann nur nicht darueber diskutieren. Und der vertrauliche Meldeweg
bleibt offen: Er ist ein Fall mit einer Zustaendigkeit, kein Raum mit
dreissig Leuten.
GERECHNET IN ORTSZEIT, nicht in UTC. `getHours()` auf einem UTC-Server
haette den Chat im Sommer von 2 bis 8 geschlossen -- zwei Stunden
daneben, und nur denen sichtbar, die um diese Zeit wach sind. Dieses
Haus ist mit der Rechnung schon zweimal hereingefallen.
DER RIEGEL SITZT IM SERVER, nicht im Browser. Ein ausgegrautes Feld ist
eine Hoeflichkeit; wer die Adresse kennt, spricht die Schnittstelle
direkt an. Nachrichten UND Anhaenge werden abgelehnt -- ein offener
Anhangweg waere der Umweg, den jeder findet, der es einmal versucht.
2. KEIN TELEFON -- UND WARUM DAS EINEN EIGENEN RIEGEL BRAUCHT
Ein Anruf haengt in diesem Haus an der RAUMMITGLIEDSCHAFT, nicht an der
Rolle. Solange die Community keinen Raum hatte, war die Frage muessig.
Seit sie einen hat, waere Telefonieren erlaubt -- nicht, weil es jemand
entschieden haette, sondern weil es niemand verboten hat.
Der Riegel steht ganz vorne am Anruf-Router, nicht in den neun Routen
dahinter. Alle sieben Wege sind geprueft, einzeln.
3. DER FUND, DER DIE GANZE NACHTRUHE UMGANGEN HAETTE
Ein Gast konnte ein PRIVATES ZWEIER-GESPRAECH mit DogFather aufmachen.
Die Route antwortete mit 200 und legte den Raum an.
`ohneAussen` nimmt die Community aus den Listen ANDERER heraus -- damit
kein Creator einen Zuschauer anschreibt. Die Gegenrichtung kam nie vor,
weil die Chatseite fuer 'gast' gar nicht offen war. Seit heute ist sie
offen, und damit war die Erlaubnis da.
Ein Zweier-Gespraech ist kein Kanal: keine Nachtruhe, kein Modi liest
mit, niemand koennte moderieren. Aus "die Community bekommt einen Chat"
waere ungewollt "jeder Zuschauer bekommt eine Standleitung zu
DogFather" geworden.
GEFUNDEN HAT ES DIE PRUEFUNG, NICHT DAS LESEN -- und zwar in dem Moment,
in dem ich zwei Dateien weiter selbst vor genau dieser Sorte Erlaubnis
gewarnt hatte.
4. ZWEI TOTE WEGE, EINER DAVON MEINER
pruef-community-sicht sucht nach sichtbaren Wegen, die ins Leere
fuehren. Sie fand zwei:
a) "Bei dir klingelt nichts" -> anruf-probe.html. Der Hinweis von
heute Vormittag, und die Seite steht einem Gast ausdruecklich NICHT
offen. Mein Fehler, und einer, der jedem naechsten Hinweis genauso
passiert waere.
AN DER WURZEL BEHOBEN: Die Hinweise pruefen jetzt auch die ROLLE
(`darfSeite`), nicht nur die Adresse. Das ist der 15.09. noch
einmal, eine Ebene tiefer -- damals die Adresse, diesmal die Rolle,
und dieselbe Lehre: Die Hinweise sind eine DRITTE Stelle neben
Seiten und Schnittstellen.
b) Der Verweis "Kalender" im Tagesblick. Steht fest im HTML, fuehrt
fuer die Community ins Leere -- und zwar SCHON VOR den Aenderungen
dieses Tages. Aufgefallen nur, weil (a) daneben stand. Der Weg
wird jetzt abgeleitet: Wer die Kachel hat, hat den Weg.
5. DIE PRUEFUNG LAEUFT ZWEIMAL
Die Nachtruhe laesst sich nicht in EINEM Lauf in beiden Zustaenden
pruefen -- die Zeiten werden beim Laden gelesen, und ein zweiter Server
braeuchte denselben Port. pruef-treffchat ruft sich deshalb selbst noch
einmal auf, mit einem Fenster, das jetzt gilt. Dieselben Pruefungen,
andere Lage.
DIE UHR WIRD NICHT GEFAELSCHT. Verschoben wird die GRENZE, nicht die
Zeit -- eine Pruefung, die an der Systemzeit dreht, faelscht danach auch
anderes mit und ist nur nachts gruen.
6. WAS SICH NEBENBEI GEAENDERT HAT
- pruef-treff war SCHON VORHER ROT (8 Fehler): Sie erwartete sieben
Kacheln fuer die Community, es waren gestern Nacht schon zehn. Feste
Zahlen, Rechnung von gestern. Jetzt abgeleitet -- 72 Pruefungen statt
66, alle gruen.
- Ein 404 bei jedem Seitenaufruf der Community: `anruf.js` holte die
Verbindungsadressen, bevor es wusste, wer fragt. Der Browser
protokolliert das, BEVOR JavaScript abfangen kann -- also darf die
Anfrage gar nicht erst gestellt werden. `/api/ich` sagt es jetzt
vorher. Ein Fehler, der immer kommt, macht den naechsten echten
unsichtbar.
- Reaktionen (Daumen) bleiben nachts erlaubt. Ausdruecklich, mit
Begruendung im Code: Ein Daumen ist keine Nachricht, er loest keine
Meldung aus und kann keinen Streit anfangen. Eine Luecke ohne
Begruendung wird beim naechsten Durchsehen entweder geschlossen oder
uebersehen -- beides falsch.
GEMESSEN: pruef-treffchat 108/0 (neu, laeuft zweimal), pruef-treff 72/0
(vorher 66 mit 8 Fehlern), pruef-chat gruen, pruef-rechtetafel 19/0,
pruef-community-sicht gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
ff09a67578 |
Anruf-Probe: erreichbar auch in der App
Filipe: „geht es nicht auf der app?"
Nein -- und das war mein Fehler. Ich hatte eine Seite gebaut, die
sagt, WARUM es nicht klingelt, und sie war nur ueber die Adresszeile
erreichbar. In der installierten App gibt es keine. Eine Hilfe, die
man nicht aufrufen kann, ist keine.
Zwei Wege dorthin, beide genau da, wo man hinschaut, wenn etwas nicht
stimmt:
* Ein „?" neben den Anrufknoepfen im Chat -- dauerhaft da, auch
ohne laufenden Anruf. Wichtig fuer die andere Seite: Wer angerufen
wird und nichts hoert, sieht gar keinen Anrufkasten.
* Und „Klingelt nichts?" im Anrufkasten selbst, fuer den, der gerade
vergeblich anruft.
Beide klein und ohne Farbe: Wer telefoniert, soll sie uebersehen; wer
ratlos dasitzt, findet sie.
pruef-anruf weiterhin 106, 0 Fehler.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
93c9788782 |
Telefonieren im Chat -- und die Farben nach Nachbarschaft verteilt
ZWEI SACHEN IN EINEM COMMIT, weil beide aus derselben Nacht stammen. === 1. DIE FARBEN: DER RICHTIGE ABSTAND === Filipe: "es gibt noch mehr die aehnlich aussehen von den farben also leg los alle die sich aehnlich sind von den farben wechseln." Er hatte recht, und mein Denkfehler laesst sich benennen: Ich hatte den kleinsten Abstand ueber ALLE 37 Paare maximiert -- und der liegt bei 37 Farben zwangslaeufig bei 0,10. Das ist die Packungsgrenze, kein Versaeumnis. NUR SIEHT NIEMAND ALLE 37 NEBENEINANDER. Man sieht NACHBARN. Im Browser gemessen, an der tatsaechlichen Lage auf dem Schirm -- 125 Paare, die wirklich nebeneinander stehen, 15 davon unter 0,15: Creator-Profile / Zahlen 0,1019 beide rosa-rot LIVE-Analyse / Technik 0,1030 beide orange Wunschliste / Meldungen 0,1032 beide gelbgruen Wer sieht was / Entwicklung 0,1039 beide cyan Regeln & Hilfe / Mitmachen 0,1047 beide gruen Der Treff / Anschlagbrett 0,1070 beide rosa Die Farben bleiben, ihre ZUTEILUNG aendert sich: Nachbarabstand 0,1047 -> 0,2133 (mehr als verdoppelt) Nachbarn unter 0,15 6 -> 0 Die Nachbarschaft steht in server/kachel-nachbarn.json, gemessen im Browser -- nicht aus der Struktur im Quelltext abgeleitet. Die sagt, was zusammengehoert, nicht was zusammen zu sehen ist. === 2. TELEFONIEREN IM CHAT === Filipe: "kann man machen dass die modis, rechte hand und ich auch telefonieren koennen im chat?" ... "was man selbst in die app reinsetzten kann, nicht meinen pc belastet und trotzdem vielleicht in gruppe, mit video oder einzelnd." DER TON GEHT NICHT UEBER DEN SERVER. Direkt von Browser zu Browser (WebRTC); der Server reicht nur die Verbindungsdaten weiter, ein paar Kilobyte je Anruf. Zu zweit kodiert jedes Geraet einen Strom und dekodiert einen -- die Last eines gewoehnlichen Videoanrufs. KEIN NEUER DIENST. Der Chat hatte bereits alles: `chatEreignis()` fuer den Hinweg (SSE), Push fuers Klingeln, Raeume mit mehreren Teilnehmern. Ein eigener WebSocket daneben waere eine zweite Verbindung fuer dieselbe Frage -- und die zweite wird beim naechsten Umbau vergessen. Gebaut: Ton und Video, einzeln und in Gruppe bis GRUPPE_MAX (4), Klingeln mit Annehmen/Ablehnen, Mikro und Kamera schaltbar, Gespraechsdauer, Auflegen. Der Chat bleibt daneben benutzbar -- man schreibt oft, waehrend man spricht. EIN FUND, DER OHNE PRUEFLAUF LIVE GEGANGEN WAERE: Der Server sperrt Mikrofon und Kamera per Permissions-Policy auf ALLEN Seiten. Der erste Lauf meldete "microphone is not allowed in this document" -- der Anruf haette bei JEDEM versagt, mit einer Meldung, die auf die falsche Faehrte fuehrt (man sucht an den Browsereinstellungen). Die Sperre bleibt ueberall und ist an genau EINER Stelle geoeffnet: der Chat-Seite, und nur fuer sie selbst (`self`, nicht `*`). NOCH NICHT GEBAUT -- und ausdruecklich nicht heimlich: coturn. Ohne Vermittlungsserver klappen Anrufe nur im selben Netz. Die Adressen stehen in den Einstellungen statt im Quelltext; sie lassen sich nachtragen, ohne eine Zeile zu aendern. Ein oeffentlicher STUN-Dienst als Standard kam nicht in Frage: Er saehe bei jedem Anruf die IP-Adressen beider Teilnehmer, und fuer ein Team, das ueber Moderation und Vorfaelle spricht, ist das keine Kleinigkeit. server/pruef-anruf.mjs, 40 Pruefungen. Der wichtigste Abschnitt: Wer nicht in den Raum gehoert, kommt an KEINE Route. Ein Anruf hinterlaesst keine Spur -- wer mithoert, faellt nicht auf. Gegenproben, jede zielgenau: Empfaengerpruefung der Signalisierung weg -> 1 rot Raumpruefung weg -> 5 rot (jede Route offen) Kopfzeilen-Ausnahme weg -> 4 rot Gruen: anruf, chat, chat-optik, chat-kanaele, css-klassen, namen, struktur. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
9f277435a5 |
Reaktionen: Vorschlaege, ganzer Katalog, eigene Favoriten
Filipe: "soll viel besser und geiler sein und man soll auch auswaehlen
koennen, also paar als vorschlaege mit der moeglichkeit andere
auszuwaehlen und als favoriten zu speichern."
Aus einem Streifen mit sechs Zeichen ist eine Karte geworden:
Vorschlaege oben, Suchfeld, darunter der Katalog in sechs Gruppen --
82 Zeichen, jedes mit deutschen Suchwoertern. Wer "feuer" tippt, muss
nicht scrollen.
DREI LISTEN, DREI FRAGEN, und sie werden gern verwechselt:
KATALOG Was gibt es? fest, workspace-reaktionen.js
VORSCHLAG Was steht vorn, solange fest -- bis jemand eigene
ich nichts gewaehlt habe? Favoriten hat
FAVORITEN Was hat DIESER Mensch in der Datenbank
sich gemerkt?
Nur der Katalog entscheidet, was ANGENOMMEN wird. Vorschlag und
Favoriten sind Reihenfolge, keine Erlaubnis -- sonst koennte man sich
ueber einen Favoriten etwas erlauben, das im Katalog nicht steht. Die
erlaubte Menge wird aus dem Katalog ABGELEITET; eine zweite Liste
daneben waere die, in der ein Zeichen fehlt, das die Oberflaeche
anbietet.
FAVORITEN HAENGEN AM MENSCHEN, NICHT AM GERAET. Im Browser abgelegt
waeren sie am Handy andere als am Rechner und beim naechsten Loeschen
der Seitendaten weg.
DER STERN SCHALTET EINEN MODUS, statt an jedem Zeichen einen zweiten
Knopf zu haben: Am Handy gibt es kein "daneben zeigen". Im Merk-Modus
faerbt sich die ganze Tafel, damit niemand reagiert, wenn er merken
wollte. Die Tafel bleibt dabei offen -- acht Favoriten waeren sonst
acht Mal Aufmachen -- und die Vorschlagszeile aendert sich sofort mit.
DIE GRENZE SAGT BESCHEID, statt still den aeltesten wegzuwerfen: Wer
einen neunten merken will, bekommt "nimm erst einen weg". Ein Favorit,
der ohne Ansage verschwindet, sieht wie ein Fehler aus.
Eine Selbstpruefung beim Laden meldet doppelte Zeichen im Katalog und
Vorschlaege, die nicht darin stehen -- beides waere in der Tafel still.
pruef-chat-aufloesen 85 -> 115. Gemessen wird, was PASSIERT, nicht dass
es Elemente gibt: dass die Suche wirklich eingrenzt (1 statt 82) und
das Richtige findet, dass ein Fehlgriff "Nichts zu ... gefunden" sagt
statt eine leere Flaeche zu zeigen, und vor allem, dass im Merk-Modus
KEINE Reaktion entsteht -- an der Zahl der Reaktionen gemessen, nicht
an der Absicht.
NEBENBEFUND AUS DER EIGENEN PRUEFUNG: pruef-css-klassen hat meine
Gruppenueberschrift mit 10,56 px abgelehnt (Grenze 11,5). Richtig so --
eine gesperrte Versalzeile ist ohnehin schwerer zu lesen, die darf
nicht auch noch die kleinste sein. Auf .72rem angehoben, statt die
Grundlinie zu verschieben.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
47269bda21 |
Chat: auf eine Nachricht reagieren, ohne zu antworten
Filipe: "ich will dass man auf die nachrichten auch reagieren kann mit einem emoji, die nachricht selbst ohne zu antworten." Neben "antworten" steht jetzt "reagieren". Ein Klick klappt sechs Zeichen auf, ein zweiter Klick setzt es -- und unter der Nachricht steht, wer mit was reagiert hat. EINE FESTE AUSWAHL, KEIN FREIES FELD (👍 ❤️ 😂 😮 🔥 🙏). Drei Gruende, der erste ist der wichtigste: Eine feste Liste laesst sich pruefen -- was dort nicht drinsteht, kommt nicht in die Datenbank, kein beliebiger Text, keine 4-KB-Zeichenketten. Zweitens sehen alle dasselbe. Drittens kann man sechs Zeichen ueberfliegen; eine volle Tafel ist eine Suchaufgabe, und dann tippt man doch wieder "ok". DIE LISTE STEHT AUF DEM SERVER und wird an die Oberflaeche geliefert. Stuende sie im Browser, gaebe es sie zweimal -- und die zweite Fassung waere die, in der ein Zeichen fehlt, das der Server noch annimmt. Faellt der Abruf aus, erscheint KEINE Auswahl statt einer mit erfundenen Zeichen. DER PRIMAERSCHLUESSEL BEANTWORTET "WIE OFT?": (nachricht, person, zeichen). Eine Person darf verschiedene Zeichen geben, jedes aber nur einmal -- und zwar durchgesetzt von der Datenbank, nicht von einer Abfrage davor, die man vergessen kann. Derselbe Klick noch einmal nimmt es zurueck; das erspart einen zweiten Weg, den man auch absichern muesste. KEIN ZAEHLER IN chat_nachrichten. Eine mitgefuehrte Zahl muesste bei jedem Hin und Her stimmen und ist genau die Art Angabe, die irgendwann nicht mehr stimmt und die niemand nachrechnet. Gezaehlt wird beim Lesen -- in EINER Abfrage fuer alle 200 Nachrichten, nicht je Zeile eine. WER ES WAR, STEHT IM TITEL. "Drei Daumen" sagt weniger als "Ayla, Ben und Cem", und es sind Leute aus demselben Raum. KEINE BENACHRICHTIGUNG AUFS HANDY. Wer im Raum ist, sieht es sofort; wer nicht, bekommt nichts. Ein Daumen ist keine Nachricht -- wer dafuer geweckt wird, schaltet Meldungen ab. Was NICHT geht: wer nicht im Raum ist (404), ein erfundenes Zeichen (400), eine zurueckgenommene Nachricht (409). Und mit der Nachricht verschwinden die Reaktionen (CASCADE). pruef-chat-aufloesen 59 -> 85. Gemessen wird der BESTAND, nicht die Antwort -- und im Browser der KNOPF, nicht nur das Recht: dass die Auswahl aufklappt, sich nach dem Klick von selbst schliesst, die Reaktion darunter erscheint, als die eigene erkennbar ist und ein Klick darauf sie wieder wegnimmt. EINE EIGENE PRUEFUNG WAR ZU SCHWACH: "bei Cem ist ueberall selbst=true" war trivial wahr, weil es nur EINE Sorte gab. Jetzt bekommt eine andere Person ein drittes Zeichen, und in derselben Antwort muss eines auf true und eines auf false stehen. Eine Angabe, die nie `false` sein kann, sagt nichts. Im CSS keine vierte Abschrift: "reagieren" haengt an derselben Regel wie "antworten" -- neben anheften und kopieren waere es die vierte fast gleiche gewesen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
1ab2729e47 |
Die rechte Hand steht ueberall an zweiter Stelle - und im Kalender ueberhaupt
Filipe, mit Bildschirmfoto der Liste "Wen gehst du durch?" (Diene, Dogi,
VanVan - alphabetisch, die rechte Hand ganz rechts): "rechte hand soll
immer als erstes sein. ueberall. wie in dem sinne soll sie ganz links
sein. ausser bei personen und zugaenge soll sie ueber jedem aber unter
dogfather sein. ich will dass auch ueberall immer nach der hirarchie
gearbeitet wird."
EINE REIHENFOLGE, NICHT ZWEI REGELN
ROLLEN_REIHE in workspace.js ist jetzt:
Spicy Media > DogFather > Rechte Hand > Manager > Scout > Creator > Modi
Er hat zwei Faelle beschrieben, aber es braucht nur eine Reihenfolge: In
den Team-Listen kommt DogFather gar nicht vor (er beurteilt, er wird
nicht beurteilt) - dort steht sie dadurch automatisch ganz vorn. In
"Personen & Zugaenge" steht er drin, also steht sie dort hinter ihm.
Zwei Sonderfaelle waeren zwei Stellen, an denen es auseinanderlaeuft.
Dass Spicy Media davor bleibt, ist seine ausdrueckliche Entscheidung auf
Nachfrage. 'gast' steht bewusst nicht in der Liste und faellt ans Ende.
ROLLEN_SORTIERUNG (der SQL-Ausdruck) wird jetzt aus ROLLEN_REIHE
ABGELEITET statt danebengeschrieben. Bis heute stand die Reihenfolge
zweimal da; beim Hochziehen der rechten Hand haetten beide geaendert
werden muessen. Eine Liste, die niemand pflegt, kann nicht veralten -
derselbe Grundsatz wie beim Spaltenverlust vom 06.09.
WAS DABEI AUFFIEL, OHNE DASS JEMAND DANACH GESUCHT HAT
Der Server sortierte laengst richtig. DREI Auswahllisten im Browser
haben seine Reihenfolge wieder verworfen und nach einer eigenen Liste
mit fuenf Agentur-Rollen neu gezeichnet - Team Dogi kommt darin nicht
vor und DARF es nicht (bereiche.js laedt jeder herunter).
- Chat-Auswahl und Sicht-Umschalter: Team Dogi landete in einem
Nachzuegler-Block ganz unten, hinter jedem Creator.
- Teilnehmerwahl im Kalender: dort gab es nicht einmal einen
Nachzuegler-Block. Die rechte Hand und die Modis standen GAR NICHT
zur Auswahl. DogFather konnte sein eigenes Team zu keinem Termin
einladen, und auf dem Bildschirm sah das vollkommen normal aus.
Das ist derselbe Fehler zum vierten Mal (Chat 10.09., Personenliste
10.09., Sicht-Umschalter 11.09., Kalender 11.09.). Deshalb keine vierte
Einzelreparatur, sondern eine Stelle: window.Bereiche.gruppieren()
gruppiert in genau der Reihenfolge, in der der Server die Menschen
schickt - ohne einen einzigen Rang zu kennen. Fehlt der Helfer, wird
eine Gruppe mit allen gezeichnet: nicht schoen, aber sichtbar, und
niemand verschwindet. Der Kalender-Weg schickt die Ueberschrift jetzt
mit, wie der Chat es laengst tut.
PRUEFUNGEN
pruef-nachwuchs 109 -> 123 (Abschnitt 12: die Reihenfolge, mit der
Gegenprobe, dass sie NICHT alphabetisch ist -- Rieke
steht alphabetisch hinten, mit "Anna" waere jede
Zeile gruen ohne etwas zu messen)
pruef-dabei-optik misst die Wahl jetzt im Browser: ist Team Dogi
ueberhaupt da, und steht es vorn
pruef-rollen 315 (vorher 312), 423 s gemessen. Die Notbremse lag
bei 480 s und hat angeschlagen - kein Haenger,
sondern zu wenig Luft, seit die rechte Hand vier
Kacheln mehr hat. Jetzt 900 s, mit der Messung
daneben und dem Hinweis, beim naechsten Mal nicht
die Zahl zu erhoehen, sondern nachzusehen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
f23260dcbb |
Chat: Gruender duerfen ihre Gruppe oder ihren Kanal aufloesen — und der Umschalter erklaert sich
Zwei Wuensche von Filipe, beide am Neu-Fenster. 1) "ich will eine bessere erklaerung dafuer bitte." Neben dem Umschalter "Gespraech | Kanal" stand ein Satz ueber das ANTIPPEN von Personen -- also ueber den naechsten Schritt, nicht ueber die Wahl, die gerade ansteht. Wer die beiden Woerter zum ersten Mal sieht, erfuhr nirgends, was sie bedeuten. Der Unterschied ist nicht "wenige/viele Leute", sondern WONACH der Raum benannt ist: ein Gespraech nach den Menschen darin, ein Kanal nach einem Thema. Daran haengt alles Weitere -- dass es einen Kanal je Zustaendigkeit nur einmal gibt (eindeutiger Index, nachgesehen), dass sein Name festliegt, dass die Teamleitung immer dabei ist (kanaeleAngleichen, nachgesehen) und dass Leute wechseln koennen, ohne dass der Raum ein anderer wird. Genau das steht jetzt da, und nichts davon ist behauptet. 2) "die person die ihn oeffnet soll auch das recht haben das zu loeschen und so dass es dan fuer jeden geloescht ist. aber nur die person die es gruendet." Ein EIGENER Weg (/ganz), kein Zusatzfeld am bestehenden. Es gibt jetzt zwei Loeschknoepfe nebeneinander, und sie tun etwas sehr Verschiedenes: Wegraeumen ist nur bei mir, Aufloesen ist fuer alle und endgueltig. Ein vergessenes Feld waere genau dieser Unterschied gewesen. Aus demselben Grund ein anderes Zeichen und eine eigene Warnfarbe -- zwei gleich aussehende Papierkoerbe waeren eine Falle. Nur der Gruender, woertlich: nicht die Teamleitung, nicht DogFather, nicht wer `leitung` in der Gruppe hat. Nicht bei Zweier-Gespraechen -- dort gibt es keinen Gruender, und "niemand nimmt einem anderen die Unterhaltung weg" gilt weiter. Reihenfolge beim Loeschen ist nicht beliebig: erst das Live-Ereignis (chatEreignis liest die Teilnehmer aus der Tabelle -- danach waere die Liste leer), dann die Zeilen in EINER Transaktion, dann die Anhaenge von der Platte. Umgekehrt haetten wir bei einem Ruecklauf Nachrichten, die auf geloeschte Dateien zeigen. WAS DIE PRUEFUNG GEFUNDEN HAT, BEVOR ES JEMAND GEMERKT HAETTE: Der Knopf blieb unsichtbar, obwohl das Recht stimmte. Die Oberflaeche holt den offenen Raum aus dem Nachrichten-Weg, nicht aus der Raumliste -- zwei Wege, ein Raumobjekt, und nur einer kannte das neue Feld. Die Regel steht jetzt in darfAufloesen() und wird von allen dreien benutzt: Liste, Nachrichten-Weg und der Loeschweg selbst. Gefunden hat das die Pruefung, weil sie den KNOPF misst und nicht das Recht dahinter. Haette sie nur `darf_aufloesen` geprueft, waere sie gruen gewesen und der Knopf nie erschienen. NEU: server/pruef-chat-aufloesen.mjs (59 Pruefungen). Sie misst am BESTAND, nicht an der Antwort: ob der Raum wirklich aus der Datenbank weg ist, ob keine Teilnehmerzeile liegen blieb, ob der Anhang von der Platte verschwand -- und mit Gegenprobe, dass der Anhang-Ordner selbst stehen bleibt. Ohne die waere "Datei ist weg" auch dann gruen, wenn es sie nie gab; genau das ist beim ersten Lauf passiert (der Upload lief ins 415, weil ich ihn als Formular statt roh geschickt hatte). Dazu: Wegraeumen ist NICHT Aufloesen (Ben raeumt weg, Cem hat alles noch), ein Zweier-Gespraech laesst sich gar nicht aufloesen, ein Aussenstehender bekommt 404 statt 403, ein zweiter Versuch findet nichts, und die Zustaendigkeit eines aufgeloesten Kanals wird wieder frei (sonst haette der eindeutige Index sie dauerhaft blockiert). Nebenbei: Die drei Kopfknoepfe schoben sich jeder einzeln mit `margin-left: auto` nach rechts. Bei zwei sichtbaren teilen sich zwei auto-Raender den freien Platz und reissen sie auseinander -- und WELCHE sichtbar sind, entscheidet der Server. Jetzt schiebt ein Behaelter einmal, die Knoepfe stehen beieinander, egal wie viele es sind. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
d92ba76e33 |
Kategorie-Kanaele und angeheftete Ankuendigungen (Kapitel 7.2)
Die vier Saetze aus dem Anforderungsdokument, der Reihe nach: Team- Gruppenchat, Kategorie-Kanaele mit Zugriff fuer Owner und rechte Hand, private 1:1-Chats OHNE diesen Zugriff, und Pin-Nachrichten an alle. EIN KANAL IST KEINE VIERTE TABELLE, sondern eine dritte Art Raum (`art = 'kanal'` neben 'direkt' und 'gruppe'). Damit gilt fuer ihn ohne eine einzige neue Zeile alles, was schon da ist: Verlauf, Anhaenge, Suche, Ungelesen-Zaehler, Live-Strom, Wegraeumen. Eine eigene Tabelle haette all das ein zweites Mal gebraucht -- und die zweite Fassung waere die gewesen, in der die Zugriffsregel fehlt. Welche Zustaendigkeit, kommt aus MODI_KATEGORIEN -- derselben Liste, aus der auch die Aufgaben ihre Kategorie nehmen. Der NAME kommt aus der Kategorie und ist kein freies Feld: "Clipping" neben "Clipping-Team" waeren zwei halbe Verlaeufe, und man merkt es erst, wenn jemand die Antwort im falschen sucht. Ein eindeutiger Teilindex haelt das auch dann fest, wenn zwei Anfragen im selben Augenblick ankommen. DIE ZUGRIFFSREGEL STEHT IN istDrin() -- der Funktion, durch die alle sieben lesenden und schreibenden Wege gehen. In den Routen stuende sie in sechs davon und in der siebten nicht. Sie gilt AUSDRUECKLICH nur fuer 'kanal': Zweier-Gespraeche bleiben zu, auch fuer DogFather (so steht es im Dokument), und Gruppen ebenfalls -- wer eine Gruppe aufmacht, hat sich fuer einen geschlossenen Kreis entschieden, und den nachtraeglich still zu oeffnen waere das Gegenteil dessen, was er getan hat. Wenn Filipe das anders will, ist es eine Zeile -- aber es waere seine Entscheidung und muesste fuer die Beteiligten SICHTBAR sein. istDrin() nimmt dafuer die PERSON statt ihrer Nummer und wirft bei einer Nummer einen Fehler, statt stillschweigend "nein" zu antworten. HOECHSTENS DREI ANKUENDIGUNGEN je Raum. Nicht eine (Regeln, Live-Plan und Frist muessen gleichzeitig oben stehen koennen) und nicht beliebig viele -- eine Pinnwand, die scrollt, ist ein zweiter Verlauf. Der Aushang hat eine EIGENE Abfrage, weil der Verlauf nur 200 Zeilen liefert: Eine Ansage von vorletzter Woche waere sonst genau dann weg, wenn sie am laengsten oben stehen sollte. Wird die Nachricht zurueckgenommen, faellt sie ab UND gibt den Platz frei. DREI DINGE, DIE ERST DAS HINSEHEN GEZEIGT HAT: Der frisch angelegte Kanal hatte zwei Leute statt vier. Die Personenauswahl zeichnete nach der Rollenfolge aus bereiche.js -- wer dort nicht steht, wurde NICHT GEZEICHNET. Team Dogi steht dort nicht und darf es auch nicht (der Rollenname gehoert in keine Datei, die jeder herunterlaedt). Folge: DogFather konnte ueber die Auswahl niemandem aus seinem Team schreiben. Der Server schickt die Ueberschrift jetzt mit; der Browser braucht dafuer keinen Rollennamen. Der Kommentar, der genau davor warnte, stand die ganze Zeit darueber. Dieser Fehler war nebenbei ein Netz: Was nicht gezeichnet wird, kann auch nicht falsch gezeichnet werden. Deshalb ist jetzt gemessen, dass ein Manager und Spicy Media Team Dogi gar nicht erst geschickt bekommen -- und dabei fiel auf, dass Spicy Media in der EIGENEN Auswahl stand: Sobald es jemanden zu verbergen gibt, schreibt ohneVerborgene() aus "sieht alles" eine echte Liste, und darin steckt man selbst. Am Fuss jeder Nachricht stehen jetzt vier Handgriffe statt drei. Bei 390 px -- der haeufigsten Handybreite -- stand "kopieren" 18 px ueber der Blase, bei 320 px 75. Behoben mit `flex-wrap: wrap` und nicht mit einer Schwelle: Eine Regel, die misst, bleibt beim fuenften Handgriff richtig; eine Zahl nicht. pruef-chat-optik misst es ab jetzt. NACHGEZOGEN, was pruef-css-klassen an MEINEM letzten Commit fand: teamlage.html lud kopf.js ohne wahl.js (der Sicht-Umschalter sah aus wie aus einem anderen Programm -- kaputt war nichts, und genau deshalb faellt es niemandem auf), und .tampel__tag stand auf 11,2 px. Beides war schon gepusht, weil ich die Pruefung nicht laufen liess. pruef-chat-kanaele 73 (neu) · pruef-chat 48 · pruef-chat-ausbau 64 · pruef-chat-anhaenge 60 · pruef-chat-optik 24 -> 26 · pruef-css-klassen gruen · pruef-rollen 274 · pruef-modi-verborgen 78 · pruef-team-ampel 28 · pruef-start-ansicht gruen · pruef-modi-wortleck 5 · pruef-zwischenspeicher 21. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
6c48579f66 |
Die Kopfleiste bleibt auch in einer fremden Sicht in EINER Reihe
Filipe, mit Bildschirmfoto aus der installierten App: "es ist noch nicht alles in einer zeile und irgendwie funktionieren nicht alle knoepfe." DER GRUND WAR NICHT DIE BREITE SEINES GERAETS, SONDERN DER ZUSTAND. In der eigenen Sicht klappt der Umschalter auf 36 px zusammen; sobald man die Sicht einer anderen Person uebernimmt, stand der Name darin und er war 152 px breit. Gemessen waren es dann zwei Zeilen bei 320, 360, 390, 412 UND 430 px -- ausnahmslos. Auf seinem Bild stand "Miesmus..." im Umschalter und der goldene Rahmen um die Seite: er war in einer fremden Sicht. MEINE PRUEFUNGEN HABEN DEN FALSCHEN ZUSTAND GEMESSEN. pruef-handy lief ausschliesslich in der eigenen Sicht und war deshalb gruen, waehrend es beim Nutzer zweizeilig war. Ein gruener Haken sagt nur, dass die Bedingung erfuellt war -- nicht, dass sie den Zustand geprueft hat, in dem der Nutzer ist. Die Pruefung wechselt jetzt selbst in eine fremde Sicht (92 -> 99 Pruefungen). WAS SICH AENDERT - Auf dem Handy ist der Umschalter auch in fremder Sicht ein Zeichenknopf: Auge + Anfangsbuchstabe, 46-48 statt 152 px, in der ROLLENFARBE der Person, deren Sicht laeuft. Die Farbe kommt aus `data-rolle` -- dieselbe Zuordnung, die gate.css ohnehin hat, keine zweite Farbliste. - Der volle Name wandert in ein Band unter die Leiste, zusammen mit "Zurueck zu meiner Sicht" als ganzem Satz statt als 28-px-Kreuz. Er steht dort GANZ statt als "Miesmus...". Am Rechner bleibt alles wie bisher; dort ist Platz. - Der Rahmen um die Seite nimmt dieselbe Farbe an. Man sieht damit nicht nur DASS eine fremde Sicht laeuft, sondern WESSEN. - Das `:not([data-fremd="ja"])` faellt an beiden Stellen weg. Es war der ganze Fehler: eine Regel, die den wichtigeren Fall ausnahm. UND DER BLOCK FUER SCHMALE GERAETE STAND AN DER FALSCHEN STELLE Er galt bis 340 px und stand 3600 Zeilen VOR dem 560er-Block -- bei gleicher Spezifitaet verliert er damit. Gewirkt hat er nur, weil sein Selektor zufaellig ein `:not()` trug. Jetzt steht er direkt hinter dem 560er und gilt bis 400 px (34 px je Knopf, 4 px Abstand). Damit bleibt auch bei 360 px auf den UNTERSEITEN alles in einer Reihe -- dort stehen zusaetzlich der Zurueck-Knopf und die Glocke. Gemessen nach dem Umbau, eigene und fremde Sicht, Start- und Unterseite: 360, 390, 412 und 430 px alle einzeilig. Offen bleibt 320 px (iPhone SE 1. Generation bzw. Anzeige-Zoom) -- dort passt es ohne das Weglassen einer Funktion nicht, das ist eine Entscheidung und kein Handgriff. DER SICHERE BEREICH (auf Filipes Zusage) Jede der 20 Seiten sagt `viewport-fit=cover`, aber im ganzen Workspace stand kein einziges `env(safe-area-inset-*)`. Sein Android ist NICHT betroffen (im Bildschirmfoto nachgesehen), ein iPhone waere es: Von einem 36-px-Knopf blieben unter einer 47 px hohen Statusleiste rechnerisch 5 px zum Antippen. Einmal zentral benannt (gate.css) und an den vier Stellen angewandt, wo etwas am Rand klebt: Kopfleiste (oben und seitlich), Inhalt (seitlich und unten), Speichern-Leiste im Profil, Chat-Eingabe. Auf Geraeten ohne Aussparung sind alle vier Werte 0. Nebenbei: chat.js misst die Hoehe ueber der Chatflaeche jetzt einschliesslich des Bandes -- sonst stuende das Eingabefeld genau um dessen Hoehe unter dem Bildschirmrand. Derselbe Fehler wie mit den festen 62 px, nur mit einem anderen Element. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
14e9bbf7a5 |
Chat: Fotos und PDFs schicken, Gespraeche wegraeumen
Filipe, mit Bildschirmfoto: "man muss die chats auch geloescht bekommen!!! am besten waere es auch wenn man da auch im chat pdfs schicken koennte. pdfs und fotos." Zwei Entscheidungen vorher abgestimmt, weil sie den Bau bestimmen: Geloescht wird NUR BEI MIR. Schicken duerfen ALLE im Gespraech, auch Creator -- anders als in der Dateiablage, wo etwas in einem Bereich landet, den mehrere sehen. Hier bekommt es genau der, mit dem man ohnehin gerade spricht. --- ANHAENGE --- Drei Wege zur selben Sache, weil Leute unterschiedlich arbeiten: die Bueroklammer, Hineinziehen und Einfuegen mit Strg+V (der Weg fuer einen Screenshot -- der liegt in der Zwischenablage und nirgends als Datei). Alle drei laufen durch dieselbe Funktion; drei Fassungen waeren drei Gelegenheiten, dass eine die Pruefung vergisst. Ein Foto wird GEZEIGT, ein PDF wird als Karte ANGEBOTEN. Das ist kein Schoenheitsunterschied: Ein Bild erkennt man in einer Zehntelsekunde, ein PDF muss man ohnehin oeffnen -- eine Vorschau davon waere ein grauer Kasten, der so tut, als koennte man etwas lesen. DIE SICHERHEIT STEHT IN dateiErkennen(). Dateiname und Content-Type kommen vom Absender und sind frei erfunden; der Typ wird deshalb aus den ersten Bytes bestimmt (PNG/GIF/WebP/JPEG/PDF, mit Breite und Hoehe im selben Durchgang). SVG steht absichtlich NICHT in der Liste -- das ist XML, das Skripte enthalten darf, ein als Bild getarntes Programm. Ausgeliefert wird spaeter genau der ERKANNTE Typ, nie der eingeschickte, dazu nosniff und "default-src 'none'; sandbox". Auf der Platte bekommt jede Datei einen erzeugten Zufallsnamen, in einem Ordner ausserhalb des Repos. Zuruecknehmen loescht die Datei wirklich -- sonst waere sie im Verlauf weg und ueber die Adresse noch da, also nur der Anschein einer Ruecknahme. --- WEGRAEUMEN --- Zwei Spalten in chat_teilnehmer statt einer, wegen eines Randfalls: Bei einem Gespraech ohne jede Nachricht waere die Grenze 0 -- und 0 heisst sonst "nie geloescht". geloescht_am unterscheidet die beiden. Die Grenze wirkt in der Liste, im Verlauf, in der Vorschau, in der SUCHE, bei den Anhaengen und in der Ungelesen-Zahl. Die Suche ist die Stelle, an der so etwas typischerweise durchrutscht: aus der Liste weg, ueber die Suche noch da. --- DER FUND: 323 PIXEL --- Ein Bild ist spaeter fertig als der Rest der Seite. Beim Oeffnen springt der Verlauf ans Ende, dann kommt das Foto an und schiebt alles darunter weg -- man steht ploetzlich mittendrin, ohne etwas angeklickt zu haben. Das width/height-Attribut am <img>, wie man es ueberall liest, hilft hier NICHT: Es gibt nur das Seitenverhaeltnis. Damit daraus eine Hoehe wird, muss die Breite feststehen -- bei "width: auto" und einem nicht geladenen Bild ist sie 0. Der Platz wird jetzt am KASTEN reserviert (aspect-ratio + max-width aus den gemessenen Massen). Und die Pruefung dazu hatte denselben Fehler wie das Auge: Sie mass in einem Fenster, in dem das Bild laengst im Zwischenspeicher lag, und meldete tadellose 0 px. Sie misst jetzt in einem FRISCHEN Browser -- der Fall, um den es geht, ist der erste. --- SICHERUNG --- chat-anhaenge/ ist im selben Zug in tools/sicherung-holen.sh eingetragen, nicht spaeter, wenn es auffaellt: Genau so ist die Luecke bei den Profilbildern entstanden. tools/wiederherstellung-proben.mjs bestaetigt: "der Server benutzt 4 Datenordner", keiner fehlt. --- Pruefung --- server/pruef-chat-anhaenge.mjs, neu, 60 Pruefungen, alle gruen. Abschnitt 3 versucht ausdruecklich, hereinzukommen: HTML als bild.png, SVG als foto.png, SVG als svg, eine Textdatei, ein PNG-Kopf ohne Inhalt -- alle fuenf mit 415 abgewiesen, ein echtes JPEG danach mit 201 angenommen (sonst bewiese der Block nur, dass gar nichts durchkommt). 13 MB geben 413 mit lesbarem Text, nicht 500. Konsolenfehler werden nach ZEITPUNKT getrennt, nicht nach Statusnummer: Was waehrend eines absichtlichen Versuchs entsteht, ist gewollt. Nach Nummer zu filtern waere bequem und wuerde ab morgen echte 404 mit verschlucken. Ausserdem gruen: pruef-chat, pruef-chat-optik, pruef-chat-ausbau, pruef-css-klassen. Angesehen bei 1440 px und bei 390 px. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
e28724564a |
Chat: sechs Ergaenzungen -- und ein Absturz, den nie jemand gesehen hat
Filipe: "die kategorie chat, boah ich will dass du die wirklich ueberall perfektionierst. wirklich alles was gratis ist und hinzugefuegt werden kann ohne problem will ich drin haben bitte. ich will das es hoch profissionel und ultra krass geil ist." Zuerst Bestand aufgenommen, nicht gebaut: Suche, Ungelesen-Zahlen, die "ab hier neu"-Linie, Lesestand, Live-Strom, Antworten mit Zitat, Zuruecknehmen und Enter-zum-Senden gab es schon. Dazugekommen ist, was gefehlt hat und ohne fremde Bibliothek geht: 1. ADRESSEN SIND ANKLICKBAR. Gebaut als echte Knoten, nie ueber innerHTML -- ein Chat ist die eine Stelle, an der jeder schreiben darf. Erkannt wird bewusst wenig (http, https, www.): Wer mehr erkennt, macht irgendwann aus "z.b." einen Link ins Nichts. Satzzeichen am Ende bleiben beim Satz. rel="noopener noreferrer". 2. KOPIEREN je Nachricht, mit Rueckfall auf "Text markieren", wenn der Browser die Zwischenablage nicht hergibt. 3. DER VERLAUF REISST NIEMANDEN MEHR WEG. Vorher sprang er bei JEDEM Neuzeichnen ans Ende -- wer weiter oben nachlas und dabei eine Nachricht bekam, verlor die Stelle. Jetzt bleibt er stehen, und ein Knopf sagt, WIE VIEL unten wartet, nicht nur DASS etwas da ist. 4. ENTWUERFE JE GESPRAECH. Wer mitten im Satz wechselt, findet ihn wieder. Im localStorage, nicht auf dem Server: Ein Entwurf ist nichts, was jemand anders sehen soll. Abgeschickt heisst geloescht. 5. EMOJI-AUSWAHL, dreissig feste Zeichen, eingefuegt an der Cursorstelle. Am Handy hat die Tastatur sie ohnehin -- am Rechner nicht, und dort sitzt die Betreuung. 6. ZEICHENZAEHLER, sichtbar ab 400 Rest. Die Grenze steht NICHT im Skript, sondern kommt aus dem maxlength des Feldes -- zwei Stellen fuer dieselbe Zahl laufen auseinander. --- DER FUND, um den es eigentlich geht --- Die neue Pruefung hoert auf "pageerror". Damit kam sofort neun Mal dieselbe Meldung: "Cannot set properties of null (setting 'hidden')", raumOeffnen, Zeile 278. Ursache: verlaufZeichnen() leerte den Verlaufskasten mit `textContent = ''`. Darin liegt aber #verlauf-leer, der Absatz "Links ein Gespraech auswaehlen". Nach dem ersten Zeichnen gab es ihn nicht mehr, und raumOeffnen faellt sechs Zeilen weiter darueber. Die Folge ist nicht die Fehlermeldung, sondern der Abbruch: Beim ZWEITEN Aufruf liefen history.replaceState, gelesenMelden() und raeumeZeichnen() nie. Der zweite Aufruf ist der Normalfall -- der Ereignisstrom ruft nach jedem Verbindungsaufbau genau das, um nachzuholen, was waehrend der Pause geschrieben wurde. Dieses Nachholen hat nie funktioniert. Von aussen sah alles normal aus; nur die Konsole wusste Bescheid. Behoben, indem nur noch die Nachrichten entfernt werden und der Absatz stehenbleibt. Abschnitt 8 der Pruefung wechselt jetzt dreimal zwischen zwei Gespraechen OHNE Neuladen und verlangt null Abstuerze. --- UND EIN ZWEITER, der schon laenger drin war --- Abschnitt 9 misst den Kontrast an der wirklichen Flaeche (Text kurz unsichtbar, Flaeche fotografiert). Die Fusszeile jeder Nachricht stand auf --text-still: auf der eigenen Blase 3,68:1, unter den 4,5:1 fuer Text dieser Groesse. Aufgefallen ist es nie, weil niemand nachgemessen hat. Jetzt traegt .chat-nachricht__fuss EINE Farbe (--text-leise, 4,81:1) und Uhrzeit, antworten, zuruecknehmen und kopieren erben sie -- statt vier eigener Angaben, die beim naechsten Mal auseinanderlaufen. --- Pruefung --- server/pruef-chat-ausbau.mjs, neu, 64 Pruefungen, alle gruen. Zu jedem Punkt eine Gegenprobe: kein Link ohne Adresse, keine Auszeichnung aus <b>/<img onerror>, kein Kopier-Knopf an zurueckgenommenen Nachrichten, kein Sprungknopf fuer den, der schon unten steht, kein Entwurf nach dem Abschicken, ein absichtlich zu dunkler Text faellt durch, und ein absichtlich geworfener Fehler wird bemerkt (sonst waere Abschnitt 10 auch gruen, wenn niemand zuhoert). Ausserdem gruen: pruef-css-klassen, pruef-chat, pruef-chat-optik. Angesehen bei 1440 px und bei 390 px. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
7de32a5ec7 |
Punkt 15: Der Chat bekommt Suche, Antworten mit Zitat und die Ungelesen-Linie
Wunsch Filipe: "ich will dass du diese seite viel krasser und detaillierter machst, ich will dass du dich informierst und alles reinsetzt was wir noch gebrauchen koennten." NICHT ALLES, SONDERN WAS TAEGLICH FEHLT. Der Chat konnte schon Raeume, Verlauf, Gelesen-Stand, Live-Zustellung, Gruppen und Zuruecknehmen. Drei Dinge fehlten, und jedes davon kostet ohne es echte Zeit: 1. SUCHE IN DEN NACHRICHTEN. Ein Chat ohne sie ist ab dem zweiten Monat ein Archiv, in dem man nichts findet. Ein Suchfeld gab es -- es durchsuchte aber nur die NAMEN der Gespraeche, also die kleinere Haelfte. Jetzt durchsucht dasselbe Feld beides und zeigt die Fundstellen UNTER der Gespraechsliste: Wer "Patrick" eingibt, will vielleicht das Gespraech und vielleicht die Nachricht -- ein Umschalter haette ihn zwingen wollen, das vorher zu wissen. 2. ANTWORTEN MIT ZITAT. Zu zweit weiss man meistens, worauf sich etwas bezieht. In einer Gruppe laufen drei Faeden parallel, und "ja, mach das" kann alles heissen. Das Zitat steht IN der Blase (es gehoert zur Antwort, nicht darueber) und fuehrt per Klick zur Stelle. 3. DIE LINIE "AB HIER NEU". Wer nach zwei Tagen zurueckkommt, sucht sonst die Stelle, an der er aufgehoert hat, indem er Uhrzeiten liest. BEWUSST NICHT GEBAUT: Anhaenge (dafuer gibt es den Dateien-Bereich mit Rechten und Ablauf), Reaktionen (eine vierte Sache, bevor die drei sich bewaehrt haben) und Tipp-Anzeigen (dauernder Verkehr fuer eine Auskunft, die man in zwei Sekunden ohnehin sieht). DIE SICHERHEIT DER SUCHE STEHT IM JOIN, nicht in einer nachtraeglichen Pruefung: `chat_teilnehmer` wird mit der eigenen Personenkennung verbunden, und was dort nicht drinsteht, kommt gar nicht erst aus der Datenbank. Ein Filter, der erst hinterher aussortiert, ist eine Zeile davon entfernt, vergessen zu werden. Ebenso beim Zitat: Worauf geantwortet wird, muss im SELBEN Raum liegen -- sonst koennte jemand die Kennung aus einem fremden Gespraech mitschicken, und beim Empfaenger stuende ein Zitat aus einem Raum, den er nie gesehen hat. DREI FEHLER, DIE DER DURCHLAUF GEFUNDEN HAT: 1. `ESCAPE '\'` IN EINEM TEMPLATE-LITERAL. Dort ist `\'` eine Fluchtsequenz fuer das Anfuehrungszeichen -- SQLite bekam ein LEERES Fluchtzeichen und antwortete "ESCAPE expression must be a single character". Die Suche war damit komplett tot. Kein Syntaxfehler, kein Warnhinweis: Erst der Aufruf mit echten Daten hat es gezeigt. 2. DIE MASKIERUNG KANNTE ZWEI VON DREI ZEICHEN. `%` und `_` waren dabei, der Backslash nicht -- ausgerechnet das Fluchtzeichen selbst. Geprueft wird das jetzt an der ZEILE AUS DER DATEI, nicht an einem Nachbau: Mein erster Test hat die Maskierung nachgebaut und dabei die Shell-Maskierung mitgeschleppt -- er meldete einen Fehler, den nur er hatte. 3. DIE UNGELESEN-LINIE SCHIEN NICHT ZU FUNKTIONIEREN. Sie tat es -- mein Testaufbau war falsch: Filipes Seite war noch offen, die neuen Nachrichten kamen ueber den Live-Strom an und wurden sofort als gelesen gemeldet. Es gab schlicht nichts Ungelesenes. Erst als er die Seite verlaesst, bevor Patrick schreibt, steht die Linie da -- und zwar genau vor "Neu von Patrick, eins", und beim zweiten Oeffnen ist sie weg. Der Gelesen-Stand wird deshalb beim OEFFNEN mitgeschickt, bevor er gesetzt wird -- eine Zeile spaeter waere er immer die letzte Nachricht, und die Linie staende nie irgendwo. Ohne Volltextindex, mit Absicht: `LIKE` liest die Tabelle, und bei einem Team dieser Groesse sind das einige tausend Zeilen. Ein FTS5-Index waere eine zweite Tabelle, die synchron gehalten werden muss -- genau daran gehen solche Sachen kaputt. Wenn der Verlauf sechsstellig wird, ist das der Zeitpunkt dafuer, nicht heute. Geprueft: pruef-chat, pruef-chat-optik, pruef-css-klassen, pruef-workspace-seiten, pruef-handy -- alle in Ordnung. Dazu im Browser durchgespielt: Zitat gesetzt und gelesen, Suche nach "Bitrate" (1 Treffer), nach "100 %" (1 Treffer -- die Maskierung haelt), nach Unsinn (0), einbuchstabige Suche (zu kurz), Antwortleiste mit dem richtigen Namen, Ungelesen-Linie an der richtigen Stelle und beim zweiten Oeffnen weg. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
dd1f561f3b |
Vier Meldungen -- und dahinter zweimal derselbe alte Fehler
DIE SYMBOLE IN DER TAGESKACHEL WAREN DIESELBEN -- OHNE IHRE GESTALTUNG
Sie kommen vom selben Bauer wie alle anderen, bekamen aber nie dessen
Aussehen: Alle Lagenregeln waren auf `.kachel__svg` eingegrenzt, und
dieses Zeichen heisst `.dran__svg`. Uebrig blieb eine flache Kontur --
daneben, auf derselben Seite, dieselben Zeichen mit drei Lichtern,
Tiefe und Randlicht. Die Regeln gelten jetzt fuer beide Traeger, und
das Feld darum ist dasselbe gefasste Schild wie auf den Kacheln.
"UNDEFINED" IM CHAT -- DERSELBE FEHLER WIE HEUTE FRUEH, NUR ALS OBJEKT
Ueber Cigdems Namen stand woertlich "UNDEFINED". Die Rollennamen
standen als Objekt in FUENF Skripten (chat.js zweimal, dateien.js,
kalender.js zweimal), in keinem davon 'spicy'.
Heute Frueh war es dieselbe Sache als Menge (`new Set([...])`), und
seitdem sucht `pruef-css-klassen.mjs` danach. Ein Muster, das nur eine
Schreibweise kennt, findet auch nur eine -- die Pruefung sucht jetzt
auch nach Rollen-OBJEKTEN, mit Gegenprobe. Die Namen stehen an EINER
Stelle in bereiche.js.
DOGFATHER UND SPICY MEDIA SIND IM CHAT FUER JEDEN ERREICHBAR
DogFather kam bisher als Nebeneffekt ueber die Betreuungskette mit
hinein, Spicy Media gar nicht -- die Rolle steht in keiner Kette, sie
steht daneben. Beide werden jetzt ausdruecklich hinzugefuegt: Eine
Zustaendigkeit, die nur zufaellig aus einer anderen Regel herausfaellt,
faellt beim naechsten Umbau genauso zufaellig wieder heraus.
Gemessen aus der Sicht eines Creators -- wer bei ihm ankommt, kommt
ueberall an.
DIE PERSONENLISTE: SPICY MEDIA SIEHT ALLES AUSSER DOGFATHER
Der Abschnitt "Spicy Media" fehlte in der Liste komplett -- die Rolle
gibt es seit heute Frueh, die Personenseite kannte sie nicht. Und Spicy
Media selbst sah dort bisher nur das Anlegen-Formular; sie bekommt
jetzt die Liste, ohne DogFathers Zeile, und weiterhin ohne Codes,
Sperren, Loeschen und Protokoll. Ueberblick ist nicht Verwaltung.
ZWEI FOLGEFEHLER, BEIDE VON DEN PRUEFUNGEN GEFUNDEN
* `next("route")` TUT DAS GEGENTEIL VON DEM, WONACH ES KLINGT. Mein
erster Versuch war eine Ausnahme-Route VOR der Schranke, die mit
`next("route")` weiterreicht -- das ueberspringt aber die restlichen
Handler DIESER Route und geht zur naechsten Schicht, also genau zur
Schranke. Spicy bekam weiter 404, die Oberflaeche verstand das als
"nicht erlaubt" und sprang zur Startseite. Gemessen: Auf
personen.html standen die Kategorien der STARTSEITE.
* DAS PROTOKOLL WARF SIE VON DER SEITE. Es bleibt bei DogFather und
antwortet ihr mit 404 -- und `hole()` versteht ein 404 unter
`/verwaltung/` als "nicht erlaubt". Die Seite baute sich auf und
sprang im naechsten Atemzug weg. Eine Abfrage, von der man weiss,
dass sie 404 gibt, stellt man nicht.
UND EINE MEINER EIGENEN NEUEN PRUEFUNGEN WAR WERTLOS
"bei ihr fehlt der Abschnitt DogFather" -- gruen, mit dem Zusatz
"(keine Abschnitte)". Sie war gruen, weil die Liste bei ihr GAR NICHT
DA war. Genau der Haken, der nichts beweist. Er steht jetzt neben einem
Ergebnis, das etwas enthaelt: "Spicy Media | Manager | ...".
18 Pruefungen gelaufen, alle gruen. pruef-spicy von 49 auf 57.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
ac432d85e1 |
Spicy Media: sieben stille Luecken -- und der Kalender zeigt wirklich nur noch Eigenes
Filipe hat drei Sachen gemeldet. Zwei davon waren nicht das, wonach sie
aussahen.
1. "BEI DER SPICY ROLLE IST DA EIN PROBLEM" (Creator-Profil laedt nicht)
Nicht diese Seite war kaputt. In NEUN Skripten stand dieselbe Zeile
const LEITUNG = new Set(['admin', 'manager']);
und in keinem davon 'spicy'. profil.js nahm deshalb den Creator-Zweig
und lud das EIGENE Profil -- ein Spicy-Zugang ist kein Creator, also
404. Acht der neun sind nicht kaputtgegangen; sie haben sich still
falsch verhalten.
Die Liste steht jetzt EINMAL in bereiche.js. Beim Aufraeumen kamen mit
derselben Suche sechs weitere Luecken heraus, alle vom selben Typ:
* Aufgaben abbrechen -- Server UND Knopf ohne 'spicy'
* Teilen-Knopf in der Kopfleiste -- ohne 'spicy'
* Chat: die Gespraechsliste laeuft ueber eine feste Rollenfolge.
Wer nicht darin steht, taucht gar nicht auf -- eine Person, die es
fuer die anderen nicht gibt.
* Kalender: dieselbe Rollenfolge, dort landete Spicy Media durch
indexOf() === -1 ganz oben statt an ihrem Platz.
* Dashboard: "Creator anlegen" nur fuer admin/manager -- der Server
haette sie gelassen, den Knopf hat sie nie gesehen.
* Personenliste: ROLLENNAME ohne 'spicy'. Der Auffangwert
`|| p.rolle` schrieb "spicy" statt "Spicy Media" -- plausibel
genug, um jahrelang zu bleiben.
`pruef-css-klassen.mjs` verlangt jetzt, dass kein Workspace-Skript sich
wieder eine eigene Rollenliste baut. Mit Gegenprobe, dass der Sucher so
eine Liste auch wirklich findet.
2. "DIE ZAHLEN DIESE KATEGORIE NICHT SEHEN"
Kachel und Seite waren beim Anlegen der Rolle auf ["spicy","admin"]
gesetzt worden -- "dieselben Rechte ausser Automationen". Beides jetzt
auf DogFather allein.
3. "IN CIGDEMS KALENDER STEHT IMMER NOCH MEIN MANAGER MEETING"
Das war MEIN Denkfehler von heute Frueh, nicht ein vergessener Fall.
Ich hatte "geht alle an" als "kein Teilnehmer eingetragen" definiert --
also entschied der Server, was alle angeht, und nicht der, der den
Termin anlegt. Wer niemanden eintraegt, meint aber meistens nicht
"alle", sondern "mich".
Der Fall ist entfallen. Sichtbar ist ein Termin jetzt nur noch fuer
den, der ihn angelegt hat, dem er zugeordnet ist, der das Gegenueber
ist -- oder der in der Teilnehmerliste steht. Damit ist das Markieren
im Termin die einzige Antwort auf "wen geht das an": eine sichtbare
Entscheidung im Formular statt einer unsichtbaren Regel im Server.
Calls & Protokolle rufen dieselbe Funktion auf und koennen deshalb gar
nicht auseinanderlaufen -- das war Filipes vierter Wunsch, und er ist
mit derselben Zeile erledigt.
Am laufenden System als Cigdem nachgemessen: Profil laedt ("Profil:
Luna"), Zahlen-Kachel weg und Seite gesperrt, im Kalender NUR der
Termin, bei dem sie markiert ist, Calls zeigt genau denselben.
Fuenf Pruefungen auf die endgueltige Regel umgeschrieben statt
geloescht (sicht, spicy, teilnehmer, scout-zuteilung, css-klassen).
Die dritte Drehung bei scout-zuteilung steht mit allen drei Staenden
in der Akte -- eine geloeschte Pruefung hinterlaesst keine Spur davon,
dass hier einmal etwas anderes galt.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
e8478c9cae |
Spicy sieht DogFathers Sachen nicht mehr -- und sechs Fehler dazu
VIER DINGE AUS DEN BILDSCHIRMFOTOS, jedes ein echter Fehler:
1. SPICY MEDIA SAH DOGFATHERS DATEN. Beim ersten Anlauf bekam die Rolle
dieselbe Regel wie DogFather (`1=1`) -- damit stimmte der Ueberblick
ueber Manager, Scouts und Creator, und nebenbei standen seine eigenen
Termine, Aufgaben, Dateien und Eintraege mit drin. Jetzt gibt es
ohneDogFather() als EINE Stelle dafuer: Zwei Spalten werden geprueft,
`creator_id` (um wen geht es) und `erstellt_von` (wer hat es
geschrieben) -- ein Termin, den er sich selbst anlegt, haengt nur an
der zweiten. `IS NULL OR NOT IN` und nicht bloss `NOT IN`: In SQL ist
`NULL NOT IN (...)` weder wahr noch falsch, die Zeile fiele
stillschweigend heraus.
2. "PERSOENLICHER ZUGANGSCODE · undefined" auf der Anmeldeseite. Eine
zweite Namensliste im Browser, die beim Hinzufuegen der Rolle
niemand gepflegt hat. Ein unbekannter Schluessel faellt jetzt auf
sich selbst zurueck statt auf `undefined` -- haesslich, aber
sichtbar.
3. SPICY KAM NICHT IN DIE PERSONENVERWALTUNG. Der Server liess sie
herein, das Skript warf sie wieder hinaus: zwei Listen fuer dieselbe
Frage, gepflegt wurde nur die erste.
4. DIE ANMELDEKARTE WAR ZU KLEIN FUER FUENF ROLLEN. Der Kommentar an
genau dieser Stelle warnt woertlich davor -- und ich habe getan,
wovor er warnt: eine Rolle eingefuegt und die Zahl daneben nicht
angefasst. Gemessen: Inhalt 573 px in einer 526 px hohen Tafel, die
Fusszeile stand unter dem Rahmen. Schrift kleiner half nicht (sie lag
schon auf dem Anschlag), also sind die Abstaende an neun Stellen
enger. Nachgemessen auf fuenf Groessen: passt ueberall.
DIE ZEIT WAR WIRKLICH FALSCH. Nicht nur in meinem Satz: `datum()` in
personen.js schnitt die ISO-Zeichenkette ab -- und die ist UTC. Im
Protokoll stand 03:00, wo 05:00 war. Das Tueckische daran ist, dass es
nie kaputt aussieht: Eine Uhrzeit ist immer plausibel.
PROFILBILDER WERDEN JETZT GEZEICHNET. Der Server lieferte sie seit
gestern mit, gezeichnet wurden sie nirgends -- deshalb aenderte sich
nichts. Jetzt in der Personenauswahl (Aufgaben, Termine, Dateien,
Bereiche), in der Gespraechsliste und an jeder Nachricht. Der
Anfangsbuchstabe bleibt als Unterlage LIEGEN: Faellt das Bild aus, steht
dort weiter etwas Sinnvolles.
DER CHAT: Gesichter mit Rollenfarbe, Blasen mit Richtung (die erste
einer Folge eckig, die naechsten rund -- so sieht man, wo ein Gedanke
anfaengt), das offene Gespraech mit Schiene, Ungelesenes hervorgehoben,
und das Eingabefeld in einer eigenen Leiste, die sich beim Schreiben
hebt.
ZWEI EIGENE PATZER, beide von Pruefungen gefunden:
- `o is not defined`: Mein Suchmuster hat die zwei Zeilen fuer das
Bild ans DATEIENDE gesetzt statt in die Schleife -- und in
kalender.js an einen <span> statt ans <option>. Gemeldet von
pruef-sicht, das die Browserkonsole mitliest.
- Ein Kommentar mit `bild` in schraegen Anfuehrungszeichen stand INNEN
in einer Vorlagenzeichenkette und hat sie geschlossen. Die halbe SQL
wurde zu Programmtext.
Dazu: `.chat-neu` gibt es nicht (heisst `.chat__eingabe`), und der
Rollenknopf hatte fuer den Manager keinen sichtbaren Fokus -- ein
box-shadow wird von `overflow: hidden` abgeschnitten, ein outline nicht.
Gruen: spicy (43), creator-anlegen (29), personen-liste (33), sicht (48),
chat (48), chat-optik (24), buehne (38), struktur (32), css-klassen (15),
handy (59), breiten (23), formulare (19), start-ansicht (136),
lesbarkeit (14), barrierefrei (18), tempo (8), kopf-messen (3),
glocke (26), haerte (20), manager-sicht (43), alle-wege (19),
aufgabenbrett (44), kalender (84).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
953c3f5721 |
Zahlen bekommen eine Oberflaeche, das Dashboard bekommt Zahlen
Der Server konnte seit gestern rechnen -- und niemand konnte etwas
eintragen. Ein Rechenwerk ohne Oberflaeche ist kein Modul, sondern ein
Versprechen. Das ist jetzt eingeloest:
* leistung.html: Wochenkarten (Wert, Vergleich zur Vorwoche,
Verlaufslinie), Ziele als Fortschrittsbalken, die letzten 14 Tage
zum Eintragen -- auch die LEEREN, denn eine Luecke ist selbst die
Auskunft. Import aus dem TikTok-Export mit Vorschau VOR dem
Schreiben.
* Kachel "Zahlen" als erste der Gruppe "Rund um den Creator", eigenes
Zeichen (steigende Linie, kein zweites Balkendiagramm).
* Dashboard: jede Creator-Karte traegt jetzt Diamanten, LIVE-Tage und
Verweildauer. Bis heute zeigte sie ausschliesslich ARBEIT -- ein
Creator konnte null ueberfaellige Aufgaben haben und gleichzeitig
seit drei Wochen einbrechen, und die Karte sah tadellos aus.
* Die Fruehwarnung steht oben im Dashboard. Sechs benannte Signale im
Klartext mit Beleg, bewusst OHNE Punktzahl -- ein Wert wie
"Abwanderungsrisiko 73" klingt nach Wissenschaft und ist eine
Behauptung, der man nicht widersprechen kann.
* chat.html?mit=<person>: der Weg von der Warnung ins Gespraech. Gab
es vorher nicht; ein Hinweis ohne Weg dahin ist nur ein schlechtes
Gewissen.
GEFUNDEN VON DEN PRUEFUNGEN, nicht von der Theorie:
1. Die Verlaufslinie zeichnete fuer vier der sieben Groessen NICHTS.
Der Server liefert im Verlauf nur drei Reihen; fuer den Rest kam
undefined an. `=== null` faengt das nicht, Number(undefined) ist
NaN, und ein <polyline points="NaN,NaN"> ist im DOM vorhanden und
auf dem Bildschirm unsichtbar -- ohne Fehlermeldung. Die Pruefung
misst deshalb die PUNKTE, nicht die Anwesenheit des Elements.
2. Fuenf Schriftgroessen im CHAT lagen unter 11,5 px (.68/.7 rem) und
waren seit vorgestern drin. Die Grundlinie der Groessenpruefung
stand auf 43, gemessen wurden 48. Nicht die Grundlinie angehoben,
sondern die fuenf Stellen behoben: Eine Grundlinie, die mitwaechst,
ist keine mehr.
pruef-leistung-optik.mjs: 57 Pruefungen, zwei echte Browser, Gegenprobe
zu jeder Aussage -- auch dazu, dass die Vorschau vor dem Bestaetigen
wirklich noch nichts geschrieben hat und dass ein Creator seine Zahlen
zwar SIEHT, sie aber weder eintragen noch die Fruehwarnung ueber sich
lesen kann (auch nicht ueber eine von Hand gebaute Anfrage).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4637aa24e7 |
Chat zwischen Creator, Scouts und Managern
Wunsch Filipe, 06.09.2026: *"eine kategorie chat, wo die creator mit
ihren manager nachrichten austauschen koennen, wie erinnerungen, fragen
und noch vieles mehr."* Auf Nachfrage entschieden: Zweier-Gespraeche UND
Gruppen; Manager und Scouts duerfen sich auch ohne gemeinsamen Creator
schreiben.
WER MIT WEM steht an EINER Stelle: schreibbareIds() in workspace.js.
Bewusst getrennt von einladbareIds() (Terminwahl): Dort geht es darum,
wen man zu einem Kalendereintrag dazustellen darf -- harmlos. Ein Chat
legt ein dauerhaftes Gespraech an, schickt eine Benachrichtigung und
macht den eigenen Namen sichtbar. Zwei Fragen, zwei Funktionen.
Ein Creator erreicht seine Betreuer und DogFather, KEINEN fremden
Creator. Eine Gruppe ist kein Schlupfloch: Jede Nummer wird einzeln
gegen dieselbe Regel geprueft.
SOFORT STATT NACHFRAGEN IM TAKT (SSE). Ein Chat, der alle fuenf
Sekunden fragt, ist fuenf Sekunden langsam und stellt bei zehn
Angemeldeten 7200 Anfragen in der Stunde fuer Nachrichten, die es
meistens nicht gibt. Kein WebSocket: Hier fliesst alles in eine
Richtung, und SSE uebersteht einen Verbindungsabriss von selbst.
DIE ZAHL STEHT AUF JEDER SEITE, nicht nur im Chat. Eine Nachricht, die
man erst sieht, wenn man den Chat aufmacht, ist keine Nachricht --
sie ist ein Fundstueck.
Push aufs Handy nur an die, die NICHT gerade zusehen. Wer die Seite
offen hat, sieht es ohnehin; ihm zusaetzlich etwas aufs Handy zu
schicken ist der schnellste Weg, dass er Benachrichtigungen abschaltet.
WAS BEWUSST NICHT GEHT:
* Niemand liest fremde Gespraeche mit -- auch DogFather nicht. Ein
Chat, in dem der Chef stillschweigend mitliest, ist kein Chat.
Er kann jederzeit jedem schreiben, aber sichtbar.
* Eine abgeschickte Nachricht laesst sich nicht aendern, nur
zuruecknehmen. Wer Absprachen nachtraeglich umschreiben kann, macht
den Verlauf wertlos. Zurueckgenommenes hinterlaesst einen Hinweis
statt eines Lochs.
DAZU: CALL-LISTE NACH ZEIT GEGLIEDERT
Wunsch mit Bild von "STEHT AN 27": *"die liste soll kategorisiert sein
und werden mit einem button zum auf und zu machen."* Jetzt Heute /
Diese Woche / Naechste Woche / Spaeter, offen nur der erste gefuellte
Block. Nach ZEIT und nicht nach Titel: Auf dem Bild waren fast alle
"Community-Talk" -- nach Titel gruppiert haette man zwei Ueberschriften
und darunter dieselbe lange Liste.
DER FUND, DER DIE FUNKTION GERETTET HAT: Ein zugeklappter Block zeigte
seinen Inhalt trotzdem -- 367 Pixel Hoehe bei open=false. <details>
versteckt seinen Inhalt naemlich nur, solange niemand dem Inhalt eine
eigene display-Angabe gibt, und .gruppe__karten traegt display:grid.
Der Knopf haette sich bewegt und sonst nichts getan. Im Bildschirmfoto
fiel es nicht auf, weil der Ausschnitt genau darueber endete.
Ausserdem gefunden und behoben:
* Ein Wettlauf beim Abschicken: War der Ereignisstrom schneller als
die Antwort auf das POST, stand die eigene Nachricht zweimal im
Verlauf.
* Die Chatseite war zu hoch -- die Kopfleistenhoehe stand als fester
Wert (62 px) im CSS, am Handy ist sie doppelt so hoch. Das
Eingabefeld stand halb unter dem Bildschirmrand. Jetzt gemessen.
* Der Platzhalter "Enter schickt ..." brach am Handy um UND stimmte
dort nicht: Ohne Tastatur schickt Enter absichtlich nicht.
* Der Dialog benutzte Klassen aus aufgaben.css, das chat.html nicht
lud -- gemeldet von pruef-css-klassen, bevor jemand einen
ungestylten Dialog zu sehen bekam.
Pruefungen: pruef-chat (44 Punkte, Rechte und Sichtbarkeit),
pruef-chat-optik (24, zwei echte Browser schreiben sich),
pruef-call-kategorien (16).
Co-Authored-By: Claude Opus 5 <[email protected]>
|