diff --git a/server/pruef-haus-seiten.mjs b/server/pruef-haus-seiten.mjs index 9529ab3e..92977a2e 100644 --- a/server/pruef-haus-seiten.mjs +++ b/server/pruef-haus-seiten.mjs @@ -81,6 +81,22 @@ const jetzt = new Date().toISOString(); anlegen("Rieke", "hand", "CODE-HAND-0001"); anlegen("Frida", "modi", "CODE-MODI-0001"); anlegen("Mara", "manager", "CODE-MANA-0001"); + anlegen("Sam", "creator", "CODE-CREA-0001"); + const idSam = d.prepare("SELECT id FROM personen WHERE name = 'Sam'").get().id; + /* EIN ECHTER ANLASS FÜR DEN HINWEIS. Ohne ihn gäbe es ihn nirgends, + und „er steht nicht auf crew.“ wäre ein grüner Haken über der Null. + + DIE TABELLE NICHT SELBST ANLEGEN: Der erste Entwurf schrieb hier + ein CREATE TABLE IF NOT EXISTS mit erfundenen Spalten hin. Die + echte Tabelle war längst da, das IF NOT EXISTS schwieg, und der + INSERT scheiterte an „no column named schluessel“ -- die Prüfung + hätte gemeldet, der Hinweis stehe nirgends, und das wäre richtig + und wertlos gewesen. Gefunden hat es die Gegenprobe. */ + const spalten = d.prepare("PRAGMA table_info(startcheck)").all().map((x) => x.name); + if (!spalten.includes("bewertung")) throw new Error("startcheck sieht anders aus als erwartet"); + d.prepare("INSERT INTO startcheck (creator_id, feld, punkt, bewertung, geaendert)" + + " VALUES (?,?,?,?,?)") + .run(idSam, "technik", "licht", "handlung", jetzt); d.close(); } @@ -262,6 +278,73 @@ melde("=== 5. Der Durchgang über alle Seiten ==="); `für einen Modi mehr als für DogFather (${zu.modi.length})`); } +/* ======================================================================= + 6. EIN HINWEIS AUF EINE SEITE, DIE ES HIER NICHT GIBT + + Filipe, nach dem Ausliefern: „wieso steht es noch da?" -- „1 Punkt im + Start-Check braucht Handlung", auf crew., mit einem Pfeil auf eine + Seite, die dort gesperrt ist. + + Das war die dritte Stelle: nicht Seite, nicht Schnittstelle, sondern + eine Liste von VERWEISEN. Sie bekommt jetzt dieselbe Regel. + ======================================================================= */ +melde(""); +melde("=== 6. Hinweise und Suche ==="); +{ + const hinweise = async (host, keks) => { + const a = await ruf("/workspace/api/hinweise", host, "GET", { cookie: keks }); + try { return JSON.parse(a.text).hinweise || []; } catch { return []; } + }; + + /* ZUERST DIE GEGENPROBE: Auf der Agenturadresse MUSS er dastehen. + Ohne sie beweist „er ist auf crew. weg" nur, dass es ihn nirgends + gibt. */ + const drueben = await hinweise(HAUS, kDogi); + const dort = drueben.find((h) => h.art === "startcheck_handlung"); + ok(!!dort, `auf der Agenturadresse steht der Hinweis (${dort?.text || "—"})`); + ok(dort?.ziel === "startcheck.html", `und zeigt auf den Start-Check (${dort?.ziel})`); + + /* UND HIER IST DER GEMELDETE FEHLER. */ + const hier = await hinweise(CREW, kDogiCrew); + ok(!hier.some((h) => h.art === "startcheck_handlung"), + "auf der Team-Adresse steht er nicht mehr"); + ok(!hier.some((h) => /startcheck|scouting|content|profil|calls/.test(String(h.ziel || ""))), + `und kein einziger Hinweis zeigt dorthin (${hier.length} Hinweise insgesamt)`); + + /* ABER DIE HINWEISE DES TEAMS BLEIBEN. Eine Regel, die alle + wegnimmt, wäre keine Lösung, sondern eine leere Startseite. */ + ok(hier.every((h) => !h.ziel + || ws.gehoertAufDieseAdresse({ rolle: "admin", haus: "crew" }, + "/workspace/" + String(h.ziel).split("?")[0])), + "jeder verbliebene Hinweis führt auf eine Seite, die es hier gibt"); + + /* DIESELBE SORTE VERWEIS: die Suche. */ + const suche = async (host, keks, q) => { + const a = await ruf(`/workspace/api/suche?q=${encodeURIComponent(q)}`, host, "GET", + { cookie: keks }); + try { return JSON.parse(a.text); } catch { return { gruppen: [] }; } + }; + /* ZUERST WIEDER DIE GEGENPROBE. „Kein Treffer zeigt dorthin“ ist + wertlos, solange es gar keinen Treffer gibt -- genau der grüne + Haken über der Null, vor dem die Hausregel warnt. Also erst + nachweisen, dass die Suche diesen Menschen auf der Agenturadresse + WIRKLICH findet. */ + const s0 = await suche(HAUS, kDogi, "Sam"); + const zieleH = (s0.gruppen || []).flatMap((g) => g.treffer || []).map((t) => t.ziel || ""); + ok(zieleH.length > 0, `auf der Agenturadresse findet die Suche Sam (${zieleH.length} Treffer)`); + ok(zieleH.some((z) => /profil.html/.test(z)), + `und ein Treffer führt auf sein Creator-Profil (${zieleH.join(", ")})`); + + const s1 = await suche(CREW, kDogiCrew, "Sam"); + const ziele = (s1.gruppen || []).flatMap((g) => g.treffer || []).map((t) => t.ziel || ""); + ok(!ziele.some((z) => /profil|scouting|calls|content/.test(z)), + `auf der Team-Adresse verweist keiner dorthin (${ziele.length} Treffer)`); + ok(s1.gesamt === ziele.length, + `und die Zahl nennt nur, was wirklich dasteht (${s1.gesamt})`); + ok((s1.gruppen || []).every((g) => (g.treffer || []).length > 0), + "keine Überschrift ohne Treffer darunter"); +} + /* ------------------------------------------------------------------- */ melde(""); melde(`${geprueft} Pruefungen, ${fehler} Fehler`); diff --git a/server/workspace-hinweise.js b/server/workspace-hinweise.js index f2d414a5..2260301e 100644 --- a/server/workspace-hinweise.js +++ b/server/workspace-hinweise.js @@ -25,6 +25,7 @@ import express from "express"; import { db, sitzungLesen, betreuteIds, istLeitung, istDogFather, siehtAlles, pipelineIds, + gehoertAufDieseAdresse, } from "./workspace.js"; import { sichtbar as sichtbarAufgaben } from "./workspace-aufgaben.js"; import { sichtbar as sichtbarTermine } from "./workspace-kalender.js"; @@ -80,8 +81,33 @@ hinweisRouter.get("/workspace/api/hinweise", (req, res) => { const jetzt = jetztLokal(); const hinweise = []; + /* DIE ADRESSE IST IMMER DIE ECHTE (15.09.2026). + + `person` kann die angesehene sein -- der Sicht-Umschalter zeigt + die Lage eines anderen. Das aendert, WESSEN Zahlen dastehen, + nicht, auf welcher Wand man steht. */ + const hier = { ...person, haus: (req.person || person)?.haus }; + const dazu = (art, stufe, text, ziel, anzahl) => { if (!anzahl) return; + /* EIN HINWEIS AUF EINE SEITE, DIE ES HIER NICHT GIBT, IST KEIN + HINWEIS (15.09.2026). + + Filipe, mit dem Bildschirmfoto auf crew.: „wieso steht es noch + da?" -- „1 Punkt im Start-Check braucht Handlung". Die Seite + war da schon gesperrt; der Hinweis zeigte ins Leere. + + Das war MEIN Fehler von heute Mittag: Ich hatte die Seiten + gesperrt und ausdruecklich dazugeschrieben „nur die Seiten, + nicht die Schnittstellen" -- und dabei uebersehen, dass die + Hinweise eine DRITTE Stelle sind. Sie sind keine Seite und + keine Schnittstelle, sondern eine Liste von Verweisen. + + DIESELBE REGEL, NICHT EINE ZWEITE: Was auf dieser Adresse + keine Seite hat, bekommt hier auch keinen Hinweis. Eine eigene + Liste hier waere die, die beim naechsten Umbau auseinanderlaeuft. */ + if (ziel && !gehoertAufDieseAdresse(hier, + "/workspace/" + String(ziel).split("?")[0])) return; hinweise.push({ art, stufe, text, ziel, anzahl }); }; diff --git a/server/workspace-suche.js b/server/workspace-suche.js index dec0738f..b22e36e0 100644 --- a/server/workspace-suche.js +++ b/server/workspace-suche.js @@ -25,7 +25,7 @@ import express from "express"; import { db, sitzungLesen, betreuteIds, istLeitung, istDogFather, siehtAlles, pipelineIds, - sichtbareCreatorIds, + sichtbareCreatorIds, gehoertAufDieseAdresse, } from "./workspace.js"; import { sichtbar as sichtbarAufgaben } from "./workspace-aufgaben.js"; import { sichtbar as sichtbarTermine } from "./workspace-kalender.js"; @@ -278,11 +278,35 @@ sucheRouter.get("/workspace/api/suche", (req, res) => { } } + /* UND HIER GILT SIE AUCH (15.09.2026). + + Ein Suchtreffer ist ein Verweis auf eine Seite. Zeigt er auf eine, + die es auf dieser Adresse nicht gibt, fuehrt er zur Startseite + zurueck -- und man sucht ihn beim naechsten Mal wieder. + + Die Daten waren nie das Problem: Die filtert die Haustrennung seit + dem 10.09. Das Ziel war es. Gefunden habe ich das nicht durch + Nachdenken, sondern beim Nachsehen, WER SONST NOCH Seitenziele + ausliefert, nachdem Filipe den Hinweis gemeldet hatte. + + LEERE GRUPPEN FALLEN MIT WEG. Eine Ueberschrift ohne Treffer + darunter sieht aus, als waere etwas kaputtgegangen. */ + const hier = { ...person, haus: (req.person || person)?.haus }; + const erlaubt = gruppen + .map((g) => ({ + ...g, + treffer: (g.treffer || []).filter((t) => !t?.ziel + || gehoertAufDieseAdresse(hier, "/workspace/" + String(t.ziel).split("?")[0])), + })) + .filter((g) => g.treffer.length); + res.json({ frage: q, zu_kurz: false, - gruppen, - gesamt: gruppen.reduce((s, g) => s + g.treffer.length, 0), + gruppen: erlaubt, + /* Abgeleitet, nicht mitgezaehlt -- sonst nennt die Zahl Treffer, + die gar nicht dastehen. */ + gesamt: erlaubt.reduce((s, g) => s + g.treffer.length, 0), }); } catch (fehler) { console.error("[workspace] Suche:", fehler?.message); diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index ff056be9..0f00e6f8 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -13,25 +13,25 @@ "theme_color": "#06090f", "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609151417", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609151430", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609151417", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609151430", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609151417", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609151430", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609151417", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609151430", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 5b166fe5..d8056446 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - +
@@ -282,10 +282,10 @@ - - - - - + + + + +