95c4599baa52df3bbabe9d5fc58f60190cb0206d
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
418b6211e2 |
Ein Hinweis auf eine Seite, die es hier nicht gibt, ist kein Hinweis
Filipe, mit dem Bildschirmfoto auf crew.: "wieso steht es noch da?" -- "1 Punkt im Start-Check braucht Handlung", mit einem Pfeil auf eine Seite, die seit einer Stunde dort gesperrt ist. MEIN FEHLER VON HEUTE MITTAG. Ich hatte die Seiten gesperrt und ausdruecklich dazugeschrieben "nur die Seiten, nicht die Schnittstellen" -- und dabei uebersehen, dass es eine DRITTE Stelle gibt. Die Hinweise auf der Startseite sind keine Seite und keine Schnittstelle, sondern eine Liste von VERWEISEN. Der Satz im Kommentar klang vollstaendig und war es nicht. Nachgesehen, wer sonst noch Seitenziele ausliefert, statt zu raten: workspace-hinweise.js alle 16 Hinweise, ueber dazu() -> behoben workspace-suche.js jeder Treffer traegt ein Ziel -> behoben workspace-push.js Benachrichtigungen tragen eines -> OFFEN Die ersten beiden bekommen dieselbe Regel wie die Seiten, nicht eine zweite: gehoertAufDieseAdresse(). Was hier keine Seite hat, bekommt hier auch keinen Hinweis und keinen Treffer. Bei der Suche fallen leere Gruppen mit weg (eine Ueberschrift ohne Treffer sieht aus, als waere etwas kaputt) und `gesamt` wird danach abgeleitet, sonst nennt die Zahl Treffer, die gar nicht dastehen. DIE ADRESSE IST IMMER DIE ECHTE: Beide Stellen benutzen `req.sicht || req.person`. Der Sicht-Umschalter aendert, WESSEN Zahlen dastehen -- nicht, auf welcher Wand man steht. Das Haus kommt deshalb aus req.person. PUSH BLEIBT OFFEN, und zwar bewusst: Eine Benachrichtigung entsteht, wenn niemand auf einer Adresse steht. Sie geht an ein GERAET, und das oeffnet die Adresse, als die es installiert wurde. Das ist eine andere Frage als diese hier, und eine halbe Antwort waere schlechter als keine. Gehoert eigens angesehen. Was die Gegenprobe gefunden hat -- an mir selbst, zweimal: Der erste Entwurf der Pruefung legte die Tabelle `startcheck` mit erfundenen Spalten selbst an. Die echte war laengst da, das IF NOT EXISTS schwieg, der INSERT scheiterte. Die Pruefung haette gemeldet, der Hinweis stehe nirgends -- richtig und wertlos. Und "kein Suchtreffer zeigt dorthin" stand ueber NULL Treffern. Jetzt wird erst nachgewiesen, dass die Suche denselben Menschen auf der Agenturadresse wirklich findet (1 Treffer -> profil.html). server/pruef-haus-seiten.mjs 34 Pruefungen (vorher 24), 0 Fehler pruef-sicht, pruef-haus-trennung 66, pruef-betreuung, pruef-manager-sicht 43 -- alle 0 Fehler Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
68bc116c36 |
Die Rolle "Spicy Media" -- und drei Fehler, die nur ihre Pruefung fand
DIE PERSONENTABELLE WURDE NEU GEBAUT. Eine Rolle ist ein erlaubter Wert in einer Spalte, und der steckt in einem CHECK -- den kann SQLite nicht aendern. Auf `personen` zeigen ZWEIUNDFUENFZIG Fremdschluessel. Deshalb wird der Bauplan NICHT abgeschrieben, sondern gelesen: Der CREATE-Text kommt aus sqlite_master, darin wird ausschliesslich die Rollenliste ersetzt, und die Kopierliste kommt aus PRAGMA table_info. Die beiden aelteren Umstellungen schreiben ihre Spalten von Hand ab -- `personen` hat seit damals SIEBEN dazubekommen (bild, ueber_mich, tiktok ...). Wer hier abschreibt, verliert alle Profilbilder. ZWEI FRAGEN, DIE MAN AUSEINANDERHALTEN MUSS: siehtAlles() = DogFather ODER Spicy Media -> Listen, Uebersichten istDogFather() = nur DogFather -> loeschen, Rollen, Codes Es waere weniger Arbeit gewesen, istDogFather() um "spicy" zu erweitern -- und genau das waere der Fehler: Spicy Media koennte dann DogFather loeschen. DER CHAT BRAUCHTE NICHTS. Er haengt allein an der Teilnehmerliste und kennt kein "das Management sieht alles". Spicy Media sieht fremde Gespraeche nicht, weil es dafuer keinen Weg gibt -- nicht, weil eine Abfrage es verbietet. DREI ECHTE FEHLER, alle von pruef-spicy gefunden, keiner vorher sichtbar: 1. MEIN EIGENER KOMMENTAR STAND IM BAUPLAN. SQLite hebt den CREATE-Text woertlich auf, samt Kommentaren. Ich hatte "'spicy' steht HIER mit drin" hineingeschrieben -- und die Erkennung suchte genau dieses Wort im ganzen Text. Ergebnis: Die Umstellung hielt die Tabelle fuer erledigt, obwohl die CHECK-Regel noch die alte war. Jetzt wird die Regel herausgeschnitten und NUR darin gesucht; der Kommentar steht ausserhalb des SQL. 2. DER SICHERUNGSNAME HATTE NUR MINUTEN. `VACUUM INTO` weigert sich, eine vorhandene Datei zu ueberschreiben -- zu Recht. Zwei Umstellungen in derselben Minute wollten in dieselbe Datei, die zweite scheiterte, und weil ohne Sicherung nicht umgestellt wird, blieb sie aus. Es sah nach "lief" aus (die Datei lag ja da) und war keine. Jetzt mit Sekunden. 3. EINE FRISCHE DATENBANK LEGTE DIE ALTE ROLLENLISTE AN und stellte beim allerersten Start sofort um -- Tabelle neu bauen, Sicherung schreiben, fuer nichts. Ein Bauplan, der sofort umgebaut werden muss, ist der falsche. Und ein vierter in der Pruefung selbst: Der Chat-Aufbau benutzte einen falschen Weg, das Gespraech entstand gar nicht -- "Spicy Media sieht 0 Gespraeche" war trotzdem gruen, weil es keine gab. Jetzt ist das Anlegen selbst eine Pruefung, und eine Gegenprobe zeigt, dass Max es sehr wohl sieht. DAZU: Manager sehen die Kachel "Personen & Zugaenge" -- die SEITE geht auf, die Schnittstellen nicht. Alles unter /verwaltung haengt weiter an `nurAdmin` und antwortet 404; sie sehen genau den Teil, fuer den es einen Weg gibt. Spicy Media legt Creator UND Manager an (zweite enge Tuer, Rolle steht auch dort nicht im Aufruf; ein Manager kommt durch sie nicht). Der Rollentext des Managers stimmte nicht mehr -- er legt jetzt Creator an. pruef-spicy: 36 Pruefungen, alle gruen. Ausserdem gruen: personen-liste (33), creator-anlegen (29), sicht (48), css-klassen (15), alle-wege (19), haerte (20), manager-sicht (43). Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
947c9d8a26 |
Agentur: Eintraege gehoeren allen -- und Events bekommen ein eigenes Formular
Gemessen am 07.09.2026, bevor irgendetwas geaendert wurde: Von drei Agentur-Eintraegen sah eine Creatorin genau EINEN -- den, der ihr zugeordnet war. Ein Event fuer alle traf weder `creator_id = ich` noch `erstellt_von = ich`; die Agentur-Seite war fuer jeden Creator leer. Nicht kaputt, nicht fehlerhaft: leer, so wie eine Seite aussieht, auf der noch nichts steht. Die Pruefung dazu war gruen. Sie legte ihre Testeintraege mit `creator_id: idLuna` an und pruefte damit einen Fall, den es im Alltag nicht gibt. - Bereichseinstellung `fuerAlle` + `ohneCreatorBezug`, daraus abgeleitet sichtbarEintrag(). BEWUSST neben sichtbar() statt darin: an derselben Funktion haengen Aufgaben, Dateien, Termine und Calls -- wer dort "1=1" einschleust, gibt nebenbei fremde Akten frei. Eine Gegenprobe mit einer zweiten Creatorin haelt das fest. - Die Zuordnung bietet nur noch "Agentur" an. Der Server verwirft eine Zuordnung ausserdem selbst -- inklusive des frei getippten Namens, und zwar NACH externPruefen: davor haette der Name den Riegel wieder aufgemacht. - "Event & Kampagne" heisst jetzt "Agentur-Events" und hat ein eigenes Formular: Von/Bis, Titel, Beschreibung, Aufgaben (Punkte und Preise), Regeln. Die Karte zeigt den Zustand als WORT (laeuft bis / startet / vorbei seit), nicht nur als Farbe. - Drei neue Spalten -- und sie stehen auch im Tabellenneubau vom 06.09. Der laeuft NACH dem Spaltennachtrag und haette sie samt Inhalt weggeworfen, ohne Fehler und mit stimmender Zeilenzahl. - Creator sehen weiterhin alles und tragen weiterhin nichts ein (403). Die Unterzeile sagt jetzt "alles, was hier steht" statt "alles, was zu dir gehoert" -- eine vollstaendige Liste soll sich nicht wie ein Ausschnitt lesen. pruef-agentur: 61 Pruefungen (vorher 40), alle gruen. Zwei eigene Fehler nebenbei gefunden und behoben: eine Beschriftung mit 11,2 px (Grenze 11,5) und ein Testdatum aus UTC statt Ortszeit. Zusaetzlich gruen: css-klassen, struktur, formulare, barrierefrei-workspace, handy. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
bede91921d |
Der sechste Bereich, und zwei Pruefungen, die den Lauf lahmgelegt haben
DER AGENTUR-BEREICH (Stufe 4 des Plans)
Kernprinzip 04 des Konzepts lautet woertlich "Die Agentur bleibt
angebunden" -- und dafuer gab es bis heute nichts. Fuenf Bereiche
standen, der sechste fehlte vollstaendig. Damit stand nirgends, welche
Kampagne laeuft, welche Schulung ansteht und wie ein Anliegen an die
Agentur ausgegangen ist. Das lief ueber private Nachrichten: nicht
auffindbar, nicht nachvollziehbar, beim naechsten Mal von vorn.
Vier Arten, und die vierte ist der Punkt: kampagne, schulung, anliegen
und ZUSTAENDIGKEIT. Die letzte ist keine Verlegenheit, sondern das, was
das Konzept ausdruecklich fordert -- Betreuung und Umsetzung sind unsere
Seite, offizielle Wege sind Agenturseite. Solange das nur im Kopf steht,
wird es bei jedem Streitfall neu verhandelt.
Der Umbau war das eigentliche Risiko, nicht der Bereich: Ein CHECK
laesst sich in SQLite nicht aendern, die Tabelle muss neu gebaut werden
-- und dabei werden ALLE vorhandenen Eintraege umgeschrieben. Deshalb
geht pruef-agentur.mjs (31 Pruefungen) den Weg wirklich: Sie baut eine
Datenbank im ALTEN Stand nach, fuellt sie mit allen fuenf Bereichen,
laesst die echte Anwendung darueberlaufen und zaehlt danach jede Zeile
UND jedes Feld nach -- auch die seltenen Spalten (hook, creator_extern),
die man beim Abschreiben des Bauplans vergisst. Wichtigste Gegenprobe:
Der CHECK muss danach noch BEISSEN. Eine Umstellung, die nebenbei die
Schranke entfernt, sieht aus wie ein Erfolg und ist der schlimmere
Ausgang.
Nebenbei drei abgeschriebene Bereichslisten beseitigt (Wochenbericht,
Suche, Report-Ziele). Im Wochenbericht waere der neue Bereich sonst
schlicht nicht vorgekommen -- ohne Fehler, ohne Luecke, einfach nicht da.
ZWEI PRUEFUNGEN, DIE DEN GESAMTLAUF ZUM STILLSTAND BRACHTEN
pruef-call-kategorien.mjs hing DREI STUNDEN. Ursache war ein Zeitzuender
in ihr selbst: Sie legte Calls auf "heute 18:00" und erwartete zwei
davon unter "Heute". Ab 18 Uhr sind die vorbei, der Server schiebt sie
nach "Protokoll fehlt", und die Oberflaeche unterteilt erst ab FUENF
anstehenden. Uebrig blieben vier, die Bloecke verschwanden, und die
Pruefung wartete auf einen Klick auf einen Block, den es nicht gab.
Genau die Sorte Fehler, vor der die Projektnotiz vom 06.09. warnt: Sie
war um 17:59 gruen und um 18:01 rot, ohne dass sich am Code etwas
geaendert hatte. Jetzt liegen alle Zeiten RELATIV zu jetzt, und die
Erwartung wird mit derselben Vorschrift gerechnet, die calls.js benutzt
-- statt Zahlen, die nur zu einer bestimmten Tageszeit stimmen.
Und der Grund, warum daraus ein Stillstand statt eines Fehlers wurde:
index.js setzt bewusst zwei Auffangnetze (uncaughtException,
unhandledRejection). Fuer den Betrieb richtig -- ein Fehler darf die
Website nicht offline nehmen. Fuer eine Pruefung fatal: Sie importiert
index.js in denselben Prozess und erbt die Netze. Ihr eigener Absturz
wird dann nur protokolliert, und der Express-Server haelt den Prozess
danach ewig am Leben. Kein Fehler, kein Ergebnis, kein Ende.
Deshalb zwei Abhilfen, die zusammengehoeren:
* server/helfer-notbremse.mjs -- haengt eigene Zuhoerer DANEBEN
(process.on ergaenzt, es ersetzt nicht) und beendet den Lauf mit
Fehler; dazu ein Wecker. In alle 42 Browserpruefungen eingebaut.
Der Betrieb bleibt unveraendert.
* tools/alles-pruefen.mjs gibt jeder Datei eine Frist von 600 s. Wer
sie reisst, wird abgebrochen und ZAEHLT ALS FEHLGESCHLAGEN, mit der
letzten Ausgabe davor als Beleg. Einzelne Dateien nachzuruesten hilft
nur bis zur naechsten ohne Notbremse -- deshalb sitzt sie dort, wo
sie fuer alle gilt, auch fuer die, die es noch nicht gibt.
AUSSERDEM: pruef-breiten.mjs pruefte 16 Seiten aus einer Liste von Hand,
chat.html und leistung.html fehlten darin. Der Chat war bei keiner
einzigen der neun Breiten je gemessen worden. Wie bei pruef-handy kommt
die Liste jetzt aus dem Verzeichnis.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
0404f8c0c1 |
Dreizehn Lecks: eine Managerin sah die Creator aller anderen
Wunsch: "jeder manager soll auch immer nur seine und die seiner scouts
zugeteilten creator und creator daten sehen. und nicht die der anderen."
DIE KETTE WAR GEBAUT -- SIE WURDE NUR NICHT BENUTZT
Manager -> seine Scouts -> deren Creator steht seit dem 01.09.2026 an
genau einer Stelle (betreuteIds). Die Frage war eine andere: Benutzt sie
auch JEDER Weg, der Creator-Daten herausgibt? Ueber zwanzig Stellen
prueften die ROLLE statt der ZUTEILUNG -- "ist Leitung? dann alles".
NICHT GELESEN, SONDERN GEMESSEN
server/pruef-manager-sicht.mjs baut zwei Managerinnen mit vollstaendig
getrennten Creators. Bei der fremden heisst ALLES "GEHEIM..." -- Aufgabe,
Termin, Bereichseintrag, Datei, Steckbrief, Content-Saeule. Danach wird
jede der 31 Leseschnittstellen abgefragt und die ganze Antwort danach
durchsucht. Ein Leck faellt damit auf, egal wo es sitzt und egal, ob ich
es beim Lesen uebersehen haette.
GEFUNDEN: DREIZEHN. Alle geschlossen:
Kalender fremde Fristen -- besonders unangenehm, weil es
nicht wie ein Leck aussieht: eine kleine orange
Marke mit einem Titel, in dem fremde Vorhaben stehen
Personenauswahl alle Namen im Zuweisungsfeld
Dateien alle Namen in der Freigabe-Auswahl
Uebersicht Gesamtuebersicht ueber ALLE Creator
Report Auswahl UND Auswertung ueber den ganzen Bestand
Start-Check alle Creator zur Auswahl
Steckbriefe Bild, Kanaele, "ueber mich" von allen
Profile alle Profile, samt interner Notiz
Schulung Schulungsstand aller Creator
Suche Creator-Profile aller -- die unauffaelligste Stelle:
Man sucht etwas anderes und bekommt fremde Namen
Content-Balance Themensaeulen fremder Kanaele (die Abfrage daneben
war korrekt eingeschraenkt, DIESE hatte eine eigene
Bedingung)
darfCreator eine einzige Zeile -- sie hing an Profil,
Start-Check und Uebersicht gleichzeitig. Es reichte,
eine Nummer in die Adresse zu schreiben.
Die Antwort steht jetzt an EINER Stelle: sichtbareCreatorIds und
sichtbarePersonenIds in workspace.js. Rueckgabe null heisst "alle" und
gilt allein DogFather -- bewusst kein leeres Feld: Eine leere Liste
bedeutet "niemand", und die Verwechslung der beiden macht aus einer
Sperre eine Freigabe.
ZWEI DINGE, DIE ICH MIR SELBST NACHTRAGEN MUSS
1. Beim Stopfen fehlte einmal ein Import. Der Weg warf einen Fehler,
antwortete 503 -- und weil in einer Fehlermeldung kein "GEHEIM" steht,
meldete die Pruefung "kein Leck". Sie war gruen, weil der Weg KAPUTT
war. Die Pruefung zaehlt jetzt beides: nichts durchsickern UND
antworten.
2. Ein Fehlalarm: Die Suche gibt den SUCHBEGRIFF in ihrer Antwort
zurueck. Wer nach "GEHEIM" sucht, findet das Wort zwangslaeufig --
auch bei null Treffern. Ich haette um ein Haar ein Leck "repariert",
das es nie gab. Das Echo wird jetzt entfernt, bevor gemessen wird.
FOLGEN, bewusst in Kauf genommen:
* Ein Manager ohne Zuteilung sieht keinen Creator. Die Uebersicht sagt
ihm das jetzt in einem Satz, statt leer zu bleiben.
* Er kann nur noch IN SEINEN Creator-Bereichen schreiben (darfCreator).
ZWEI PRUEFUNGEN UMGEDREHT statt geloescht -- eine geloeschte Pruefung
hinterlaesst keine Spur davon, dass hier einmal etwas anderes galt:
pruef-uebersicht ("Manager sieht dasselbe" -> "nur seine zugeteilten",
mit beiden Faellen) und pruef-scout-zuteilung ("sieht die ganze
Personenliste" -> "landet auf der Startseite").
GEPRUEFT: 43 neue Pruefungen, dazu 23 bestehende Laeufe gruen --
Startansicht 133, Rollen 97, Kalender 84, Serien 67, Steckbrief 65,
Handy 50, Sicht 48, Ampel 47, Content 45, Aufgabenbrett 44, Schulung 41,
Bereiche 37, Scout-Zuteilung 36, Uebersicht 35, Personenliste 33,
Freie Namen 32, Team 30, Protokoll-Loeschen 20, Personenformular 20,
Formulare 19, Betreuung 18, Code 17, Grosscheck 15.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
9e523d3ea2 |
Manager sehen nur noch ihre zugeteilten Scouts -- und deren Creator
Wunsch vom 01.09.2026: "er soll nur die Scouts sehen, die ihm zugeteilt sind." Dazu entschieden: Ein Manager sieht dann AUCH die Creator dieser Scouts, und zuteilen darf NUR DogFather. WAS VORHER WAR. Ein Manager sah die gesamte Scout-Pipeline -- alle Leads aller Scouts, dazu dieselben in der Suche und in "Was ist dran". Das war die letzte Stelle, an der "nur DogFather sieht alles" noch nicht galt. EINE EIGENE TABELLE, KEIN ZWEITER EINTRAG IN `betreuung`. Dort heisst die Spalte creator_id, und der ganze uebrige Code liest sie als "das ist ein Creator". Ein Scout darin waere technisch moeglich und fachlich eine Luege gewesen: betreuteIds() gaebe Scout-Nummern zurueck, die anderswo als Creator behandelt wuerden. Solche Abkuerzungen raechen sich genau dann, wenn niemand mehr weiss, dass sie getroffen wurden. DIE KETTE steht an EINER Stelle (betreuteIds in workspace.js): Manager -> seine Scouts -> deren Creator. Ohne sie muesste jeder Creator einem Manager einzeln zugewiesen werden, und beim ersten vergessenen faende er ein Loch in seiner Uebersicht, ohne zu merken, dass es eines ist. Dieselbe Regel gilt fuer Leads in Pipeline, Suche und Hinweisen -- aus einer Quelle (pipelineIds), nicht dreimal abgeschrieben. ZUTEILEN DARF NUR DOGFATHER, und das ist keine Foermlichkeit: Diese Zuteilung ERWEITERT die Sicht eines Managers. Duerfte er sie selbst setzen, koennte er sich seine eigene Sichtbarkeit vergeben -- eine Grenze, die der Begrenzte selbst verschieben kann, ist keine. Deshalb istDogFather und ausdruecklich NICHT istLeitung. In der Personenliste steht bei jedem Scout "Gehoert zu", sichtbar nur fuer DogFather. Der Leerwert heisst "— direkt bei DogFather —" und nicht "— niemand —": Ein Scout ohne Manager ist nicht unbetreut, er haengt an DogFather. Das ist ein Zustand, kein Mangel. NEBENBEI KORRIGIERT: In der Zustaendigkeits-Route stand als Kommentar noch "ein Eintrag auf DogFather oder Manager aendert an den Rechten nichts, die Leitung sieht ohnehin jeden Creator". Das gilt seit heute nicht mehr -- fuer einen Manager entscheidet dieser Eintrag jetzt sehr wohl ueber die Sichtbarkeit. Ein falscher Kommentar ist schlimmer als keiner: Er wird geglaubt. DIE PRUEFUNG STELLT DEN MISSBRAUCH AN DEN ANFANG. Diese Aenderung erweitert Sichtbarkeit -- alles andere heute hat sie eingeschraenkt. Ein Fehler dort zeigt jemandem zu wenig und faellt auf; ein Fehler hier zeigt zu viel und faellt niemandem auf. Geprueft wird deshalb: Manager und Scout duerfen nicht zuteilen (404, und es wird auch wirklich nichts geschrieben), Scout an Scout und Scout an DogFather werden abgewiesen, ein Creator laesst sich nicht zuteilen. Danach die Kette in beide Richtungen, das Zuruecknehmen, und dass ein Scout zu genau einem Manager gehoert. Ein lehrreicher Fehlschlag in der Pruefung selbst: Sie meldete, die Auswahl fehle in der Oberflaeche. Sie fehlte nicht -- die Personenliste ist nach Rollen ZUGEKLAPPT, und die Pruefung hatte nicht aufgeklappt. Sah aus wie ein Produktfehler, war einer der Pruefung. Sie klappt jetzt auf und stellt vorher fest, dass wirklich alle sieben Zeilen dastehen. Gesamtlauf: 30 von 30 Dateien, 1210 von 1210 Einzelpunkten. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
1c00770ec5 |
Lesbarere Kaesten, und DogFather kann durch fremde Augen sehen
SCREEN 1 -- "die Kachel ganz leicht dunkler, so dass man den Text besser gelesen bekommt, aber nicht zu viel, so dass man den Hasen noch sieht." Die Erklaerkaesten stehen jetzt auf 88 statt 78 Prozent Deckung. Zehn Punkte sind gemessen der Unterschied zwischen muehsam und ruhig lesbar und lassen zwoelf Prozent Bild durch -- das Motiv bleibt sichtbar. "und die von wichtigen und neuen PDFs sollen auch staerker sein." Das war kein Geschmack, sondern ein Fehler: `background` ist eine Eigenschaft, keine Schicht. Die Zeile `background: rgba(232,192,125,.045)` hat die Flaeche nicht getoent, sondern ERSETZT -- uebrig blieben viereinhalb Prozent Deckung. Damit war ausgerechnet die Anleitung, die jeder lesen soll, die am schwersten lesbare der Seite. Die Toenung liegt jetzt als Schicht darueber. Gemessen: 88 % gegen 78 % bei einer gewoehnlichen. pruef-lesbarkeit.mjs misst das an ECHTEN PIXELN (Text kurz unsichtbar machen, Flaeche fotografieren, WCAG-Formel) und kennt ZWEI Grenzen -- lesbar genug UND durchsichtig genug. Mit nur einer haette sie eine schwarze Flaeche am besten gefunden, und das wollte niemand. SCREEN 2 -- "ich will alles von den Scouts und Managern einsehen koennen, auswaehlen, was und von wem. Ueberall, auf jeder Seite. NUR WIR BEIDE SOLLEN DIESE OPTION HABEN." Die naheliegende Loesung waere ein Filter je Seite gewesen -- also eine zweite Rechteregel in zwoelf Modulen, und eine Rechteregel an zwoelf Stellen stimmt irgendwann an elf. Stattdessen wird die PERSON getauscht, nicht die Regel: Waehlt DogFather einen Scout, laufen alle vorhandenen Sichtbarkeitsregeln unveraendert mit diesem Scout. Er sieht exakt dessen Arbeitsplatz -- nicht mehr, nicht weniger. Keine neue Rechteregel. Im Browser genauso: EIN Ort statt vierzehn. fetch wird einmal umgeleitet und haengt den Wert an jede lesende Abfrage an. Neue Seiten sind damit von selbst dabei; man kann es nicht vergessen. Drei Sicherungen: nur admin (auf dem SERVER geprueft, nicht in der Oberflaeche), nur lesend (geschrieben wird immer im eigenen Namen -- sonst staende im Protokoll der falsche Name), nur aktive Personen. Und ein Rahmen um die Seite, solange eine fremde Sicht laeuft. Der gefaehrlichste Fall ist nicht, dass man nicht umschalten kann, sondern dass man vergisst, dass man umgeschaltet hat -- und drei Aufgaben statt dreissig fuer den Bestand haelt. FUENF FEHLER, DIE DIE PRUEFUNGEN GEFUNDEN HABEN: 1. steckbrief.html hat die Kopfleiste NIE gefuellt -- dort stand monatelang "…" statt des eigenen Namens. Aufgefallen, weil der Umschalter dort fehlte. Jetzt zusaetzlich ein Netz darunter: Meldet sich nach kurzer Zeit niemand, holt der Kopf sich selbst, wer angemeldet ist. Die naechste neue Seite kann es nicht mehr vergessen. 2. Der Umschalter sprengte die Kopfleiste (46 px am Rechner, 117 px am Handy) und drueckte den Abmelden-Knopf hinaus. 3. Ich habe das <select> gestaltet -- wahl.js ersetzt aber jedes Auswahlfeld durch einen eigenen Knopf und schrumpft das echte Feld auf einen Pixel. Meine Regeln haben es wieder auf 20 x 44 aufgeblasen, wo es als unsichtbares Hindernis ueber dem Knopf lag. Gestaltet wird jetzt der Knopf. 4. Ein Wettlauf: Auf profil.html rufen zwei Dateien werZeigen() auf. Beide kamen an "gibt es den Umschalter schon?" vorbei, bevor eine ihn angehaengt hatte -- zwei Umschalter uebereinander. Die Sperre gehoert vor das erste await. 5. Die Handy-Pruefung bemaengelte ein Schild, das dort per display:none gar nicht erscheint. Sie sieht jetzt nur noch sichtbaren Text an -- eine Pruefung, die Unsichtbares anmahnt, gewoehnt man sich ab zu lesen. Dazu zwei Messfehler in den Pruefungen selbst: getComputedStyle liefert ein LEBENDES Objekt (die Farbe wurde gelesen, nachdem der Text unsichtbar gemacht war -- gemeldet wurden 1,17:1 fuer tadellos lesbaren Text), und ein Vergleich lief still ins Leere, weil die Vergleichsdaten fehlten. pruef-sicht.mjs stellt den MISSBRAUCH an den Anfang: Scout, Manager und Creator haengen ?sicht= an und muessen ignoriert werden; erfundene Nummern, Buchstaben und ein Einschleusversuch fallen auf die eigene Sicht zurueck; eine abgeschaltete Person liefert keine Sicht mehr; und was DogFather bei fremder Sicht anlegt, steht unter SEINEM Namen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
389d8c1213 |
Workspace: neue Rolle Manager, feste Rollenreihenfolge, echte Rollenwahl
DREI TEILE. 1) ROLLE "MANAGER" Ein Manager darf alles, was DogFather darf -- mit genau zwei Vorbehalten: Er kann keine Leitung ANLEGEN und an keiner Leitung etwas AENDERN. Sonst koennte er sich einen zweiten Vollzugang schaffen oder DogFather aussperren. "Nur DogFather hat alle endgueltigen Rechte" heisst genau das. Umgesetzt ueber istLeitung() an EINER Stelle statt 44 einzelner Vergleiche auf "admin" im Server und 26 im Browser. DATENBANK-UMSTELLUNG: CREATE TABLE IF NOT EXISTS fasst eine vorhandene Tabelle nicht an -- die CHECK-Regel stand also weiter auf den alten drei Rollen, und ein Manager waere daran gescheitert, obwohl der Code stimmt. SQLite kann eine CHECK-Regel nicht aendern, also: neue Tabelle, Daten hinueber, alte weg, umbenennen. Davor schreibt der Server eine vollstaendige Sicherung (VACUUM INTO, in sich konsistent). Ohne Sicherung wird NICHT umgestellt. Geprueft nach der Umstellung: alle 13 Tabellen mit gleicher Zeilenzahl, PRAGMA integrity_check ok, keine verwaisten Verweise. Die einzige Abweichung war eine Sitzung mehr -- die eigene Anmeldung, die die Umstellung ausgeloest hat. 2) EIN SICHERHEITSLOCH, DAS DER TEST GEFUNDEN HAT Der erste Entwurf sicherte "Person anlegen" und "Person sperren" ab -- und liess "neuer Zugangscode" offen. Ein Manager konnte DogFather einen neuen Code ausstellen, bekam ihn angezeigt und haette ihn damit aus seinem eigenen Konto ausgesperrt. Im Test aufgefallen, weil ich den negativen Fall durchgespielt habe. Behoben nicht durch eine dritte Einzelpruefung, sondern durch eine Schranke an JEDEM Weg mit einer :id. Der naechste Weg, der dazukommt, ist damit automatisch mitgeschuetzt. Nachgeprueft: Manager bekommt 403 beim Code-Erneuern und Sperren von DogFather UND von sich selbst, darf aber Creator und Scouts verwalten. 3) FOLGEFEHLER DER MASSENERSETZUNG Die Regel "niemals den letzten aktiven DogFather sperren" hatte durch die Umstellung auf istLeitung() ploetzlich auch Manager blockiert -- gezaehlt werden aber nur DogFather-Zugaenge. Jetzt istDogFather(). Geprueft: DogFather kann einen Manager sperren, sich selbst nicht. 4) REIHENFOLGE UND ROLLENWAHL Ueberall DogFather, Manager, Scout, Creator. "ORDER BY rolle" waere alphabetisch gewesen (admin, creator, manager, scout) -- also fast genau falsch herum. Jetzt ein gemeinsamer Sortierausdruck aus workspace.js. Das Auswahlmenue fuer die Rolle ist weg. Es kam als weisses Windows-Menue mitten in einer dunklen Oberflaeche und schnitt "Creator" zu "Crea" ab -- gestalten laesst sich ein aufgeklapptes Systemmenue nicht. Ersetzt durch vier sichtbare Schalter mit Symbol, Farbe je Rolle und einer Zeile, was die Rolle bedeutet. Bei "Manager" gegen "DogFather" ist das der Unterschied zwischen Raten und Wissen. DogFather und Manager stehen dort nur zur Wahl, wenn DogFather selbst davorsitzt -- ein Knopf, der immer scheitert, gehoert nicht hin. Nebenbei: Das Namensfeld war auf eine von zwoelf Spalten gequetscht, weil seine Umgebung keine .feld-Klasse trug. Alle Formulare daraufhin durchsucht, keine weiteren Faelle. |
||
|
|
3a1ab64c26 |
Workspace: Suche ueber alle Bereiche (Phase 4)
Auf JEDER Seite, nicht auf einer eigenen. kopf.js baut sie selbst in die Kopfleiste ein -- eine Suche, die man nur auf einer Extraseite findet, benutzt niemand. Mit "/" oeffnen, mit Esc schliessen. Durchsucht: Aufgaben, Termine, Calls, Gespraechsprotokolle, Dateien, die fuenf Betreuungsbereiche, die Scout-Pipeline und die offenen Felder der Creator-Profile. Zwei Dinge machen den Unterschied zwischen einer Suche und einer brauchbaren Suche: 1. SIE DARF NICHTS FINDEN, WAS DIE SEITE VERBERGEN WUERDE. Eine Suche ist die verlockendste Stelle fuer ein Datenleck: Man tippt einen Namen und bekommt Treffer aus Bereichen, die man nie oeffnen duerfte. Jede Quelle wird deshalb mit der Sichtbarkeitsregel ihres eigenen Moduls abgefragt -- importiert, nicht abgeschrieben. Die management-internen Profilfelder (admin_notiz, plan_start, naechster_review) werden GAR NICHT durchsucht, auch nicht fuer das Management: Ein Treffer daraus taucht sonst spaeter in einer Ansicht auf, die diese Felder nicht zeigen darf. Wer die Notiz lesen will, oeffnet das Profil. Geprueft mit einem eigenen Leck-Test: "GEHEIM" (Inhalt einer internen Notiz) findet niemand, auch der Chef nicht. Die Lead-Notiz eines Scouts findet nur er selbst und das Management, nicht der andere Scout. 2. SIE MUSS SAGEN, WO ETWAS STEHT. Jeder Treffer traegt einen Ausschnitt RUND UM die Fundstelle, nicht die ersten Zeichen des Feldes -- man sieht sofort, warum etwas gefunden wurde. Bei Profiltreffern steht dabei, welches Feld getroffen hat, bei Protokollen ob es unter "Besprochen" oder "Entscheidung" stand. Und jeder Treffer fuehrt an die Stelle, an der man weiterarbeiten kann. LIKE-Sonderzeichen werden maskiert. Ohne das waere die Suche nach "100%" eine Suche nach "100 gefolgt von irgendwas" und "a_b" faende auch "axb" -- beides falsch und beides faellt erst spaet auf. Geprueft: "100%" und "a_b" finden genau ihren Eintrag, "axb" findet nichts. Bewusst kein Volltextindex (FTS5): Die Datenmengen sind klein, und LIKE braucht keinen zweiten Datenstand, der irgendwann auseinanderlaeuft. Kleinigkeiten aus dem Test: - Das Overlay stand auf voller Hoehe, auch bei zwei Treffern -- der Schleier ist flex und stand auf dem voreingestellten stretch. Jetzt flex-start, das Fenster waechst mit dem Inhalt (417 statt 780 px bei drei Treffern). - Das eingebaute Kreuz von type="search" sass direkt neben dem Esc-Knopf: zwei Wege fuer dasselbe, dicht nebeneinander. Entfernt. - Das CSS liegt in gate.css, nicht in einer Seiten-Datei -- genau der Fehler, der bei .knopf-still schon einmal passiert ist. |