Workspace: Kalender mit Terminen, Calls und Aufgaben-Fristen

/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
This commit is contained in:
2026-08-28 00:24:12 +02:00
parent a378b126fe
commit ef79659f8f
7 changed files with 714 additions and 1 deletions
+23
View File
@@ -149,6 +149,28 @@ export function db() {
geaendert_von INTEGER REFERENCES personen(id) ON DELETE SET NULL
);
/* Termine, Calls und Reviews. Der Beginn steht als lokale Zeit
(JJJJ-MM-TTThh:mm) -- genau so, wie ein datetime-local-Feld sie
liefert. Bewusst ohne Zeitzone: Alle Beteiligten sitzen in
derselben, und eine falsch umgerechnete Uhrzeit waere schlimmer
als gar keine Umrechnung. */
CREATE TABLE IF NOT EXISTS termine (
id INTEGER PRIMARY KEY AUTOINCREMENT,
titel TEXT NOT NULL,
beschreibung TEXT,
art TEXT NOT NULL DEFAULT 'termin'
CHECK (art IN ('termin','call','review')),
beginn TEXT NOT NULL,
dauer_min INTEGER NOT NULL DEFAULT 30,
ort TEXT,
creator_id INTEGER REFERENCES personen(id) ON DELETE SET NULL,
teilnehmer_id INTEGER REFERENCES personen(id) ON DELETE SET NULL,
erledigt INTEGER NOT NULL DEFAULT 0,
erstellt TEXT NOT NULL,
erstellt_von INTEGER REFERENCES personen(id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_termine_beginn ON termine (beginn);
CREATE TABLE IF NOT EXISTS versuche (
ip TEXT NOT NULL,
zeitpunkt TEXT NOT NULL
@@ -282,6 +304,7 @@ const GESCHUETZT = {
"/workspace/aufgaben.html": null,
"/workspace/personen.html": ["admin"],
"/workspace/profil.html": ["admin", "creator"],
"/workspace/kalender.html": null,
};
workspaceRouter.use((req, res, next) => {