Die zwei Häuser sind getrennt -- und die Tür geht in beide Richtungen

Filipe: "ich will dass du zuerst die komplette site vn der workspace
seite trennst. da soll nichts verknüpft sein. wenn ich bei der einen
was mache soll nichts bei der anderen passieren. … es soll nur für
dogfather eine kachel geben wo er mit einem einfachen klick von der
einen auf die anderen seite kommt aber sonst garnichts."

Das kehrt die Entscheidung vom 10.09.2026 um ("getrennt wird das
AUSSEHEN, nicht der Bestand"). Wer den alten Kommentar liest, liest
einen überholten Stand -- das steht jetzt an jeder betroffenen Stelle.

WAS GEMESSEN WAR, BEVOR ETWAS GEBAUT WURDE
  * Nur drei Module trennten nach Haus (Aufgaben, Bereiche, Dateien).
    Chat, Kalender, Wissen, Material, Personenlisten und der Rest nicht.
  * Die Trennung war EINSEITIG: nurHaus() griff nur auf crew.
  * siehtModis() hebelte sie für DogFather auf der Agenturseite aus --
    in seiner Gesprächsliste standen dort beide Häuser nebeneinander.
  * Keine haus-Spalte in der Datenbank.
  * Der Bestand kreuzte aber kaum: 0 von 86 Terminen gemischt, 0 von 7
    Zweier-/Gruppengesprächen, genau EIN Kanal.

WAS JETZT DASTEHT
  * Drei Rollenmengen in crew-adresse.js (crew / agentur / beide) und
    hausVonRolle(); eine unbekannte Rolle bekommt null, kein Haus.
  * Spalte `haus` an acht Wurzeltabellen, nachgetragen aus Belegen:
    238 Zeilen eindeutig, die Wissensablage geschlossen der Agentur,
    vier Restzeilen namentlich, der gemischte Kanal aufgelöst
    (die zwei Scouts gehen heraus, die 7 Nachrichten sind alle vom
    Team). Offen bleiben: null.
  * nurHaus, hausBedingung und darfAnlegen gelten in BEIDE Richtungen.
  * Der siehtModis-Durchgriff ist weg -- aber in DREI Fällen, nicht
    zwei: Prüfadressen bekommen gar kein Haus und verhalten sich exakt
    wie vorher. Die erste Fassung hatte das übersehen und 19 Prüfungen
    umgeworfen, an denen nichts kaputt war.
  * Kalender: getrennt, aber "belegt" bleibt (Filipes Entscheidung).
    Die Blöcke tragen NUR Beginn und Dauer -- kein Titel, keine Person.
    Gebaut als Gegenstück zur Liste (meine Termine MINUS die sichtbaren),
    damit beide nicht auseinanderlaufen können.
  * Die Wissens-Kachel ist auf der Team-Adresse weg UND die Route
    antwortet dort mit 404 -- eine fehlende Kachel ist nur eine Bitte.
  * Die Wechsel-Kachel für DogFather geht jetzt in beide Richtungen.

GEPRÜFT: pruef-haus-trennung 97 statt 81, 0 Fehler (vorher 7, alle
haben die alte Regel behauptet). Die neuen Abschnitte sind DORT
eingezogen statt in eine zweite Datei -- `pruef-haustrennung.mjs` hätte
sich von `pruef-haus-trennung.mjs` um einen Bindestrich unterschieden.
Dazu grün: haus-seiten, crew-adresse, chat, chat-kanaele,
kanal-besetzung, kalender, serien, treffchat, wissen-neu,
modi-checkliste, modi-katalog, rechtetafel, personen-liste, sicht,
verborgen, fremde-sicht, alle-wege.

NICHT VON MIR: pruef-treff (3) und pruef-kachel-universum (2) waren
schon vorher rot -- beim Treff auf dem Stand 40b48e89 nachgemessen,
bei den Farben steht dieselbe Zahl im Kopf der Prüfung selbst.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-24 20:40:20 +02:00
co-authored by Claude Opus 5
parent 40b48e89f1
commit 9863645952
55 changed files with 1718 additions and 697 deletions
+71 -4
View File
@@ -16,6 +16,7 @@ import {
db, protokolliere, echteIp, sitzungLesen, istLeitung, istDogFather, siehtAlles, betreutWo, termineSichtbar, heuteLokal,
kategorienFuer,
externPruefen, externSql, betreuteIds, einladbareIds, verborgeneIds, ROLLEN_SORTIERUNG, ROLLEN_GRUPPE,
hausWo, ohneAnderesHaus,
} from "./workspace.js";
import {
nachfuellenAlle, serienPruefen, serieAnlegen, zuordnungErzwingen,
@@ -486,7 +487,72 @@ kalenderRouter.get("/workspace/api/termine", (req, res) => {
b.text = b.text ? String(b.text).slice(0, 180) : null;
}
res.json({ termine, fristen, brettsachen, von, bis, checkliste_moeglich: moeglich });
/* ==== WAS AUF DER ANDEREN SEITE SCHON BELEGT IST (24.09.2026) ===
Filipe, zur Frage, was aus der Kalender-Ausnahme vom 11.09. wird:
„Getrennt, aber ‚belegt' bleibt sichtbar."
ZWEI ANSPRUECHE, EINE ANZEIGE. Der INHALT gehoert getrennt --
kein Titel, kein Teilnehmer, keine Notiz aus dem anderen Haus.
Die ZEIT gehoert nicht getrennt: Wer die Haelfte seines Tages
nicht sieht, legt einen Call auf eine Stunde, in der er schon
woanders sitzt. Genau das war der Grund fuer die alte Ausnahme,
und der Grund gilt weiter.
WAS HIER RUEBERGEHT, IST DAS MINIMUM: Beginn und Dauer. Kein
Titel, keine Nummer, keine Person -- nicht einmal die Art. Man
kann daraus ablesen, DASS etwas ist, und nichts darueber, WAS.
NUR FUER DIE DOGFATHER-ROLLE, und das ist unveraendert sein Wort
vom 11.09.2026: „NUR IN DER DOGFATHER ROLLE BEI DOGFATHER: NICHT
BEI VANVAN." Die rechte Hand sieht von der anderen Seite nichts,
auch keine Bloecke.
UND ES SIND SEINE EIGENEN TERMINE, nicht alle des anderen
Hauses. `eigen` fragt dasselbe wie die Liste darueber: angelegt,
zugeordnet, Gegenueber oder Teilnehmer. Ein Kalender, der die
Verabredungen fremder Leute als „belegt" zeigt, waere
unbrauchbar -- und ein Leck obendrein. */
let belegt = [];
if (req.person.rolle === "admin"
&& (req.person.haus === "crew" || req.person.haus === "agentur")) {
/* ==== DAS GEGENSTUECK ZUR LISTE, NICHT EINE ZWEITE REGEL =======
Der erste Entwurf fragte `t.haus = <das andere>`. Das war eine
ZWEITE Vorstellung davon, was "die andere Seite" ist -- und
zwei Vorstellungen laufen auseinander. Gemessen ist genau das
sofort passiert: Termine ohne eingetragenes Haus (aus einem
Schreibweg, der es noch nicht setzt) wurden von der Liste
korrekt ueber die BETEILIGTEN getrennt, vom Block aber nicht
gefunden -- null Bloecke, und der Kalender waere wieder die
Falle vom 11.09. gewesen.
Jetzt steht hier die Rechnung: MEINE Termine MINUS die, die
dieses Haus zeigt. Was die Liste verbirgt, wird zum Block --
beides kann sich nicht mehr widersprechen, egal wie das Haus
einer Zeile bestimmt wird.
`haus: null` HOLT NUR DEN "EIGEN"-TEIL: termineSichtbar haengt
die Hausbedingung nur an, wenn ein Haus dasteht. So muss die
Frage "was sind meine Termine" nicht ein zweites Mal
formuliert werden. */
const SPALTEN_HAUS = ["creator_id", "teilnehmer_id", "erstellt_von"];
const meine = termineSichtbar({ ...req.person, haus: null }, "t");
const hierSichtbar = `${hausWo(req.person, "t")}`
+ ` AND ${ohneAnderesHaus("t", req.person, SPALTEN_HAUS)}`;
belegt = db().prepare(`
SELECT t.beginn, t.dauer_min
FROM termine t
WHERE (${meine.wo})
AND NOT (${hierSichtbar})
AND t.erledigt = 0
AND t.beginn >= ? AND t.beginn < ?
ORDER BY t.beginn`)
.all(...meine.werte, von, bis + "T23:59:59Z");
}
res.json({ termine, fristen, brettsachen, von, bis,
checkliste_moeglich: moeglich, belegt });
} catch (fehler) {
console.error("[workspace] Termine lesen:", fehler?.message);
res.status(503).json({ fehler: "nicht_verfuegbar" });
@@ -603,11 +669,12 @@ kalenderRouter.post("/workspace/api/termine", gleicheHerkunft, (req, res) => {
const { lastInsertRowid } = db().prepare(`
INSERT INTO termine
(titel, beschreibung, art, beginn, dauer_min, ort, creator_id, teilnehmer_id,
teilnehmer_extern, erledigt, erstellt, erstellt_von)
VALUES (?,?,?,?,?,?,?,?,?,0,?,?)`).run(
teilnehmer_extern, erledigt, erstellt, erstellt_von, haus)
VALUES (?,?,?,?,?,?,?,?,?,0,?,?,?)`).run(
aus.titel, aus.beschreibung ?? null, aus.art ?? "termin", aus.beginn,
aus.dauer_min ?? 30, aus.ort ?? null, aus.creator_id ?? null,
aus.teilnehmer_id ?? null, aus.teilnehmer_extern ?? null, jetzt(), req.person.id);
aus.teilnehmer_id ?? null, aus.teilnehmer_extern ?? null, jetzt(), req.person.id,
req.person.haus || null);
/* Die weiteren Teilnehmer. Das Haupt-Gegenueber kommt als `hauptId`
mit hinein, damit die Liste vollstaendig ist -- an ihr haengt die