Kapitel 11 auf der Crew-Adresse: die Community gehoert nicht in die Pflegeliste

ZWEITER BEFUND DES ABENDS, und wieder einer, den es im Agenturhaus
gar nicht geben konnte.

Bauplan Kapitel 11, woertlich: "Stand der Ersten Schritte: nur fuer
Team-Rollen, 'fertig / offen' mit Datum. Fuer die Community wird
nichts je Person angezeigt."

Gemessen: Auf der Crew-Adresse nahm die Liste schlicht alle Fassungen
des Hauses -- und seit die Community seit heute frueh eine eigene
Fassung hat, stand jedes Mitglied mit Namen, Fortschritt und Datum
darin. Im Agenturhaus konnte das nie auffallen, dort ist jede Fassung
eine Teamrolle.

Das ist kein Schoenheitsfehler: Ein Mitglied hat sich zum Mitlesen
angemeldet, nicht zu einer Fortschrittsakte. Jetzt siebt
`standRollen()` ueber AUSSEN_ROLLEN -- abgeleitet und nicht als zweite
Liste, damit die naechste Rolle von aussen automatisch heraus ist.
Gegenprobe gefahren: Sieb ausgebaut -> die Zeile wird rot und nennt
"1 von 4".

DAZU GEPRUEFT, was Kapitel 11 sonst verlangt (pruef-anleitung
173 -> 181): DogFather bekommt auf der Crew-Adresse die Pflege statt
einer Fassung, mit den VIER Fassungen dieses Hauses (nicht denen der
Agentur); ein Modi kommt an die Liste gar nicht heran (403); und die
"Vorschau in der Sicht dieser Rolle" liefert ihm die 29 Karten des
Modi, mit `darf_pflegen: true` und `darf_abhaken: false` -- er soll
pflegen koennen, aber nicht in fremdem Namen abhaken. Nachgestellt
wird dabei genau die Anfrage, die kopf.js stellt (`sicht=<Nummer>`
an jede lesende Anfrage), nicht eine nachgebaute.

AUSSERDEM: ZWEI DINGE HIESSEN `an-stufe`
Der Kasten einer EINORDNUNG ("Das brauchst du sofort") und der Kasten
"Deine Stufe" mit Neu, Dabei, Stamm trugen dieselbe Klasse. Der
Bauplan warnt in Kapitel 14 ausdruecklich davor, die beiden zu
verwechseln -- im Quelltext taten sie es.

Aufgefallen beim Messen des Filters "Muss": Er musste seine Suche von
Hand auf `#stufen` eingrenzen, sonst haette er die Karte "Deine Stufe"
mit weggeblendet. Eine Regel wie `.an-stufe { display: none }` haette
denselben Schaden angerichtet, und man haette sie nicht kommen sehen.
Die Mitglieder-Stufe heisst jetzt `an-rang`; in der Oberflaeche aendert
sich kein Wort.

IM BROWSER NACHGEMESSEN (390 px, echte Anmeldung)
  Filter "Muss"  -> Community 5 Karten, rechte Hand 8. Genau die
                    Zahlen der Abnahme-Checkliste, und nach dem
                    Umbenennen blendet er nur noch den einen
                    Abschnitt aus statt zwei.
  "Deine Stufe"  -> Community ja ("Du bist gerade: Neu"), rechte Hand
                    nein. Steht und faellt mit dem neuen Namen.
  Keine Browsermeldungen, kein Querscrollen.

pruef-css-klassen und pruef-anleitung (181) gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-06 17:49:18 +02:00
co-authored by Claude Opus 5
parent a7b5775268
commit 88a8d302b9
51 changed files with 842 additions and 707 deletions
+69
View File
@@ -1290,6 +1290,75 @@ melde("\n=== Seite sperren, Karte weg (Abnahme Kapitel 13) ===");
+ `${vorher.length})`);
}
/* =====================================================================
DIE PFLEGE AUF DER CREW-ADRESSE (Bauplan Kapitel 11)
---------------------------------------------------------------------
„Fuer DogFather gibt es keine Fassung und keinen Rundgang. Bei ihm
oeffnet die Kachel die Pflege-Ansicht: Rolle waehlen und Vorschau,
Einordnung aendern, Texte bearbeiten, Lueckenwarnung, Stand der
Ersten Schritte — nur fuer Team-Rollen, fuer die Community wird
nichts je Person angezeigt."
DER LETZTE HALBSATZ IST DER, DER HIER GEMESSEN WIRD. Im Agenturhaus
konnte er nie falsch sein (dort ist jede Fassung eine Teamrolle);
auf der Crew-Adresse schon, seit die Community eine eigene Fassung
hat. Ein Mitglied hat sich zum Mitlesen angemeldet, nicht zu einer
Fortschrittsakte mit Namen und Datum. */
melde("\n=== Die Pflege auf der Crew-Adresse (Kapitel 11) ===");
{
const dogiCrew = await holen("admin", CREW_HOST);
ok(dogiCrew.code === 200 && dogiCrew.j?.hat_fassung === false
&& dogiCrew.j?.darf_pflegen === true,
`DogFather bekommt auf der Crew-Adresse die Pflege, keine Fassung `
+ `(HTTP ${dogiCrew.code}, Fassung ${dogiCrew.j?.hat_fassung}, `
+ `pflegen ${dogiCrew.j?.darf_pflegen})`);
/* Und zwar die VIER des Hauses, nicht die der Agentur. */
const angeboten = (dogiCrew.j?.fassungen || []).join(",");
ok(angeboten === "gast,modi,linke,hand",
`…mit den vier Fassungen dieses Hauses (${angeboten || "keine"})`);
const st = await roh("/workspace/api/anleitung/stand", CREW_HOST, null, kekse.admin);
let leute = [];
try { leute = JSON.parse(st.text)?.leute || []; } catch { /* bleibt leer */ }
ok(st.code === 200 && leute.length > 0,
`der Stand der Ersten Schritte oeffnet sich (HTTP ${st.code}, `
+ `${leute.length} Leute)`);
ok(!leute.some((p) => p.rolle === "gast"),
`…und kein einziges Mitglied steht darin (${
leute.filter((p) => p.rolle === "gast").length} von ${leute.length})`);
/* GEGENPROBE: Es steht ueberhaupt jemand drin, und zwar aus dem
Team. Ohne diese Zeile waere die darueber auch dann gruen, wenn
die Liste aus einem ganz anderen Grund leer bliebe. */
ok(leute.some((p) => ["modi", "linke", "hand"].includes(p.rolle)),
`Gegenprobe: die Teamrollen stehen sehr wohl darin (${
leute.map((p) => p.rolle).join(", ") || "niemand"})`);
/* Und ein Modi kommt gar nicht erst an die Liste. */
const stModi = await roh("/workspace/api/anleitung/stand", CREW_HOST, null, kekse.modi);
ok(stModi.code === 403, `ein Modi sieht den Stand nicht (${stModi.code})`);
/* ---- „Rolle waehlen und Vorschau in der Sicht dieser Rolle" -------
Gebaut ist das nicht als zweite Rollenauswahl, sondern ueber den
Sicht-Umschalter, den es im Haus schon gibt: kopf.js haengt jeder
LESENDEN Anfrage `sicht=<Nummer>` an. Genau das wird hier
nachgestellt -- nicht nachgebaut, sondern dieselbe Anfrage
gestellt, die der Browser stellt. */
const modiId = (() => {
const d = new DatabaseSync(process.env.WORKSPACE_DB);
const z = d.prepare("SELECT id FROM personen WHERE rolle = 'modi'").get();
d.close(); return z?.id || 0;
})();
braucht(!!modiId, "kein Modi in der Probe-Datenbank");
const vorschau = await roh(`/workspace/api/anleitung?sicht=${modiId}`,
CREW_HOST, null, kekse.admin);
let vj = null; try { vj = JSON.parse(vorschau.text); } catch { /* bleibt null */ }
ok(vj?.rolle === "modi" && (vj?.karten?.length ?? 0) === 29,
`in der Sicht auf einen Modi sieht er dessen Anleitung `
+ `(${vj?.rolle}, ${vj?.karten?.length ?? 0} Karten)`);
ok(vj?.darf_pflegen === true && vj?.darf_abhaken === false,
`…darf sie pflegen, aber nicht in fremdem Namen abhaken `
+ `(pflegen ${vj?.darf_pflegen}, abhaken ${vj?.darf_abhaken})`);
}
/* ---------- Abschluss ------------------------------------------------ */
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ }
console.log(`\n${fehler ? "FEHLER: " + fehler : "Alles in Ordnung"} — ${geprueft} Prüfungen`);