Commit Graph
18 Commits
Author SHA1 Message Date
DogFatherGitandClaude Opus 5 7be488e0ca Ein Zugang, den ausser DogFather niemand bemerkt
Aus dem Anforderungsdokument (Master-Blueprint V3.0) fehlte die Rolle
"Modi" ganz -- es gab nur spicy, admin, manager, scout, creator. Filipes
Bedingung dazu: "dass die keine neue eingangs kachel bekommen wie spicy
dogfather und so sondern einfach einen code. damit die von der workspace
auch nicht mal sehen dass die modis von mir einen eigenen zugang haben."

DER EINGANG. Es gibt keine sechste Kachel und es laesst sich auch keine
erzwingen: Wer von aussen `rolle: "modi"` schickt, bekommt wortgleich
dieselbe Antwort wie bei einer erfundenen Rolle. Ein Modi tippt auf
irgendeine vorhandene Kachel -- welche, ist gleichgueltig -- und gibt
seinen Code ein. Der Code allein entscheidet.

Moeglich macht das eine neue Spalte `code_kennung`: ein HMAC ueber den
Code, in Mikrosekunden nachgeschlagen. Zwei naheliegende Wege wurden
verworfen, weil man sie finden kann: ein Merkmal im Code ("M-...") waere
ein sichtbares Kennzeichen auf dem Zettel des Modis, eine eigene Adresse
(/modi.html) eine Seite, die man aufrufen kann. Der Suchschluessel steht
VOR dem gewohnten Weg, nicht dahinter -- ein Rueckfall nach einem
Fehlversuch haette genau die Fehlversuche verlaengert, und daran waere
es zu erkennen gewesen.

Unbedenklich, weil nachgemessen: Ein Code hat 16 Zeichen aus einem
32er-Alphabet, also 80 Bit Zufall. Der Suchschluessel sagt ausserdem nur,
WEN man pruefen soll -- ob der Code stimmt, sagt weiterhin scrypt.

DIE UNSICHTBARKEIT sitzt in verborgeneIds(), also an derselben einen
Stelle wie die Regel fuer den zweiten Admin-Zugang, und nicht in den
rund 170 Abfragen, die Personen lesen. Sie haengt dabei an der ROLLE und
nicht an einer Nummer -- die Schwachstelle, die im Kommentar der alten
Regel offen dasteht (wird Zugang 1 geloescht, rueckt der naechste nach),
kann einer Rolle nicht passieren.

Nach Filipes Entscheidungen: Die Modis sehen sich untereinander (Kapitel
7.2 des Dokuments), VanVan sieht sie mit (Kapitel 3, sie traegt dieselbe
Rolle), Codes gibt Filipe selbst weiter -- kein Einladelink, der in einem
Verlauf landen kann.

ZWEIMAL WAERE DAS WORT "MODI" BEINAHE IN EINER DATEI GELANDET, DIE JEDER
BEKOMMT: in den Rollenlisten von start.js und personen.js. Ein Blick in
den Quelltext haette genuegt. Der Anzeigename kommt jetzt aus
/workspace/api/ich (beschreibt immer nur den Angemeldeten selbst), die
Rollenauswahl aus der Antwort des Servers und nur an die DogFather-Rolle.

GEPRUEFT mit pruef-modi-verborgen.mjs (45 Pruefungen): fuenf Kacheln
fuehren mit dem Modi-Code hinein, ein Manager-Code auf fremder Kachel
weiterhin nicht (sonst waere nebenbei die Rollenpruefung abgeschafft),
und ueber fuenf Schnittstellen sieht ausser DogFather, VanVan und den
Modis niemand etwas -- auch nicht die ZAHL daneben.

Die Gegenprobe steht bewusst ganz unten, weil sie eine Person absichtlich
aus der Regel aushaengt: Weiter oben haette sie jeden Abschnitt danach
verfaelscht. Beim ersten Anlauf stand sie in der Mitte, und prompt tauchte
die Person in einer spaeteren Managerliste auf.

Abschnitt 5 prueft den Weg durch die Anwendung selbst (DogFather legt an,
der Modi meldet sich an). Die Abschnitte davor tragen die Personen von
Hand ein und rechnen den Suchschluessel selbst aus -- damit waere NICHT
bewiesen, dass personAnlegen() ihn im Betrieb schreibt. Ohne ihn kaeme
kein einziger echter Modi herein, und oben waere trotzdem alles gruen.

Die Umstellung der Rollenliste in der Datenbank steht ab jetzt einmal in
rollenRegelUmstellen() statt zum dritten Mal abgeschrieben. Jede Abschrift
waere eine Gelegenheit, eine der vier Absicherungen zu vergessen: Sicherung
vorher, Zaehlung innerhalb der Transaktion, Spaltenliste aus der Tabelle,
Pruefung auf verwaiste Verweise danach.

pruef-personen-formular erwartet jetzt sechs Rollen statt fuenf und prueft
die Liste statt nur die Anzahl -- sechs Karten koennten auch fuenf richtige
und eine doppelte sein. Dass die sechste dort auftaucht, ist gleichzeitig
der Nachweis, dass der Weg ueber den Server funktioniert.

Unveraendert bestanden: pruef-spicy (60), pruef-rollen (97),
pruef-verborgen, pruef-personen-liste, pruef-css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-10 00:11:39 +02:00
DogFatherGitandClaude Opus 5 6676998af8 Niemand sieht VanVan ausser DogFather -- plus vier Punkte vom Screen
--- DAS WICHTIGSTE ZUERST: die Verbergungsregel ---

Filipe, ausdruecklich und dringlich: "und noch gaaaaaanz wichtig keiner
soll vanvan sehen ausser ich, ueberall soll keiner vanvan sehen ausser
dogfather."

ES GAB DAVON NUR EINE HAELFTE. In der Personenliste wurde der zweite
Admin-Zugang fuer Spicy Media ausgeblendet (Wunsch vom 31.08.).
Ueberall sonst -- Chat, Kalender, Aufgaben, Dateien, Zentrale -- war er
sichtbar. `sichtbarePersonenIds` hat ihn sogar ausdruecklich JEDER
Rolle gezeigt, weil sie alle Admins einsammelt.

WORAN DIE BEIDEN AUSEINANDERGEHALTEN WERDEN: In der Datenbank tragen
beide die Rolle `admin`, es gibt kein unterscheidendes Feld. Der
Unterschied, den es wirklich gibt, ist das Alter -- DogFather ist der
erste Zugang. Also: der Admin mit der kleinsten Nummer ist DogFather,
alle weiteren sind verborgen. Drei Ausnahmen: DogFather sieht alle,
ein verborgener Zugang sieht sich selbst, und bei nur einem Admin gibt
es nichts zu verbergen.

WARUM AN EINER STELLE UND NICHT IN DEN ABFRAGEN: Allein
workspace-personen.js hat 23 Abfragen auf `personen`. Eine Regel, die
man 23-mal wiederholt, ist 23 Gelegenheiten, sie zu vergessen -- und
beim Vergessen faellt niemand auf die Nase, sondern jemand SIEHT etwas.
Die Regel sitzt deshalb in `verborgeneIds()` und wird ueber einen
MANTEL um die sechs Listenfunktionen gelegt: Diese haben zusammen
achtzehn Rueckgabewege; sie einzeln zu flicken waeren achtzehn
Gelegenheiten, einen zu uebersehen. Die ungefilterten Fassungen
(`...Roh`) werden nicht mehr exportiert -- niemand kann sie
versehentlich benutzen.

`null` HIESS BISHER "SIEHT ALLES". Sobald es etwas zu verbergen gibt,
gilt das nicht mehr: Die Liste wird ausgeschrieben. Das ist strenger,
nicht lockerer.

NEUE PRUEFUNG server/pruef-verborgen.mjs -- sechs Personen (darunter
ein zweiter Admin), fuenf Schnittstellen, jede Rolle einzeln. Sie hat
beim ersten Lauf sofort ein Loch gefunden, das ich sonst nicht bemerkt
haette: Die ZENTRALE holt sich das Haus selbst und ging an allen
Listenfunktionen vorbei -- Spicy Media sah VanVan dort als Segment im
Team-Ring. Und beim Korrigieren der Pruefpfade fiel ein zweites auf:
`darfEintragen` im Kalender liess die Leitung JEDEN eintragen, bevor
ueberhaupt eine Liste befragt wurde. Eine Sichtbarkeitsregel, die nur
beim Lesen gilt und nicht beim Schreiben, hat ein Loch in der Mitte.

Die Pruefung hat eine Gegenprobe: Ein Manager MUSS DogFather in
derselben Liste sehen -- sonst waere "sieht VanVan nicht" auch dann
gruen, wenn die Listen leer zurueckkaemen.

--- screen1 Punkt 1: Silber mit Babyblau ---

"ich will dass diese farbe gemischt wird mit babyblau."

#c7dcf4 statt #d8e0ec -- dieselbe Helligkeit, mit Blaurichtung.
Nachgerechnet bleibt der Abstand zur naechsten Rolle bei 0,1790, immer
noch weiter als das frueher benutzte Babyblau (0,1349). Gemischt ist es
ausserdem SICHTBAR: Die Schiene laeuft von Silber nach Babyblau, und
der Glanz traegt beide Toene. Eine Mischung, die man nur im Hexwert
findet, ist keine.

--- screen1 Punkt 2: das Wasserzeichen ---

"soll viel groesser sein und nicht so abgecuttet sondern gut zu sehen
sein."

NACHGEMESSEN war es auf der Dashboard-Kachel zu 50 Prozent
abgeschnitten, und zwar auf DREI Seiten: 36 px ueber dem oberen Rand,
44 rechts, 60 unten -- 220 px Zeichen auf einer 152 px hohen Kachel.

UND ES GAB ZUM DRITTEN MAL DIESE WOCHE EINE DOPPELREGEL: 3600 Zeilen
unter der sorgfaeltig begruendeten Fassung (156 px bei 0,14) stand eine
zweite (118 px bei 0,085) mit derselben Spezifitaet. Sie gewann, und
die Begruendung oben war wirkungslos. Am 08.09. hatte ich beim
Wasserzeichen schon einmal genau so eine Doppelung gefunden -- und
diese hier uebersehen.

Jetzt eine Fassung, und die Groesse haengt an der KACHELHOEHE: Ein um
8 Grad gedrehtes Quadrat der Seite S braucht S x 1,129 Platz, also
`min(132px, 100% - 30px)`. Nachgemessen 100 Prozent sichtbar statt 50,
bei 0,14 statt 0,085 -- die sichtbare Flaeche hat sich verdoppelt.

--- screen1 Punkt 3: die Personenliste in einer Kachel ---

Die fuenf Rollengruppen standen als fuenf lose Abschnitte frei auf dem
Hintergrundbild. Es ist aber EINE Liste mit fuenf Abschnitten. Jetzt
eine Sammelkachel aus der Modulliste, mit dunklen Fugen statt Luft --
und dunkler als die Karten darin, wie eine Vitrine.

--- screen1 Punkt 4: "Womit meldest du dich an?" ---

Der einzige Satz auf der Anmeldeseite, der eine FRAGE stellt, stand als
graue Feldbeschriftung da. Jetzt gebuerstetes Metall, ein Anschlag aus
drei Kerben in Rot und Babyblau und eine auslaufende Linie -- dieselbe
Sprache wie die Typenschilder im Workspace. Rueckfall vollwertig: Faellt
`background-clip: text` aus, steht dort heller Text.

Geprueft: pruef-verborgen (neu), pruef-rollen, pruef-start-ansicht,
pruef-css-klassen, pruef-workspace-seiten, pruef-buehne, pruef-handy,
pruef-chat, pruef-kalender -- alle in Ordnung.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-09 03:18:01 +02:00
DogFatherGitandClaude Opus 5 29785cc2a4 Abgebrochene Aufgaben mahnen nicht mehr -- an zwoelf Stellen, nicht an einer
Filipe, screen12: "die abgebrochenen sollen oben nicht mehr mit zaehlen
die sollen ihre eigenen kategorie kriegen".

DIE URSACHE war eine Bedingung, die harmlos aussieht: `a.status <>
'erledigt'`. Eine abgebrochene Aufgabe ist nicht "erledigt" -- also fiel
sie durch, und zwar in JEDE Zahl, die "noch zu tun" bedeutet. Eine
Aufgabe, die niemand mehr anfassen wird, mahnte weiter als ueberfaellig.

Das ist die Kehrseite einer bewussten Entscheidung: "abgebrochen" steht
absichtlich NICHT in STATUS, damit der normale Weg es nicht setzen kann.
Genau deshalb rutscht es aber durch jede Pruefung, die nur gegen
'erledigt' vergleicht.

FILIPE HAT EINE STELLE GESEHEN. Gesucht werden musste nach dem MUSTER:
Es waren zwoelf, in sieben Dateien.

  workspace-aufgaben.js   2   ueberfaellig und heute (die Zahlen "oben")
  workspace-hinweise.js   2   die Hinweiszeilen der Startseite
  workspace-kalender.js   1   Aufgaben mit Frist im Kalender
  workspace-personen.js   1   "offene_aufgaben" je Person
  workspace-profil.js     1   dieselbe Zahl im Profil
  workspace-push.js       2   ERINNERUNGEN, die verschickt werden
  workspace-reports.js    3   Berichte

Am schwersten wiegt workspace-push.js: Dort gingen Push-Nachrichten
hinaus -- fuer Aufgaben, die laengst abgebrochen waren.

`NOT IN ('erledigt', 'abgebrochen')` statt einer zweiten Ungleichung: Wer
spaeter einen dritten Endzustand einfuehrt, ergaenzt eine Liste, statt
eine Kette von `<>` zu verlaengern, bei der das Vergessen niemandem
auffaellt.

DIE EIGENE KATEGORIE, die Filipe verlangt hat, gibt es jetzt in der
Schnittstelle (`abgebrochen`) und auf der Startseite -- hinten bei
"Erledigt", weil beides dasselbe bedeutet: vom Tisch.

GEGENPROBE an einer abgebrochenen Aufgabe mit Frist von gestern:
  alte Bedingung  "<> erledigt"            -> ueberfaellig = 3
  neue Bedingung  "NOT IN (erledigt, abg)" -> ueberfaellig = 2
  Unterschied 1 = genau die abgebrochene. Die Schnittstelle liefert 2
  und abgebrochen = 1.

pruef-start-ansicht hat den Umbau bemerkt und "die Aufgabenzahlen stehen
(7)" gemeldet -- sie zaehlt die Kategorien und erwartete sechs. Die Zahl
steht in der Bedingung, nicht nur im Meldetext; deshalb faellt eine
Kategorie, die still verschwindet, sofort auf. Auf 7 nachgezogen:
EXIT=0, 140 Pruefungen. pruef-aufgabenbrett EXIT=0, 44.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-08 11:27:08 +02:00
DogFatherGitandClaude Opus 5 28a260fab2 Ein Husky statt der Krone -- und Spicy sieht DogFather, aber nur ihn
DER HUSKY (screen 1)

Filipe: "die krone bei dogfather durch einen husky ersetzen, wie mein
logo." Bei 24 Pixeln entscheidet die SILHOUETTE, nicht das Detail. Ein
Husky erkennt man an dreierlei, und mehr passt auch nicht hinein: den
spitzen aufrechten Ohren, dem breiten Kopf, der nach unten schmal
zulaeuft, und der Gesichtsmaske. Fell oder Zunge waeren bei dieser
Groesse Matsch -- genau deshalb hat die Krone davor funktioniert.

UND ALLE ROLLENSYMBOLE SIND JETZT KOERPER

Sie waren reine Konturen in einer Farbe -- daneben auf derselben Seite
die Kachelzeichen mit drei Lichtern. Jetzt tragen sie eine gefuellte
Flaeche in ihrer Rollenfarbe, die Zeichnung hell darauf, und Augen und
Nase eigens gesetzt. Beim gewaehlten Knopf leuchtet die Flaeche
staerker -- der einzige Unterschied, den es braucht: mehr Licht auf
demselben Gegenstand.

SPICY SIEHT DOGFATHER, ABER NICHT DEN ZWEITEN ADMIN (screen 2)

Filipe: "die rolle spicy soll auch die rolle dogfather sehen, aber nur
dogfather und nicht vanvan."

NACHGEMESSEN AM ECHTEN SYSTEM, nicht angenommen: In der Datenbank
tragen BEIDE die Rolle `admin` -- id 1 "Dogfather", id 4 "VanVan". Es
gibt kein Feld, das den einen vom anderen unterscheidet.

Der Unterschied, den es wirklich gibt, ist das Alter: DogFather ist der
erste Zugang des Hauses. Deshalb zaehlt die kleinste Nummer unter den
Admins -- eine Eigenschaft, die feststeht und nicht am Namen haengt.
Die Schwachstelle steht im Code, damit sie niemand sucht: Wuerde Zugang
1 je geloescht, rueckte der naechste nach; dann gehoert ein
ausdrueckliches Merkmal in die Tabelle.

Die Entscheidung faellt im SERVER, nicht in der Oberflaeche. Dort stand
vorher ein Filter, der den ganzen Abschnitt wegnahm -- zwei Regeln fuer
dieselbe Frage laufen auseinander, und eine ausgeblendete Zeile hat
noch nie etwas geschuetzt.

MEINE EIGENEN PRUEFUNGEN VON HEUTE MITTAG FIELEN DABEI

Richtig so: Sie pruefen "DogFather steht NICHT darin", und das gilt
nicht mehr. Umgeschrieben -- und dabei kam der eigentliche Prueffall
dazu: ein ZWEITER Admin-Zugang im Testbestand. Ohne ihn waere die Regel
gar nicht pruefbar, bei einem einzigen Admin ist jede Antwort richtig.
pruef-spicy von 57 auf 60.

NOCH OFFEN aus derselben Nachricht: die Terminarten (BigMatch,
Turniere, Special-Live) und der Umbau der Begruessungskachel nach dem
Vorbild von VanVans Werktisch.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-07 18:14:54 +02:00
DogFatherGitandClaude Opus 5 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]>
2026-09-07 16:45:50 +02:00
DogFatherGitandClaude Opus 5 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]>
2026-09-07 04:56:07 +02:00
DogFatherGitandClaude Opus 5 49bd4a7cec Manager legen Creator an -- eine neue Tuer statt eines Schluessels fuer die alte
Filipe: "wieso greift das in die rechte rein? ist doch ok, die sollen
einfach paar leute selber hinzufuegen koennen." Er hat recht, und ich
hatte zwei Dinge in einen Topf geworfen: Das hier braucht KEINE
Datenbankaenderung -- nur die Rolle "Spicy Media" braucht eine.

WARUM EIN EIGENER WEG UND NICHT DIE ALTE TUER

Alles unter /workspace/api/verwaltung haengt an EINER Schranke
(nurAdmin). Dahinter liegen acht Wege: Rollen aendern, Codes neu setzen,
sperren, loeschen, Protokoll lesen. Einen Manager dort hineinzulassen und
danach in jedem der acht einzeln zu pruefen, was er darf, ist genau die
Bauweise, durch die am 31.08.2026 ein Loch entstanden ist -- zwei von
drei Stellen abgesichert, die dritte vergessen.

Deshalb bleibt die Tuer zu, und daneben steht eine neue mit genau einem
Zweck: POST /workspace/api/creator-anlegen. Sie kann nichts anderes, als
einen Creator anzulegen -- nicht weil eine Abfrage es verbietet, sondern
weil es hier keinen anderen Weg gibt. Unterschied zwischen "darf nicht"
und "kann nicht".

DIE ROLLE STEHT NICHT IM AUFRUF, sie wird im Server gesetzt. Ein Feld
`rolle` im Koerper waere die naheliegende Loesung und die falsche: Dann
muesste eine Abfrage sie pruefen, und eine vergessene Abfrage ist ein
zweiter Zugang mit vollen Rechten. Geprueft wird deshalb nicht, dass ein
mitgeschicktes `rolle: "admin"` abgelehnt wird, sondern dass es
WIRKUNGSLOS ist.

DIE ZUTEILUNG PASSIERT SOFORT. Ein Creator ohne Betreuung ist fuer alle
ausser DogFather unsichtbar -- der Manager haette ihn angelegt und
danach nicht mehr gesehen. Wer anlegt, betreut; ein eigener Scout kann
mitgegeben werden. Eine FREMDE Scout-Nummer wird abgelehnt (403) und
nicht stillschweigend auf den Anleger zurueckgesetzt: Sonst glaubte der
Manager, er haette zugeteilt.

Der Knopf sitzt auf dem Dashboard, nicht in der Personenverwaltung --
dort kommt ein Manager gar nicht hinein, und hier sieht er seine Creator
ohnehin. Der Zugangscode steht einmal im Dialog und wird nie nachgeladen;
deshalb schliesst sich das Fenster NICHT von selbst.

pruef-creator-anlegen.mjs, 29 Pruefungen, alle gruen -- und die Haelfte
davon prueft, was NICHT geht: Personenverwaltung 404 fuer Manager, Scout
und Creator kommen gar nicht erst durch, fremder Scout 403 (und der
Creator wird dabei gar nicht erst angelegt), erfundene Nummer 403. Zwei
Manager mit je einem eigenen Scout, weil sich "nur die eigenen" mit nur
einem Manager gar nicht pruefen laesst.

Nebenbei: .feld-hinweis ist von bereich.css nach aufgaben.css gewandert
(zu den uebrigen Formularstilen) -- ein Formularbaustein in der
Bereichsdatei ist nur so lange richtig, wie ihn keine zweite Seite
braucht.

Gruen: creator-anlegen (29), personen-liste (33), css-klassen (15),
struktur (32), formulare (19).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-07 04:25:49 +02:00
DogFatherGitandClaude Opus 5 d8720debc1 Personen & Automationen gehoeren DogFather allein -- und das Formular laeuft nicht mehr ueber
ZWEI MELDUNGEN.

1. "DAS SIEHT JA MAL RICHTIG SCHEISSE AUS"
   Die Rollenauswahl im Formular "Neue Person" lief unten aus dem
   Formular heraus und legte sich ueber die Personenliste darunter.

   Die Ursache war keine schlampige Gestaltung, sondern eine Regel, die
   fuer etwas anderes gemacht ist: `.neu__raster > *` (aufgaben.css) gibt
   JEDEM direkten Kind ein Raster mit fester Zeilenhoehe von 44 px, damit
   Beschriftung und Eingabefeld in allen Spalten auf einer Linie sitzen.
   Fuer ein einzeiliges Feld ist das genau richtig. Die Rollenauswahl ist
   aber kein Feld, sondern ein Block aus vier hohen Karten -- die passten
   nicht in 44 px, und was nicht hineinpasst, steht eben daneben.

   Das Formular ist jetzt aus dem Spaltenraster geloest und liest sich
   von oben nach unten: NAME (schmal, ein Name braucht keine 1200 px),
   ROLLE (volle Breite, vier gleich breite Karten), Knoepfe. Das ist
   nicht nur reparierter Ueberlauf, sondern auch die Reihenfolge, in der
   man die Sache tatsaechlich entscheidet.

   Dazu zwei Kleinigkeiten, die den Unterschied machen: Das Namensfeld
   war ohne Rasterzeile 60 px hoch geworden (`height: 100%` einer Zeile,
   die es nicht mehr gibt) -- hoeher als die Knoepfe daneben, was nach
   Versehen aussieht, weil es eins war. Und die gewaehlte Rolle traegt
   jetzt ein HAEKCHEN, nicht nur einen etwas helleren Rahmen: Genau die
   Art Unterschied, die im Kontrastmodus verschwindet und fuer
   farbunsichere Augen nie existiert hat.

2. "DIE MANAGER SOLLEN DIESE KATEGORIEN GARNICHT SEHEN"
   "Personen & Zugaenge" und "Automationen" gehoeren ab sofort allein
   DogFather.

   Bei den Personen war es ohnehin ein Widerspruch im eigenen Haus: In
   der Rollenauswahl steht seit jeher "Manager -- dieselben Rechte wie
   DogFather, AUSSER der Personenverwaltung". Die Kachel stand trotzdem
   bei ihm, und die Schranke liess ihn hinein: Codes erneuern, sperren,
   Zuteilungen aendern. Eine Beschreibung, die etwas anderes sagt als die
   Software, ist schlimmer als beides einzeln -- man weiss danach nicht
   mehr, welcher von beiden man glauben soll.

   Umgesetzt auf DREI Ebenen, weil Wegnehmen was man SIEHT kein
   Rechteentzug ist:
     1. die Kachel erscheint nicht mehr
     2. die Seite leitet zur Startseite zurueck (GESCHUETZT)
     3. die Schnittstellen antworten mit 404 -- Personenverwaltung,
        Systemzustand, KI-Schalter

   FOLGE, die bewusst in Kauf genommen wird: Die Betreuungs-Zuteilung
   liegt auf der Personenseite. Ab jetzt kann also NUR DogFather
   festlegen, wer welchen Creator betreut.

GEPRUEFT: server/pruef-personen-formular.mjs, 20 Pruefungen. Das Aussehen
wird gemessen, nicht angesehen: Endet die Rollenauswahl innerhalb des
Formulars? Ragt eine Karte seitlich hinaus? Liegt etwas ueber der Liste?
Sind alle vier Karten gleich breit (272-272 px)? Traegt die gewaehlte ein
Haekchen? Dazu zwei Gegenproben: DogFather kommt weiterhin an beide
Bereiche (sonst waere jede Sperr-Zeile auch bei einem fuer ALLE kaputten
Bereich gruen), und die Managerin arbeitet ansonsten unveraendert weiter.
Bestehende Laeufe gruen: Rollen 97, Handy 50, Sicherung 41, Personenliste
33, Team 30, Formulare 19, Code 17, Grosscheck 15.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-03 00:00:41 +02:00
DogFatherGitandClaude Opus 5 fc26597083 Wer sich einen neuen Code gibt, sperrt sich nicht mehr selbst aus
Gemeldet: "ich hab einen neuen code fuer mich gemacht aber ich wurde raus
gekickt bevor ich den neuen code kopieren konnte jetzt komm ich nicht mehr
rein."

DER FEHLER
Ein neuer Code beendete ALLE Sitzungen der Person -- auch die, in der der
Code gerade auf dem Bildschirm stand. Der naechste Aufruf der Seite lief in
ein "nicht angemeldet", die Umleitung zur Anmeldung nahm den Kasten samt
Code mit, und der Code ist nirgends noch einmal abrufbar (in der Datenbank
steht nur seine Pruefsumme). Ergebnis: ausgesperrt, Rueckweg nur ueber
einen Eingriff auf dem Server.

Bitter daran: Die Rueckfrage sagte das sogar an ("Deine aktuelle Sitzung
wird sofort beendet") -- als Warnung formuliert, nicht als Fehler erkannt.
Ein Ablauf, den man nur mit gutem Timing ueberlebt, ist keiner.

DREI RIEGEL, NICHT EINER

1. DIE EIGENE SITZUNG BLEIBT. codeNeu() beendet weiterhin alle Sitzungen
   der Person -- ausser der einen, aus der heraus der Code gerade erneuert
   wird. Sicherheitlich kostet das nichts: Wer den Code tauscht, hat sich
   mit genau dieser Sitzung soeben ausgewiesen und haelt sie in Haenden.
   Alle ANDEREN Geraete fliegen weiterhin hinaus -- das ist der Sinn der
   Uebung und wird eigens geprueft.

2. DER KASTEN BLEIBT STEHEN. Solange ein frischer Code angezeigt wird,
   springt die Personenseite nicht mehr von selbst zur Anmeldung. Selbst
   wenn eine Sitzung aus einem anderen Grund endet (Zeitablauf, Neustart),
   bleibt der Code lesbar, bis er weggeklickt ist -- mit einem Hinweis,
   ihn jetzt abzuschreiben. Ein Code, den man nicht mehr lesen kann, ist
   schlimmer als gar keiner.

3. EINE TUER VON AUSSEN: tools/notfall-code.sh. Setzt auf dem Server einen
   neuen Code, zeigt ihn an und loescht die Sperre nach acht Fehlversuchen
   gleich mit. Weigert sich, als root zu laufen (sonst gehoerten die
   Hilfsdateien der Datenbank danach root und der Dienst koennte nicht
   mehr schreiben). Dokumentiert als "Fall 0" in WIEDERHERSTELLUNG.md --
   dem ersten Fall, den man aufschlaegt, wenn nichts kaputt ist ausser
   dem Zugang.

   KEIN fest hinterlegter Notfall-Code in der Anwendung: Der waere eine
   Hintertuer, die dauerhaft offensteht, fuer jeden der sie findet, ohne
   dass es auffiele. Dieser Weg verlangt Zugang zum Server, hinterlaesst
   einen Protokolleintrag, und es gibt nichts zu erraten.

Die Rueckfrage sagt jetzt, was wirklich passiert, statt vor etwas zu
warnen, das nicht mehr eintritt.

GEPRUEFT: server/pruef-code.mjs, 17 Pruefungen -- darunter die Gegenprobe,
dass das ZWEITE Geraet derselben Person sehr wohl abgemeldet wird (ohne sie
waere die Reparatur auf dem Weg, einen neuen Code zur Formalie zu machen),
dass der alte Code nicht mehr gilt, dass beim Erneuern eines FREMDEN Codes
weiterhin alles hinausfliegt, und dass die Seite nach dem Erzeugen nicht
zur Anmeldung springt. Das Notfall-Skript ist mit beiden Wegen getestet
(Treffer und unbekannter Name). Bestehende Laeufe gruen: Rollen 97,
Personen-Liste 33, Sicht 48.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-02 23:05:29 +02:00
DogFatherGitandClaude Opus 5 9134b30d06 Scouts gehoeren zu einem Manager ODER zu DogFather -- wie bei den Creatorn
Wunsch vom 02.09.2026: "ich will die Rollen, welcher Scout welchem
Manager oder DogFather gehoert, wie es bei den Creator ist, drunter."

Die Auswahl stand bisher nur dann unter einem Scout, wenn es ueberhaupt
einen Manager gab -- und es gibt zurzeit keinen. In der Personenliste war
davon also nichts zu sehen. Jetzt steht sie immer da, mit Managern UND
DogFather zur Wahl, genau wie "Betreut von" bei den Creatorn.

DIE BEIDEN FAELLE BEWIRKEN VERSCHIEDENES, und das ist Absicht:
  MANAGER    Der Eintrag entscheidet ueber SICHTBARKEIT -- er sieht
             danach die Leads dieses Scouts und dessen Creator.
  DOGFATHER  Der Eintrag haelt nur die ZUSTAENDIGKEIT fest. An den
             Rechten aendert er nichts; DogFather sieht ohnehin alles.

Genau diese Unterscheidung gilt bei den Creatorn seit dem 31.08. auch.
Vorher hatte ich einen Scout unter DogFather abgewiesen mit der
Begruendung, der Eintrag bewirke nichts. Das war zu eng gedacht: Er
beantwortet die Frage "wen frage ich?", und das ist der Zweck dieser
ganzen Liste.

Ein Scout unter einem Scout bleibt ausgeschlossen -- eine Ordnung, die
es nicht gibt.

ZWEI DINGE MITGEZOGEN, damit die Liste nicht zwei Sprachen spricht:
  * Der Leerwert heisst wieder "— niemand —" wie bei den Creatorn.
    "— direkt bei DogFather —" sah aus wie eine Zuordnung und war
    keine -- derselbe Fehler war bei den Creatorn schon einmal behoben
    worden, weil dieselben Leute dadurch gleichzeitig als "ohne
    zustaendige Person" gezaehlt wurden.
  * Die Rolle steht nur dann in Klammern, wenn sie etwas hinzufuegt.
    "Dogfather (DogFather)" waere zweimal dasselbe Wort.

Die Pruefung haelt jetzt BEIDES fest: dass die Zuteilung an DogFather
geht -- und dass sie niemandem mehr Sicht gibt. Verschwimmt dieser
Unterschied je, faellt es dort auf.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-02 02:16:42 +02:00
DogFatherGitandClaude Opus 5 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]>
2026-09-01 22:44:30 +02:00
DogFatherGitandClaude Opus 5 24048ff0e0 Zustaendigkeit: DogFather und Manager zaehlen wie ein Scout
Filipe: "dogfather soll auch zaehlen wie bananastift und patrick."

Beim Nachsehen war das kein Wunsch, sondern ein Fehlerbericht. In der
Auswahl "Betreut von" stand "DogFather" -- aber als LEER-Wert, nicht als
Person. Es sah aus wie eine Zuordnung und war keine. Genau dieselben
Creator zaehlten deshalb gleichzeitig im Hinweis "Creator ohne
zustaendige Person". Zwei Aussagen ueber denselben Sachverhalt, beide auf
demselben Bildschirm, beide fuer sich stimmig.

Jetzt kann jede betreuende Rolle eingetragen werden -- DogFather, Manager
und Scouts, in der ueblichen Reihenfolge. Der Leer-Wert heisst, was er
ist: "— niemand —". Bei DogFather und Manager steht die Rolle in
Klammern dabei; bei aehnlichen Namen ist sonst nicht zu erkennen, wen man
eintraegt. Und "betreut N Creator" steht jetzt an jeder betreuenden
Person, nicht nur an Scouts.

DER WICHTIGE TEIL: An den RECHTEN aendert das nichts.

Die Zustaendigkeit steuert die Sichtbarkeit NUR beim Scout -- die Leitung
sieht ohnehin jeden Creator. Waere das anders, haette eine
Anzeigeeinstellung still Rechte vergeben. Der Test weist beide Richtungen
nach:

  * Tili auf DogFather eingetragen -> KEIN Scout sieht sie.
  * Tili auf Patrick eingetragen   -> nur Patrick sieht sie, BananaStift
                                      weiterhin nicht.
  * Zurueck auf DogFather          -> Patrick verliert die Sicht wieder.
  * DogFather sieht in allen drei Faellen unveraendert beide Creator.

Ein Creator kann nicht zustaendig sein -- das waere eine Rolle, die es
nicht gibt. Und ein Scout kann die Zustaendigkeit weiterhin nicht selbst
setzen (404), sonst haette er die Rechtevergabe in der Hand, die ihn
begrenzen soll.

20 Pruefungen, darunter die Gegenprobe zum Hinweis: Auf "niemand"
zurueckgesetzt MUSS er wiederkommen, sonst waere er wertlos.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 23:40:27 +02:00
DogFatherGitandClaude Opus 5 ac81f288c8 Personen loeschen -- mit Vorschau und einer Sicherung unmittelbar davor
Wunsch Filipe: "ich will auch die moeglichkeit haben die loeschen zu
koennen."

Das ist die einzige Handlung im ganzen Workspace, die sich nicht
rueckgaengig machen laesst. Vier Vorkehrungen:

1. NUR DOGFATHER. Nicht die Leitung, nicht ein Manager -- "nur DogFather
   hat alle endgueltigen Rechte" heisst genau hier etwas. Ein Manager
   kann weiterhin sperren; das reicht fuer den Alltag und ist umkehrbar.
   Alle anderen bekommen 404, auch fuer die Vorschau: Die verraet, wie
   viel an einer Person haengt.

2. VORSCHAU. Vor dem Klick steht da, was MITGEHT (Profil, Start-Check,
   Content-Saeulen, Sitzungen, Zustaendigkeit) und was BLEIBT und nur
   seine Zuordnung verliert (Aufgaben, Termine, Bereichseintraege,
   Dateien, Leads). Eine Aufgabe verschwinden zu lassen, weil jemand
   geht, waere Geschichtsfaelschung.

   Dazu die gefaehrlichste Einzelwarnung: Wer einen Scout loescht, nimmt
   seinen Creators die zustaendige Person weg. Die Vorschau nennt sie
   beim Namen.

3. EINE SICHERUNG DIREKT DAVOR -- und wenn sie scheitert, wird NICHT
   geloescht. Damit ist "geloescht" wiederherstellbar. Das ist der
   eigentliche Gewinn aus der Sicherungsarbeit von heute Nachmittag.

4. Der Name muss getippt werden. Nicht als Schikane: Der Loeschknopf
   sitzt neben dem Sperrknopf, und die beiden sind sehr verschieden. Wer
   den Namen tippt, hat die Zeile gelesen, die er trifft.

ZWEI FEHLER, die erst die Pruefung sichtbar gemacht hat:

a) Alle Loeschungen schrieben in DIESELBE Tagessicherung. Nach der
   dritten kannte sie die erste geloeschte Person nicht mehr -- die
   Sicherung haette genau in dem Fall versagt, fuer den sie da ist.
   Loeschungen bekommen jetzt eine eigene Datei ("vorher-…") mit
   Zeitstempel, die nie ueberschrieben wird. Aufgefallen nur, weil die
   Pruefung die ANZAHL der Dateien zaehlt und nicht bloss, ob eine da ist.

b) Der Zeitstempel hatte Sekundenaufloesung -- drei Loeschungen in
   derselben Sekunde ergaben wieder eine einzige Datei. Jetzt mit
   Millisekunden, plus Zaehler als Notloesung. Und: Eine Sicherung vor
   dem Loeschen setzt NICHT den Vermerk fuer den planmaessigen Lauf,
   sonst faellt die naechtliche Sicherung aus.

Dabei auch ein Fehler in meiner eigenen Pruefung gefunden: Sie griff die
alphabetisch erste Datei und nannte sie "die aelteste" -- "vorher-…-2.db"
sortiert aber VOR "vorher-….db", weil "-" kleiner ist als ".". Sie prueft
jetzt die Eigenschaft selbst: JEDE geloeschte Person muss sich aus
irgendeiner Sicherung zurueckholen lassen.

43 Pruefungen, Schwerpunkt auf dem, was NICHT gehen darf.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 23:13:14 +02:00
DogFatherGitandClaude Opus 5 2dbf9fb57a Personen: eine Kategorie je Rolle, Reihenfolge wie auf der Zugangsseite
Wunsch Filipe: "ich will dass die auch immer die gleiche reihenfolge
haben, am besten sogar jeder seine eigene kategorie und die reihenfolge
genau wie in der zugangsseite."

Dabei kam ein echter Fehler ans Licht. Die Abfrage sortierte mit

    ORDER BY p.aktiv DESC, <Rolle>, p.name

Das "p.aktiv DESC" stand VOR der Rolle -- dadurch wanderte jede gesperrte
Person ans Ende der GESAMTEN Liste, quer durch alle Rollen. Im Bild vom
31.08.2026 stand der gesperrte Manager BanaStift deshalb ganz unten unter
den Creators. Die Reihenfolge DogFather-Manager-Scout-Creator, die
ueberall sonst gilt (ROLLEN_SORTIERUNG, CLAUDE.md), war ausgerechnet auf
der Personenseite aufgehoben -- und es sah nach Absicht aus.

Jetzt: Rolle zuerst, dann Gesperrtes ans Ende SEINER Rolle, dann Name.

Dazu vier Abschnitte mit Ueberschrift, Anzahl und demselben Zusatztext
wie auf der Zugangsseite ("Eigene Pipeline & Kontakte" usw.) -- wer sich
eben angemeldet hat, findet hier dieselbe Sprache wieder. Eine Rolle ohne
Personen wird weggelassen: Eine leere Ueberschrift ist kein
Ordnungsmerkmal, sondern eine Luecke.

Die Gruppen-Gestaltung kommt aus start.css und wird nur wiederverwendet
-- dieselbe Sprache wie auf der Startseite, kein zweiter Entwurf.

Nebenbei ein Eigentor: Der Kommentar zur Sortierung stand zuerst INNERHALB
der SQL-Zeichenkette und enthielt Rueckwaerts-Anfuehrungszeichen. Die
beenden ein Template-Literal -- der Server startete nicht mehr. Steht
jetzt darueber, mit einem Hinweis darauf.

30 Pruefungen. Neu darunter: dass die vier Abschnitte in genau dieser
Reihenfolge stehen, dass der gesperrte Manager bei den Managern steht und
nicht bei den Creators, und dass zugeklappt nur der DogFather-Abschnitt
da ist.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 23:05:04 +02:00
DogFatherGit 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.
2026-08-31 11:32:22 +02:00
DogFatherGit 1c3e642f12 Workspace: Rolle "Management" heisst jetzt "DogFather"
Auf Wunsch von Filipe. Betrifft ausschliesslich die Anzeige.

Der Rollenschluessel bleibt "admin". Er steckt in der CHECK-Regel der
Datenbank, in jeder bestehenden Sitzung und in jeder Rechteabfrage --
ihn umzubenennen haette alle drei gebrochen, und bestehende Anmeldungen
waeren ungueltig geworden. Umbenannt wird nur, was man LIEST.

Der Anzeigename steht jetzt an EINER Stelle (ROLLEN_NAME in
workspace.js) und kommt ueber /workspace/api/ich als rolle_name mit.
Stand er in elf Dateien, waere er beim naechsten Mal in zehn davon
geaendert.

Dabei aufgefallen: In der Kopfleiste stand auf JEDER Seite der rohe
Rollenschluessel -- "Chef · admin". Das war schon vorher unschoen, faellt
aber jetzt erst richtig auf. Alle elf Seiten zeigen jetzt "Chef ·
DogFather". Geprueft: kein rohes "admin" mehr in der Oberflaeche.

Geaendert: Rollenkachel und Untertitel auf der Anmeldeseite, Kopfleiste
aller Seiten, Rollentext auf dem Dashboard, Rollenmarken und Auswahl in
der Personenverwaltung, die Betreuungs-Auswahl ("nur DogFather"), der
Hinweis auf der Dateienseite, die Erklaerung zur internen Notiz im
Profil, die Hinweise fuer Scouts ohne Zuteilung -- und vier
Fehlermeldungen vom Server.

Schreibweise "DogFather" wie von Filipe geschrieben; das ist auch auf
der oeffentlichen Website die haeufigste Form (717 von 1216).

In den Code-Kommentaren der Fachmodule heisst die Rolle weiterhin "das
Management". Das bleibt bewusst so -- eine Massenaenderung an vierzig
Kommentaren waere reines Risiko ohne sichtbaren Nutzen. Ein Hinweis an
der ROLLEN_NAME-Zuordnung erklaert den Zusammenhang.
2026-08-28 11:55:05 +02:00
DogFatherGit fa8fbab410 Workspace: Scouts betreuen Creator wie das Management
Bisher hatten Scouts mit der Creator-Betreuung nichts zu tun -- keine
Profile, keine Betreuungsbereiche, keine Reports. Das aendert sich, mit
zwei bewusst gesetzten Grenzen.

GRENZE 1: nur zugeteilte Creator, keine Rollenregel.

Neue Tabelle betreuung (creator_id PRIMARY KEY -> betreuer_id). Ein
Creator hat genau EINE zustaendige Person, damit nie unklar ist, wer
gefragt ist. Das Management sieht ohnehin alle und braucht keinen
Eintrag. Wer nichts zugeteilt bekommt, sieht weiterhin nichts -- kein
Recht entsteht automatisch aus der Rolle.

Zugeteilt wird in "Personen & Zugaenge", direkt in der Personenzeile:
Betreuung ist eine Eigenschaft der Person, kein eigener Vorgang. Nur das
Management darf zuteilen -- koennte ein Scout sich selbst Creator geben,
haette er die Rechtevergabe in der Hand, die ihn begrenzen soll.
Zustaendig koennen nur aktive Scouts sein, kein Admin (der sieht alles)
und kein anderer Creator.

Bei der Uebergabe aus der Pipeline passiert die Zuteilung von selbst:
Wer jemanden gefunden hat, betreut ihn weiter. Genau darum geht es bei
"Creator-Onboarding starten". Umhaengen kann das Management jederzeit.

GRENZE 2: betreuen, nicht verwalten.

Profile, die fuenf Bereiche und Reports wie ein Manager. ABER:
- keine Zugangscodes, kein Sperren von Personen (personen.html bleibt
  admin-only, unveraendert)
- keine management-internen Felder. Der Scout bekommt admin_notiz,
  plan_start und naechster_review NICHT -- die Felder fehlen in der
  Antwort komplett, nicht nur in der Anzeige. Eine Notiz UEBER die
  Betreuung gehoert nicht in die Hand dessen, der betreut. Geprueft: Ein
  Scout, der admin_notiz mitschickt, aendert sie nicht.

Die Regel steht an EINER Stelle (betreuteIds / betreutWo / darfCreator
in workspace.js) und wird von sechs Modulen benutzt. Eine Rechteregel,
die an sechs Stellen steht, ist eine Rechteregel, die irgendwann an
fuenf Stellen stimmt.

Genau das ist beim Bauen auch passiert: workspace-calls.js hatte eine
wortgleiche Kopie der Kalender-Sichtbarkeit. Erweitert wurde nur der
Kalender -- Scouts sahen die Termine ihrer Creator, dieselben Termine
als Call aber nicht. Die Kopie ist jetzt weg, calls.js importiert die
Regel aus workspace-kalender.js.

Zwei Fehler, die die Aenderung selbst erzeugt haette, vorher gefunden:
- Report-Entscheidung: ein Scout haette eine Aufgabe angelegt, deren
  "Creator" er selbst ist -- die waere in jeder Auswertung falsch
  mitgelaufen. Zeigt jetzt auf einen seiner Creator.
- Bereichseintrag: derselbe Fehler. Ein Scout hat gar keinen eigenen
  Betreuungsbereich. Ein Eintrag ohne oder mit fremder Zuordnung landet
  beim ersten zugeteilten Creator, nie bei einem fremden. Geprueft:
  Mikas Bereich bleibt bei jedem Versuch unberuehrt.
2026-08-28 11:18:56 +02:00
DogFatherGit 232a2003dd Workspace: Aufgaben bearbeiten, Personenverwaltung im Browser
Aufgaben:
- Bearbeiten-Dialog (Titel, Beschreibung, Prioritaet, Frist, Zuordnung).
  Als natives <dialog>: Fokusfang, Esc zum Schliessen und Abdunklung
  ohne eigenen Code.
- Loeschen nur fuer Management, mit Rueckfrage und Protokolleintrag.
  Das Konzept will, dass Erledigtes stehen bleibt -- Loeschen ist der
  Ausnahmefall fuer Fehleintraege, nicht der normale Abschluss.

Personen (/workspace/personen.html, nur Management):
- Anlegen, Code erneuern, sperren/entsperren, Protokollansicht
- Der Code wird genau einmal in der Antwort zurueckgegeben, nie
  gespeichert; beim Schliessen auch aus dem Dokument entfernt
- Selbstschutz: niemand kann sich selbst sperren, und das letzte aktive
  Management laesst sich nicht sperren -- sonst kaeme niemand mehr hinein
- Code fuer sich selbst tauschen nur mit ausdruecklicher Bestaetigung,
  weil es die eigene Sitzung sofort beendet

Zwei Fehler, die beim Testen aufgefallen sind:

1. Rollenpruefung fehlte beim Ausliefern der Seiten. Ein Creator bekam
   personen.html mit HTTP 200 -- die Schnittstellen wiesen ihn zwar ab,
   das Geruest der Seite war aber sichtbar. GESCHUETZT ist jetzt eine
   Zuordnung Pfad -> erlaubte Rollen statt einer blossen Liste.

2. Das Protokoll nannte den falschen Verursacher. personAnlegen trug die
   NEU ANGELEGTE Person als person_id ein, der Eintrag las sich also so,
   als haette sie sich selbst angelegt. Akteur und Betroffener sind jetzt
   getrennt: Akteur in person_id, Betroffener im Text. Ueber die
   Kommandozeile angelegte Personen zeigen korrekt keinen Akteur.
2026-08-27 23:12:28 +02:00