/workspace/kalender.html -- letzter grosser Baustein aus Phase 1.
Zeigt zwei Quellen in EINER Ansicht, wie im Konzept gefordert
("Kalender & Calls" neben "Deadlines" und "Wiedervorlagen"):
* eigene Termine (Arten: Call, Termin, Review)
* Fristen offener Aufgaben, nur lesend eingeblendet
Nach Tagen gruppiert statt als Monatsraster: Es geht um wenige, dafuer
konkrete Termine. Eine Liste liest sich dabei besser und funktioniert auf
dem Handy ohne Umbau. Zeitraum umschaltbar: 14 / 30 / 90 Tage, wobei 90
den 90-Tage-Plan aus dem Konzept abdeckt.
Sichtbarkeit wie bei den Aufgaben, wieder an einer Stelle definiert.
Geprueft mit drei Konten:
Chef 2 Termine + 2 Fristen | Luna 2 + 1 | Sam 0 + 1
Die Fristen folgen dabei exakt der Aufgaben-Regel -- Sam sieht nur seine.
Loeschen darf das Management und wer den Termin selbst angelegt hat.
Sonst koennte ein Creator einen Call absagen, den das Management
angesetzt hat. Geprueft: Luna auf Chefs Call 403, auf ihren eigenen 200,
Sam sieht ihn gar nicht (404).
Weiteres:
- Ort/Link wird nur dann als Verweis dargestellt, wenn er wirklich mit
http(s) beginnt -- sonst liesse sich javascript: einschleusen
- Zeitpunkt und Dauer werden geprueft (kaputtes Datum 400,
5000 Minuten 400)
- Beginn steht als lokale Zeit ohne Zeitzone: Alle Beteiligten sitzen in
derselben, eine falsch umgerechnete Uhrzeit waere schlimmer als gar
keine Umrechnung
/workspace/profil.html -- Stammdaten, Ziele und 90-Tage-Plan, genau nach
Seite 5 des Konzepts. Management waehlt oben den Creator aus, ein Creator
sieht nur sein eigenes Profil.
Sicherheitskern ist das Feld admin_notiz. Das Konzept fordert "private
Admin-Notizen separat". Die Notiz wird deshalb nicht im Browser
ausgeblendet, sondern gar nicht erst gesendet: Die Spaltenliste der
Abfrage haengt an der Rolle (FELDER_OFFEN / FELDER_ADMIN). Dasselbe gilt
fuer Plan-Start und Review-Termin.
Geprueft:
- In der kompletten Rohantwort an den Creator kommt der Inhalt der
internen Notiz 0-mal vor
- Creator auf fremdes Profil: 404 (lesend wie schreibend)
- Scout auf ein Profil: 404, profil.html leitet ihn weg
- Creator setzt admin_notiz selbst: wird stillschweigend ignoriert,
der Inhalt bleibt unveraendert
- Profil einer Nicht-Creator-Person: 404
Dabei ist ein aelterer Fehler aufgefallen: /api/ich lieferte nur Name und
Rolle, nicht die eigene Nummer. Dadurch rief die Profilseite eines
Creators /api/profil/undefined auf und blieb leer. Derselbe Fehler machte
in der Personenverwaltung den Selbstvergleich unwirksam -- beim eigenen
Eintrag erschien ein "Sperren"-Knopf, den der Server dann ablehnte.
/api/ich liefert jetzt zusaetzlich die id.
Im Protokoll landen nur die Feldnamen, nie die Inhalte: Im Profil stehen
persoenliche Angaben, die nicht zusaetzlich im Audit-Log auftauchen
sollen.
Aufgaben:
- Bearbeiten-Dialog (Titel, Beschreibung, Prioritaet, Frist, Zuordnung).
Als natives <dialog>: Fokusfang, Esc zum Schliessen und Abdunklung
ohne eigenen Code.
- Loeschen nur fuer Management, mit Rueckfrage und Protokolleintrag.
Das Konzept will, dass Erledigtes stehen bleibt -- Loeschen ist der
Ausnahmefall fuer Fehleintraege, nicht der normale Abschluss.
Personen (/workspace/personen.html, nur Management):
- Anlegen, Code erneuern, sperren/entsperren, Protokollansicht
- Der Code wird genau einmal in der Antwort zurueckgegeben, nie
gespeichert; beim Schliessen auch aus dem Dokument entfernt
- Selbstschutz: niemand kann sich selbst sperren, und das letzte aktive
Management laesst sich nicht sperren -- sonst kaeme niemand mehr hinein
- Code fuer sich selbst tauschen nur mit ausdruecklicher Bestaetigung,
weil es die eigene Sitzung sofort beendet
Zwei Fehler, die beim Testen aufgefallen sind:
1. Rollenpruefung fehlte beim Ausliefern der Seiten. Ein Creator bekam
personen.html mit HTTP 200 -- die Schnittstellen wiesen ihn zwar ab,
das Geruest der Seite war aber sichtbar. GESCHUETZT ist jetzt eine
Zuordnung Pfad -> erlaubte Rollen statt einer blossen Liste.
2. Das Protokoll nannte den falschen Verursacher. personAnlegen trug die
NEU ANGELEGTE Person als person_id ein, der Eintrag las sich also so,
als haette sie sich selbst angelegt. Akteur und Betroffener sind jetzt
getrennt: Akteur in person_id, Betroffener im Text. Ueber die
Kommandozeile angelegte Personen zeigen korrekt keinen Akteur.
Erster echter Arbeitsbereich aus dem Konzept. Kanban mit offen / in
Arbeit / Review / erledigt, dazu Prioritaet, Frist, Verantwortlicher und
Zuordnung zu einem Creator-Bereich.
Kern ist die Datentrennung, und die sitzt AUSSCHLIESSLICH im Server --
in jeder einzelnen Abfrage, an einer Stelle definiert (sichtbar()):
admin sieht alles
creator sieht seinen Bereich und was ihm zugewiesen ist
scout sieht nur, was ihm zugewiesen ist
Geprueft mit vier Testkonten:
- Chef sieht 4, Luna 2, Mika 1, Sam 1 Aufgaben
- Luna auf Mikas Aufgabe: 404 (nicht 403 -- sonst liesse sich durch
Ausprobieren herausfinden, welche Nummern es gibt)
- Luna legt Aufgabe mit creator_id=Mika an: wird still auf ihren eigenen
Bereich umgebogen, Mika sieht sie nicht
- Anfrage mit fremdem Origin: 403
- ohne Anmeldung: 401, ungueltiger Status/leerer Titel: 400
- Scout bekommt in der Personenliste nur sich selbst
- Dashboard-Zahlen je Rolle korrekt eingegrenzt
Weitere Punkte:
- Texte werden im Browser nur ueber textContent gesetzt, nie innerHTML --
ein Aufgabentitel darf keine Auszeichnung einschleusen
- ueberfaellig = Frist vorbei UND nicht erledigt; die Kachel faerbt sich
nur, wenn wirklich etwas ansteht
- erledigt_am wird gesetzt bzw. wieder geleert, wenn eine Aufgabe
zurueckgeholt wird
- Erledigtes verschwindet nicht, wie im Konzept gefordert
Erster funktionierender Login fuer /workspace. Bewusst OHNE neue
Abhaengigkeiten: Node 24 bringt node:sqlite mit, Hashing und Zufall
kommen aus node:crypto. Nichts zu kompilieren, keine fremde Lieferkette
an einer Stelle, an der es um Zugangsdaten geht.
Sicherheit:
- Codes liegen nur als scrypt-Hash (N=32768) mit eigenem Salt in der DB
- Vergleich in konstanter Zeit (timingSafeEqual)
- Sitzungstoken 32 Byte Zufall, in der DB nur als SHA-256
- Cookie httpOnly, SameSite=lax, Path=/workspace, secure abhaengig von
req.secure (live immer an, nur der lokale http-Test kommt ohne aus)
- Sperre nach 8 Fehlversuchen je IP fuer 10 Minuten -- danach ist auch
der richtige Code blockiert (geprueft)
- gleiche Fehlermeldung bei falscher Rolle und falschem Code
- Audit-Log fuer Anmeldung, Fehlversuch, Sperre, Abmeldung, Codewechsel
Die Datenbank liegt AUSSERHALB des Repos (../workspace-daten/): sonst
waere sie ueber express.static aus dem Netz erreichbar, und ein git pull
wuerde Nutzdaten anfassen.
workspace.js kann die Website nicht mitreissen: node:sqlite wird erst bei
Bedarf per createRequire geladen, jede Route faengt ihre Fehler selbst ab.
Faellt die DB aus, antwortet nur /workspace/api/* mit 503.
Codes werden ausschliesslich auf der Kommandozeile erzeugt
(server/workspace-code.js) und dort einmal angezeigt -- nie in Git.
Ausserdem: start.html als geschuetzte Seite nach dem Anmelden. Der Schutz
sitzt serverseitig vor express.static, nicht nur im Browser.
Erstes sichtbares Stueck des Creator-Workspace-Konzepts. Reine statische
Dateien in einem neuen Ordner workspace/ -- express.static liefert den
Repo-Ordner aus, die Seite ist damit ohne Servercode-Aenderung und ohne
Neustart unter /workspace/ erreichbar. Rein additiv: an bestehenden
Dateien wurde nichts geaendert.
Motiv: Dogfather und Hasi Dog stehen rechts im Bild, deshalb liegt die
Code-Tafel links ueber der ruhigen Flaeche (bei VanVans Buchhaltung ist es
gespiegelt, weil dort das Emblem links steht). Drei Layoutfaelle, damit die
Figuren in keiner Fenstergroesse von der Tafel ueberdeckt werden.
Bewusst nur WebP, kein AVIF: send 0.19.2 (Express 4) kennt AVIF nicht und
liefert es als application/octet-stream aus -- wegen des nosniff-Headers
verweigert der Browser das Bild dann komplett. Lokal gegen den echten
Express-Server geprueft: 0 Konsolenfehler, 0 CSP-Verstoesse.
Anmelden funktioniert noch nicht (kein Endpunkt); das Formular sagt das
jetzt ehrlich statt "Code stimmt nicht".