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.
This commit is contained in:
@@ -129,7 +129,7 @@ function nameAusKopf(req) {
|
||||
function darfHochladen(req, res, next) {
|
||||
if (!DARF_HOCHLADEN.has(req.person.rolle)) {
|
||||
return res.status(403).json({
|
||||
fehler: "Dateien legen das Management und die Scouts ab.",
|
||||
fehler: "Dateien legen DogFather und die Scouts ab.",
|
||||
});
|
||||
}
|
||||
next();
|
||||
@@ -263,10 +263,10 @@ dateienRouter.patch("/workspace/api/dateien/:id", gleicheHerkunft, (req, res) =>
|
||||
/* "freigegeben" ist eine Abnahme -- die trifft laut Konzept das
|
||||
Management, nicht der, der die Datei hochgeladen hat. */
|
||||
if (req.body.status === "freigegeben" && req.person.rolle !== "admin") {
|
||||
return res.status(403).json({ fehler: "Freigeben darf nur das Management." });
|
||||
return res.status(403).json({ fehler: "Freigeben darf nur DogFather." });
|
||||
}
|
||||
if (datei.status === "freigegeben" && req.person.rolle !== "admin") {
|
||||
return res.status(403).json({ fehler: "Freigegebene Dateien ändert nur das Management." });
|
||||
return res.status(403).json({ fehler: "Freigegebene Dateien ändert nur DogFather." });
|
||||
}
|
||||
setz.push("status = ?"); daten.push(req.body.status);
|
||||
}
|
||||
@@ -309,7 +309,7 @@ dateienRouter.delete("/workspace/api/dateien/:id", gleicheHerkunft, (req, res) =
|
||||
return res.status(403).json({ fehler: "nicht_erlaubt" });
|
||||
}
|
||||
if (datei.status === "freigegeben") {
|
||||
return res.status(403).json({ fehler: "Freigegebene Dateien löscht nur das Management." });
|
||||
return res.status(403).json({ fehler: "Freigegebene Dateien löscht nur DogFather." });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ personenRouter.patch("/workspace/api/verwaltung/personen/:id", gleicheHerkunft,
|
||||
if (!aktiv && person.rolle === "admin") {
|
||||
const { n } = db().prepare(
|
||||
"SELECT COUNT(*) AS n FROM personen WHERE rolle = 'admin' AND aktiv = 1").get();
|
||||
if (n <= 1) return res.status(400).json({ fehler: "Das ist das letzte aktive Management." });
|
||||
if (n <= 1) return res.status(400).json({ fehler: "Das ist der letzte aktive DogFather-Zugang." });
|
||||
}
|
||||
personSperren(id, aktiv, { ...req.person, ip: echteIp(req) });
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ scoutRouter.delete("/workspace/api/leads/:id", gleicheHerkunft, (req, res) => {
|
||||
/* Ein übergebener Lead ist Teil der Betreuungsgeschichte -- den
|
||||
räumt nur das Management weg. */
|
||||
if (req.person.rolle !== "admin" && lead.status === "uebergeben") {
|
||||
return res.status(403).json({ fehler: "Übergebene Leads löscht nur das Management." });
|
||||
return res.status(403).json({ fehler: "Übergebene Leads löscht nur DogFather." });
|
||||
}
|
||||
db().prepare("DELETE FROM leads WHERE id = ?").run(id);
|
||||
protokolliere("lead_geloescht", {
|
||||
|
||||
+19
-1
@@ -54,6 +54,21 @@ const VERSUCHE_MAX = 8; // pro IP
|
||||
const VERSUCHE_FENSTER_MIN = 10;
|
||||
const ROLLEN = new Set(["admin", "creator", "scout"]);
|
||||
|
||||
/* Der Rollenschluessel bleibt "admin" -- er steckt in der CHECK-Regel der
|
||||
Datenbank, in jeder Sitzung und in jeder Rechteabfrage. Umbenannt wird
|
||||
nur, was man LIEST. Diese Zuordnung ist die einzige Stelle dafuer:
|
||||
Stand der Anzeigename in elf Dateien, waere er beim naechsten Mal in
|
||||
zehn davon geaendert.
|
||||
|
||||
Hinweis fuer spaeter: In den Kommentaren der Fachmodule heisst die
|
||||
Rolle "admin" weiterhin "das Management". Gemeint ist dieselbe Rolle,
|
||||
die in der Oberflaeche "DogFather" heisst. */
|
||||
export const ROLLEN_NAME = {
|
||||
admin: "DogFather",
|
||||
creator: "Creator",
|
||||
scout: "Scout",
|
||||
};
|
||||
|
||||
/* scrypt-Parameter. N=2^15 braucht auf diesem Server rund 150 ms — spürbar
|
||||
genug, um Rateversuche auszubremsen, und unauffällig für einen echten
|
||||
Anmeldevorgang. Die Werte werden je Datensatz mitgespeichert, damit sie
|
||||
@@ -529,7 +544,10 @@ workspaceRouter.get("/workspace/api/ich", (req, res) => {
|
||||
erkennen, welcher Eintrag der eigene ist (etwa "das bin ich" in der
|
||||
Personenliste), und das eigene Profil liesse sich gar nicht aufrufen.
|
||||
Ein Geheimnis ist sie nicht -- sie beschreibt nur den Angemeldeten. */
|
||||
res.json({ id: person.id, name: person.name, rolle: person.rolle });
|
||||
res.json({
|
||||
id: person.id, name: person.name, rolle: person.rolle,
|
||||
rolle_name: ROLLEN_NAME[person.rolle] ?? person.rolle,
|
||||
});
|
||||
});
|
||||
|
||||
/* ---------- Verwaltung (nur über die Kommandozeile) --------------------
|
||||
|
||||
@@ -260,7 +260,7 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe
|
||||
ich = await antwort.json();
|
||||
} catch { return; }
|
||||
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle}`;
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle_name || ich.rolle}`;
|
||||
|
||||
if (ich.rolle === 'admin') {
|
||||
$('feld-creator').hidden = false;
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
let daten;
|
||||
try {
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
await laden();
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
/* Creator laden nichts hoch (Wunsch 28.08.2026). Das Ablegefeld
|
||||
verschwindet, stattdessen steht dort, warum -- ein einfach
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
const knopf = $('knopf');
|
||||
const fuer = $('fuer');
|
||||
|
||||
const NAMEN = { admin: 'Management', creator: 'Creator', scout: 'Scout' };
|
||||
const NAMEN = { admin: 'DogFather', creator: 'Creator', scout: 'Scout' };
|
||||
const SPEICHER = 'dfw.rolle';
|
||||
let gewaehlt = null;
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
if (ich.rolle === 'admin') {
|
||||
$('feld-teilnehmer').hidden = false;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* ===================================================================
|
||||
Personen und Zugangscodes verwalten. Nur für Management -- der Server
|
||||
Personen und Zugangscodes verwalten. Nur für DogFather -- der Server
|
||||
liefert allen anderen ohnehin 404 auf diese Schnittstellen.
|
||||
=================================================================== */
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const ROLLENNAME = { admin: 'Management', creator: 'Creator', scout: 'Scout' };
|
||||
const ROLLENNAME = { admin: 'DogFather', creator: 'Creator', scout: 'Scout' };
|
||||
let ich = null;
|
||||
|
||||
const el = (tag, klasse, text) => {
|
||||
@@ -88,7 +88,7 @@
|
||||
const w = el('select', 'betreuung__wahl');
|
||||
w.id = 'betreuer-' + p.id;
|
||||
const leer = document.createElement('option');
|
||||
leer.value = ''; leer.textContent = 'nur Management';
|
||||
leer.value = ''; leer.textContent = 'nur DogFather';
|
||||
w.append(leer);
|
||||
for (const s2 of betreuerListe) {
|
||||
const o = document.createElement('option');
|
||||
@@ -230,7 +230,7 @@
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
if (ich.rolle !== 'admin') { location.assign('/workspace/start.html'); return; }
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle}`;
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle_name || ich.rolle}`;
|
||||
await laden();
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -97,9 +97,9 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
/* Scouts betreuen ihre zugeteilten Creator wie das Management --
|
||||
/* Scouts betreuen ihre zugeteilten Creator wie DogFather --
|
||||
sie sehen aber nur die management-internen Felder nicht. */
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
let liste;
|
||||
try { liste = await (await hole('/workspace/api/profil')).json(); } catch { return; }
|
||||
@@ -107,7 +107,7 @@
|
||||
if (ich.rolle === 'admin' || ich.rolle === 'scout') {
|
||||
if (!liste.creator.length) {
|
||||
$('unterzeile').textContent = ich.rolle === 'scout'
|
||||
? 'Dir ist noch kein Creator zugeteilt. Das Management legt fest, wen du betreust.'
|
||||
? 'Dir ist noch kein Creator zugeteilt. DogFather legt fest, wen du betreust.'
|
||||
: 'Es gibt noch keinen Creator. Lege zuerst unter Personen & Zugänge einen an.';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
try {
|
||||
const { creator } = await (await hole('/workspace/api/report/creator')).json();
|
||||
@@ -214,7 +214,7 @@
|
||||
fuer ihn nicht, das waere die Gesamtuebersicht. */
|
||||
if (!creator.length) {
|
||||
$('unterzeile').textContent =
|
||||
'Dir ist noch kein Creator zugeteilt. Das Management legt fest, wen du betreust.';
|
||||
'Dir ist noch kein Creator zugeteilt. DogFather legt fest, wen du betreust.';
|
||||
return;
|
||||
}
|
||||
$('creator-block').hidden = false;
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
if (ich.rolle === 'creator') { location.assign('/workspace/start.html'); return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
if (ich.rolle === 'admin') {
|
||||
$('unterzeile').textContent = 'Gesamtübersicht über alle Scouts.';
|
||||
@@ -358,7 +358,7 @@
|
||||
} catch { return; }
|
||||
$('f-scout').addEventListener('change', zeichne);
|
||||
} else {
|
||||
$('unterzeile').textContent = 'Deine Pipeline – nur du und das Management sehen sie.';
|
||||
$('unterzeile').textContent = 'Deine Pipeline – nur du und DogFather sehen sie.';
|
||||
}
|
||||
|
||||
await laden();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
const ROLLENTEXT = {
|
||||
admin: 'Management · Gesamtübersicht und Freigaben',
|
||||
admin: 'DogFather · Gesamtübersicht und Freigaben',
|
||||
creator: 'Creator · dein eigener Bereich',
|
||||
scout: 'Scout · deine Pipeline und die Creator, die du betreust',
|
||||
};
|
||||
@@ -48,7 +48,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle}`;
|
||||
$('wer').textContent = `${ich.name} · ${ich.rolle_name || ich.rolle}`;
|
||||
$('gruss').textContent = `Willkommen, ${ich.name}`;
|
||||
$('rollentext').textContent = ROLLENTEXT[ich.rolle] || ich.rolle;
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
if (!a.ok) { location.assign('/workspace/'); return; }
|
||||
ich = await a.json();
|
||||
} catch { return; }
|
||||
$('wer').textContent = ich.name + ' · ' + ich.rolle;
|
||||
$('wer').textContent = ich.name + ' · ' + (ich.rolle_name || ich.rolle);
|
||||
|
||||
let liste;
|
||||
try { liste = await (await hole('/workspace/api/startcheck/creator')).json(); } catch { return; }
|
||||
@@ -262,7 +262,7 @@
|
||||
if (!liste.creator.length) {
|
||||
$('felder').textContent = '';
|
||||
$('felder').append(el('p', 'leer-hinweis', ich.rolle === 'scout'
|
||||
? 'Dir ist noch kein Creator zugeteilt. Das Management legt fest, wen du betreust.'
|
||||
? 'Dir ist noch kein Creator zugeteilt. DogFather legt fest, wen du betreust.'
|
||||
: 'Es gibt noch keinen Creator.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
Feld wirkt wie ein Fehler. -->
|
||||
<p class="nur-lesen" id="nur-lesen" hidden>
|
||||
Hier siehst du die Dateien deines Bereichs. <strong>Abgelegt werden sie
|
||||
vom Management oder von Scouts</strong> – du kannst sie öffnen, aber nichts hochladen.
|
||||
von DogFather oder von Scouts</strong> – du kannst sie öffnen, aber nichts hochladen.
|
||||
</p>
|
||||
|
||||
<!-- Ablegefeld. Klick öffnet die Dateiauswahl, Ziehen funktioniert
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<title>Dogfather Universe · Creator Workspace · Anmeldung</title>
|
||||
<meta name="description" content="Privater Arbeitsbereich für Creator, Scouts und Management." />
|
||||
<meta name="description" content="Privater Arbeitsbereich für Creator, Scouts und DogFather." />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
|
||||
@@ -53,13 +53,13 @@
|
||||
<header class="kopf">
|
||||
<p class="marke">Dogfather Universe</p>
|
||||
<h1 class="titel">Creator Workspace</h1>
|
||||
<p class="unterzeile">Privater Bereich für Creator, Scouts und Management.</p>
|
||||
<p class="unterzeile">Privater Bereich für Creator, Scouts und DogFather.</p>
|
||||
</header>
|
||||
|
||||
<div class="rollen" role="radiogroup" aria-labelledby="rollen-schild">
|
||||
<p class="feldschild" id="rollen-schild">Womit meldest du dich an?</p>
|
||||
|
||||
<!-- Krone für das Management: steht für die Gesamtübersicht und die
|
||||
<!-- Krone für DogFather: steht für die Gesamtübersicht und die
|
||||
Freigaben. Das Schild ist zum Scout gewandert -- dort passt es
|
||||
besser, weil ein Scout die Pipeline abschirmt und prüft, bevor
|
||||
etwas weitergereicht wird. -->
|
||||
@@ -69,7 +69,7 @@
|
||||
<path d="M6 20.1h12"/>
|
||||
</svg>
|
||||
<span class="rolle__text">
|
||||
<span class="rolle__name">Management</span>
|
||||
<span class="rolle__name">DogFather</span>
|
||||
<span class="rolle__zusatz">Gesamtübersicht & Freigaben</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<select id="f-rolle" name="rolle">
|
||||
<option value="creator" selected>Creator</option>
|
||||
<option value="scout">Scout</option>
|
||||
<option value="admin">Management</option>
|
||||
<option value="admin">DogFather</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -108,12 +108,12 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Nur fürs Management. Der Server schickt dieses Feld an Creator
|
||||
<!-- Nur für DogFather. Der Server schickt dieses Feld an Creator
|
||||
gar nicht erst mit. -->
|
||||
<fieldset class="gruppe gruppe--intern" id="gruppe-intern" hidden>
|
||||
<legend class="gruppe__titel">Interne Notiz</legend>
|
||||
<p class="gruppe__text">
|
||||
Sieht <strong>nur das Management</strong>. Der Creator bekommt dieses Feld
|
||||
Sieht <strong>nur DogFather</strong>. Der Creator bekommt dieses Feld
|
||||
weder angezeigt noch übertragen.
|
||||
</p>
|
||||
<textarea id="admin_notiz" rows="4" maxlength="2000"></textarea>
|
||||
|
||||
Reference in New Issue
Block a user