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
+42 -8
View File
@@ -45,7 +45,7 @@ import { mkdirSync, writeFileSync, createReadStream, statSync, unlinkSync,
import {
db, protokolliere, echteIp, sitzungLesen, istDogFather,
schreibbareIds, darfSchreibenMit, ROLLEN_SORTIERUNG, DATEN_ORDNER,
fuehrtTeamDogi, MODI_KATEGORIEN, ROLLEN_GRUPPE, TEAM_DOGI_ROLLEN,
fuehrtTeamDogi, MODI_KATEGORIEN, ROLLEN_GRUPPE, TEAM_DOGI_ROLLEN, hausWo,
istTeamDogi,
} from "./workspace.js";
@@ -511,9 +511,14 @@ function teilnehmerVon(raumId) {
* Spalte wäre eine zweite Wahrheit neben chat_teilnehmer. */
function direktRaum(personA, idB, { anlegen = true } = {}) {
const d = db();
/* GESUCHT WIRD NUR IM EIGENEN HAUS (24.09.2026). Ohne das faende
DogFather auf der Team-Adresse sein Agentur-Gespraech mit
derselben Person wieder -- und schriebe hinein, ohne es zu
merken. Zwei Haeuser heisst: notfalls zwei Gespraeche. */
const vorhanden = d.prepare(`
SELECT r.id FROM chat_raeume r
WHERE r.art = 'direkt'
AND ${hausWo(personA, "r")}
AND EXISTS (SELECT 1 FROM chat_teilnehmer t WHERE t.raum_id = r.id AND t.person_id = ?)
AND EXISTS (SELECT 1 FROM chat_teilnehmer t WHERE t.raum_id = r.id AND t.person_id = ?)
AND (SELECT COUNT(*) FROM chat_teilnehmer t WHERE t.raum_id = r.id) = 2`)
@@ -522,8 +527,13 @@ function direktRaum(personA, idB, { anlegen = true } = {}) {
if (!anlegen) return null;
const n = jetzt();
d.prepare("INSERT INTO chat_raeume (art, erstellt, erstellt_von, letzte_am) VALUES ('direkt',?,?,NULL)")
.run(n, personA.id);
/* DAS HAUS WIRD BEIM ANLEGEN GESCHRIEBEN, nicht spaeter gerechnet.
`personA.haus` kommt aus der Adresse, auf der gerade gearbeitet
wird -- die einzige Auskunft, die auch dann stimmt, wenn der Raum
noch leer ist. */
d.prepare("INSERT INTO chat_raeume (art, erstellt, erstellt_von, letzte_am, haus)"
+ " VALUES ('direkt',?,?,NULL,?)")
.run(n, personA.id, personA.haus || null);
const raumId = d.prepare("SELECT last_insert_rowid() AS id").get().id;
const rein = d.prepare(
"INSERT INTO chat_teilnehmer (raum_id, person_id, seit, gelesen_bis) VALUES (?,?,?,0)");
@@ -1081,12 +1091,30 @@ chatRouter.get("/workspace/api/chat/raeume", (req, res) => {
Chat stehen, ohne dass jemand daran denken muss. */
if (gehoertInTreff(req.person)) treffAngleichen();
/* ==== NUR DIE RAEUME DIESES HAUSES (24.09.2026) ================
Filipe: „die seiten soll nicht mehr im chat kalender und alles
andere verbunden sein."
DIESE LISTE HATTE KEINEN HAUS-FILTER, und das fiel nur bei einem
einzigen Menschen auf: DogFather. Alle anderen sehen ohnehin nur
Raeume, in denen sie sitzen, und sie sitzen nur in denen ihres
Hauses. Er sitzt in beiden -- gemessen am echten Stand standen
auf der Team-Adresse in seiner Gespraechsliste auch seine zwei
Zweier-Gespraeche mit Scouts.
UEBER DIE SPALTE UND NICHT UEBER DIE TEILNEHMER: Ein Raum, in
dem nur DogFather sitzt (er legt einen Kanal an, es ist noch
niemand drin), haette ueber die Teilnehmer keinen Beleg und
stuende in beiden Haeusern. Die Spalte weiss, wo er ihn
angelegt hat. */
const reihen = db().prepare(`
SELECT r.id, r.art, r.name, r.kategorie, r.letzte_am, r.erstellt_von,
t.gelesen_bis, t.leitung, t.geloescht_bis
FROM chat_raeume r
JOIN chat_teilnehmer t ON t.raum_id = r.id AND t.person_id = ?
WHERE t.raus_am IS NULL
AND ${hausWo(req.person, "r")}
AND (t.geloescht_am IS NULL
OR EXISTS (SELECT 1 FROM chat_nachrichten n
WHERE n.raum_id = r.id AND n.id > t.geloescht_bis))
@@ -1265,8 +1293,13 @@ chatRouter.post("/workspace/api/chat/gruppe", gleicheHerkunft, express.json({ li
const d = db();
const n = jetzt();
d.prepare("INSERT INTO chat_raeume (art, name, erstellt, erstellt_von) VALUES ('gruppe',?,?,?)")
.run(name, n, req.person.id);
/* Auch die Gruppe merkt sich ihr Haus (24.09.2026). Sie hat beim
Anlegen genau EIN Mitglied -- den, der sie anlegt. Ueber die
Beteiligten waere sie also gar nicht einzuordnen, solange
DogFather sie anlegt und noch niemand dazugekommen ist. */
d.prepare("INSERT INTO chat_raeume (art, name, erstellt, erstellt_von, haus)"
+ " VALUES ('gruppe',?,?,?,?)")
.run(name, n, req.person.id, req.person.haus || null);
const raumId = d.prepare("SELECT last_insert_rowid() AS id").get().id;
d.prepare("INSERT INTO chat_teilnehmer (raum_id, person_id, seit, gelesen_bis, leitung) VALUES (?,?,?,0,1)")
.run(raumId, req.person.id, n);
@@ -1403,12 +1436,13 @@ chatRouter.post("/workspace/api/chat/kanal", gleicheHerkunft, express.json({ lim
}
const n = jetzt();
d.prepare(`INSERT INTO chat_raeume (art, name, kategorie, erstellt, erstellt_von)
VALUES ('kanal',?,?,?,?)`)
d.prepare(`INSERT INTO chat_raeume (art, name, kategorie, erstellt, erstellt_von, haus)
VALUES ('kanal',?,?,?,?,?)`)
/* Der eigene Name geht in die Spalte, der feste kommt aus
MODI_KATEGORIEN. Beides landet in derselben Spalte -- die
Zeile im Chat liest nur noch dort nach. */
.run(anzeigeName || kanalName(schluessel), schluessel, n, req.person.id);
.run(anzeigeName || kanalName(schluessel), schluessel, n, req.person.id,
req.person.haus || null);
const raumId = d.prepare("SELECT last_insert_rowid() AS id").get().id;
/* DIE GANZE TEAMFUEHRUNG KOMMT HINEIN, nicht nur der Anlegende.