Schul-Alltag Module — Konzept
Fuenf Module die den taeglichen Schulbetrieb digitalisieren. Alle fuenf teilen sich ein gemeinsames Datenmodell und nutzen die bestehende Prilog-Infrastruktur (Spaces, Chat, Kalender, SSE, n8n-Trigger).
Designprinzip: Jedes Feature lebt IN einem Space. Ein Space ist nicht nur ein Chatroom — er ist die digitale Entsprechung einer Schulklasse, eines Teams, einer AG. Alles was in dieser Gruppe passiert (Chat, Aufgaben, Briefe, Abwesenheiten, Umfragen) gehoert in denselben Space.
Architektur-Ueberblick
┌──────────────────────────────────────────────────────────┐
│ Space "Klasse 4b" │
│ │
│ ┌─────┐ ┌────────┐ ┌──────────┐ ┌─────────────────┐ │
│ │Chat │ │Aufgaben│ │ Kalender │ │ Dateien (DMS) │ │
│ └─────┘ └────────┘ └──────────┘ └─────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────┐ ┌────────────────────┐ │
│ │Elternbriefe │ │Umfragen │ │ Mitteilungsheft │ │
│ │& Formulare │ │ │ │ (pro Schueler) │ │
│ └──────────────┘ └──────────┘ └────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Abwesenheiten │ │
│ │ (Space-uebergreifend, aber pro Space filterbar) │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘Gemeinsames Datenmodell
Alle fuenf Features nutzen eine zentrale SpacePost-Tabelle als Grundlage. Ein SpacePost ist eine strukturierte Nachricht in einem Space — kein Chat-Bubble, sondern ein formales Objekt mit Typ, Antwortoptionen und Tracking.
SpacePost
├── id, spaceId, tenantId
├── type: 'letter' | 'poll' | 'form' | 'note' | 'absence'
├── title, body (Markdown)
├── authorId
├── visibility: 'all' | 'parents' | 'staff' | 'students'
├── responseType: 'none' | 'acknowledge' | 'yes_no' | 'choice' | 'form_fields'
├── responseDeadline (optional)
├── reminderSent: boolean
├── pinned: boolean
├── attachments: FileItem[]
├── createdAt, updatedAt
│
├── SpacePostResponse[] (Antworten/Rueckmeldungen)
│ ├── id, postId, userId
│ ├── response: 'yes' | 'no' | 'acknowledged' | JSON (Formular-Felder)
│ ├── comment (optionaler Freitext)
│ ├── createdAt
│
├── SpacePostReminder[] (automatische Erinnerungen)
│ ├── id, postId, sentAt, targetCount, respondedCount
│
└── AbsenceEntry[] (nur fuer type='absence')
├── id, postId, studentUserId, spaceId, tenantId
├── date, endDate (Zeitraum)
├── reason: 'sick' | 'family' | 'appointment' | 'other'
├── reportedBy (Eltern-UserId)
├── attestRequired: boolean (auto ab Tag 3)
├── attestReceived: boolean
├── acknowledgedBy (Lehrer-UserId)
├── createdAt1. Elternbriefe mit Rueckmeldung
User-Flow: Lehrer
Lehrer oeffnet Space "Klasse 4b" → Tab "Briefe & Umfragen"
│
├── Klick "Neuer Brief"
│
├── Formular:
│ ├── Titel: "Wandertag am 15. Mai"
│ ├── Text: (Markdown-Editor, wie Chat aber laenger)
│ ├── Anhang: Routenplan.pdf (optional)
│ ├── Rueckmeldung: [Keine | Kenntnisnahme | Ja/Nein | Auswahl]
│ ├── Frist: 10. Mai (optional)
│ └── Sichtbarkeit: Nur Eltern
│
├── Klick "Senden"
│
└── Brief erscheint im Space als Karte (nicht als Chat-Nachricht)
├── Eltern sehen ihn im Feed + als Badge
├── Status-Balken: "18 von 24 beantwortet"
└── Lehrer kann Erinnerung an fehlende sendenUser-Flow: Eltern
Eltern oeffnen Space "Klasse 4b" → sehen Brief-Karte oben angepinnt
│
├── Klick auf Brief → Detail-Ansicht
│ ├── Titel + Text + Anhang
│ ├── Antwort-Buttons: [Ja, mein Kind nimmt teil] [Nein]
│ ├── Optionaler Kommentar: "Leon braucht Wanderschuhe"
│ └── Klick "Absenden"
│
└── Bestaetigung: "Ihre Rueckmeldung wurde gespeichert"Lehrer-Dashboard: Rueckmeldungsuebersicht
┌─────────────────────────────────────────────────────┐
│ Wandertag am 15. Mai Frist: 10. Mai │
│ ████████████████████░░░░░ 18/24 (75%) │
│ │
│ ✓ Ja (teilnehmen): 16 │
│ ✗ Nein: 2 │
│ ○ Ausstehend: 6 │
│ │
│ Ausstehend: │
│ Familie Weber, Familie Schmidt, Familie Klein, │
│ Familie Braun, Familie Hoffmann, Familie Lang │
│ │
│ [Erinnerung senden] [Als PDF exportieren] │
└─────────────────────────────────────────────────────┘Automatische Erinnerung
- Cron-Job prueft taeglich Posts mit
responseDeadline - 3 Tage vor Frist: Erinnerungs-Nachricht im Chat an alle die noch nicht geantwortet haben
- Am Tag der Frist: letzte Erinnerung
- Erinnerung kommt als System-Nachricht im Space-Chat: "Erinnerung: Bitte geben Sie Ihre Rueckmeldung zum Wandertag ab (Frist: 10. Mai)"
2. Schnelle Umfragen / Abstimmungen
Konzept
Umfragen sind SpacePosts mit type: 'poll' und responseType: 'choice'. Die Optionen werden als JSON im Post gespeichert.
SpacePost (type: 'poll')
├── title: "Wann passt der Elternabend?"
├── body: "Bitte waehlen Sie einen Termin."
├── config: {
│ options: ["Dienstag 18:00", "Mittwoch 19:00", "Donnerstag 18:30"],
│ multiSelect: false,
│ anonymous: false,
│ showResultsBeforeVote: false,
│ }
├── responseDeadline: "2026-05-10"
└── SpacePostResponse[]
└── response: { choice: "Dienstag 18:00" }User-Flow: Erstellen
Lehrer → Space → Tab "Briefe & Umfragen" → "Neue Umfrage"
│
├── Frage: "Wann passt der Elternabend?"
├── Optionen: [+ Option hinzufuegen]
│ ├── "Dienstag 18:00"
│ ├── "Mittwoch 19:00"
│ └── "Donnerstag 18:30"
├── Mehrfachauswahl: [Ja / Nein]
├── Anonym: [Ja / Nein]
├── Ergebnis vor Abstimmung zeigen: [Ja / Nein]
├── Frist: (optional)
└── [Umfrage starten]Ergebnis-Ansicht (Live-Update via SSE)
┌─────────────────────────────────────────────┐
│ Wann passt der Elternabend? │
│ │
│ Dienstag 18:00 ████████████░░ 12 (50%) │
│ Mittwoch 19:00 ██████░░░░░░░░ 6 (25%) │
│ Donnerstag 18:30 ██████░░░░░░░░ 6 (25%) │
│ │
│ 24 von 24 haben abgestimmt │
│ │
│ [Umfrage schliessen] │
└─────────────────────────────────────────────┘Sonderfall: Ja/Nein-Schnellumfrage
Fuer die haeufigste Variante ("Kommt Ihr Kind zum Schulfest?") gibt es einen Shortcut: responseType: 'yes_no' braucht keine Optionen. Zwei grosse Buttons: Ja / Nein.
3. Abwesenheiten / Krankmeldungen
Konzept
Abwesenheiten sind das einzige Feature das Space-uebergreifend funktioniert. Ein Schueler kann in mehreren Spaces sein (Klasse, AG, Foerderunterricht). Eine Krankmeldung gilt fuer alle.
Die Abwesenheit wird von den Eltern gemeldet und ist an den Schueler gebunden (nicht an einen Space). Lehrer sehen sie gefiltert nach ihren Spaces.
Datenmodell
AbsenceEntry
├── id
├── tenantId
├── studentUserId -- der abwesende Schueler (Matrix-User-ID)
├── studentName -- Anzeigename (denormalisiert fuer Performance)
├── date -- Ab-Datum
├── endDate -- Bis-Datum (null = nur heute)
├── reason -- 'sick' | 'family' | 'appointment' | 'other'
├── reasonText -- optionaler Freitext ("Zahnarzt um 10 Uhr")
├── reportedBy -- Eltern-User-ID
├── reportedAt
├── attestRequired -- automatisch true wenn Dauer >= 3 Tage
├── attestReceived -- Lehrer setzt auf true
├── attestFileId -- optionaler Datei-Anhang (Attest-Scan)
├── acknowledgedBy -- Lehrer-User-ID (hat zur Kenntnis genommen)
├── acknowledgedAt
├── status -- 'reported' | 'acknowledged' | 'excused' | 'unexcused'
├── createdAt, updatedAt
Index: (tenantId, date), (studentUserId, date)User-Flow: Eltern melden Abwesenheit
Eltern oeffnen Prilog → oben rechts: grosser roter Button
"Kind abwesend melden"
│
├── Kind auswaehlen (falls mehrere Kinder)
│ └── Leon Mueller (Klasse 4b)
│
├── Zeitraum:
│ ├── [Nur heute]
│ ├── [Mehrere Tage] → Datepicker: Von ___ Bis ___
│
├── Grund:
│ ├── [Krank]
│ ├── [Familiär]
│ ├── [Arzttermin]
│ └── [Sonstiges] → Freitext
│
└── [Abwesenheit melden]
└── Bestaetigung: "Abwesenheit fuer Leon am 19.04. gemeldet.
Die Klassenlehrerin wird benachrichtigt."User-Flow: Lehrer — Morgen-Uebersicht
Lehrer oeffnet Space "Klasse 4b" → Tab "Anwesenheit"
┌─────────────────────────────────────────────────────┐
│ Heute: Montag, 19. April 2026 │
│ │
│ ● Anwesend: 22 ○ Abwesend: 2 ? Unbekannt: 0 │
│ │
│ Abwesend: │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🔴 Leon Mueller Krank seit heute │ │
│ │ Gemeldet von: Frau Mueller, 07:12 │ │
│ │ [Zur Kenntnis nehmen] │ │
│ ├────────────────────────────────────────────────┤ │
│ │ 🟡 Mia Schmidt Arzttermin nur heute │ │
│ │ Gemeldet von: Herr Schmidt, 07:45 │ │
│ │ Anmerkung: "Ab 11 Uhr wieder da" │ │
│ │ [Zur Kenntnis nehmen] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Langzeit-Abwesenheiten: │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🔴 Tim Weber Krank 15.04. - 22.04. │ │
│ │ ⚠ Attest erforderlich (ab Tag 3) │ │
│ │ Attest: [Noch nicht eingereicht] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ [Abwesenheit manuell eintragen] │
│ [Monatsuebersicht] [Export CSV] │
└─────────────────────────────────────────────────────┘Monats-Uebersicht (Klassenbuch-Ersatz)
April 2026
Schueler 01 02 03 04 05 ... 19 20 21 22
─────────────────────────────────────────────
Leon Mueller · · · · · K · · ·
Mia Schmidt · · · · · A · · ·
Tim Weber · · · · · K K K K
Emma Braun · · F · · · · · ·
─────────────────────────────────────────────
K = Krank, A = Arzttermin, F = Familiaer, · = AnwesendAttest-Automatik
- Cron-Job prueft taeglich alle offenen Abwesenheiten
- Wenn
endDate - date >= 3 Tage→attestRequired = true - Wenn attestRequired und kein Attest nach 5 Tagen → Erinnerung an Eltern
- Eltern koennen Attest als Foto/PDF hochladen →
attestFileIdgesetzt
Benachrichtigungen
- Eltern meldet Abwesenheit → System-Nachricht im Klassen-Space: "Leon Mueller wurde fuer heute als krank gemeldet."
- Lehrer nimmt zur Kenntnis → Eltern erhalten Bestaetigung
- Attest-Erinnerung → Chat-Nachricht an Eltern
Sekretariats-Ansicht (Space-uebergreifend)
Schulleitung / Sekretariat sieht eine Gesamtuebersicht aller Klassen:
┌─────────────────────────────────────────────┐
│ Abwesenheiten heute — Gesamtschule │
│ │
│ Klasse 1a: 1 abwesend (Sophie K.) │
│ Klasse 2b: 0 abwesend │
│ Klasse 3a: 3 abwesend │
│ Klasse 4b: 2 abwesend (Leon M., Mia S.) │
│ │
│ Gesamt: 6 von 312 Schuelern (1,9%) │
└─────────────────────────────────────────────┘4. Digitales Mitteilungsheft
Konzept
Das Mitteilungsheft ist ein privater Kanal zwischen Klassenlehrer und Eltern eines bestimmten Schuelers. Es ersetzt das gelbe Heft.
Technisch ist es ein SpacePost mit type: 'note' und einer Referenz auf den Schueler. Nur der Klassenlehrer und die Eltern des Schuelers sehen die Eintraege.
MitteilungsheftEntry
├── id
├── tenantId
├── spaceId -- Klassen-Space
├── studentUserId -- der betroffene Schueler
├── authorId -- Lehrer oder Eltern
├── direction -- 'school_to_home' | 'home_to_school'
├── content -- Text (kurz, max 1000 Zeichen)
├── category -- 'info' | 'request' | 'praise' | 'concern'
├── acknowledgedAt -- Gegenseite hat gelesen
├── acknowledgedBy
├── createdAtUser-Flow: Lehrer schreibt Mitteilung
Lehrer → Space "Klasse 4b" → Tab "Mitteilungsheft"
│
├── Schueler-Liste mit Badges (ungelesene Antworten)
│ ├── Leon Mueller (1 neue Antwort)
│ ├── Mia Schmidt
│ ├── Tim Weber (Attest ausstehend)
│ └── ...
│
├── Klick auf "Leon Mueller"
│
└── Chat-aehnliche Ansicht (aber formal):
┌─────────────────────────────────────────────┐
│ Leon Mueller — Mitteilungsheft │
│ │
│ 📤 14.04. (Schule → Eltern) │
│ Leon hat heute seine Sportsachen vergessen. │
│ Bitte morgen mitbringen. │
│ Kategorie: Hinweis │
│ ✓ Gelesen am 14.04. um 18:23 │
│ │
│ 📥 15.04. (Eltern → Schule) │
│ Danke fuer den Hinweis, Sportsachen sind │
│ eingepackt. │
│ ✓ Gelesen am 15.04. um 07:45 │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Neue Mitteilung... │ │
│ │ Kategorie: [Hinweis ▾] │ │
│ │ [Senden] │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘User-Flow: Eltern
Eltern oeffnen Prilog → sehen Badge am Space "Klasse 4b"
│
├── Tab "Mitteilungsheft"
│ └── Nur Eintraege fuer das eigene Kind sichtbar
│
├── Neue Mitteilung von der Schule:
│ "Leon hat seine Sportsachen vergessen"
│ [Gelesen ✓] ← 1-Klick-Bestaetigung
│
└── Antwort schreiben (optional)Datenschutz
- Eltern sehen NUR die Eintraege ihres eigenen Kindes
- Lehrer sehen alle Eintraege ihrer Klasse
- Eintraege werden nach Schuljahresende archiviert
- Kein anderer Schueler, kein anderer Elternteil sieht fremde Eintraege
Kategorien mit Icons
| Kategorie | Icon | Beispiel |
|---|---|---|
info | ℹ️ | "Morgen unterrichtsfrei" |
request | 📋 | "Bitte Sportsachen mitbringen" |
praise | ⭐ | "Leon hat heute toll mitgemacht" |
concern | ⚠️ | "Leon war heute sehr unruhig" |
5. Formulare / Einverstaendniserklaerungen
Konzept
Formulare sind SpacePosts mit type: 'form' und strukturierten Feldern. Der Lehrer erstellt ein Formular aus einer Vorlage oder frei, die Eltern fuellen es digital aus — das ersetzt die Zettelwirtschaft.
SpacePost (type: 'form')
├── title: "Einverstaendnis Schwimmunterricht"
├── body: "Hiermit erklaere ich, dass mein Kind..."
├── config: {
│ fields: [
│ { key: "childCanSwim", type: "yes_no", label: "Kann Ihr Kind schwimmen?", required: true },
│ { key: "healthNotes", type: "text", label: "Gesundheitliche Hinweise", required: false },
│ { key: "emergencyPhone", type: "phone", label: "Notfall-Telefon", required: true },
│ { key: "consent", type: "checkbox", label: "Ich bin einverstanden", required: true },
│ ],
│ requireSignature: true, -- digitale "Unterschrift" (Name + Datum)
│ template: "swimming", -- Vorlage-ID (fuer Wiederverwendung)
│ }
├── responseDeadline: "2026-05-01"
└── SpacePostResponse[]
└── response: {
"childCanSwim": "yes",
"healthNotes": "Keine",
"emergencyPhone": "0151-12345678",
"consent": true,
"signature": { "name": "Maria Mueller", "date": "2026-04-22" }
}Feld-Typen
| Typ | Darstellung | Validierung |
|---|---|---|
text | Einzeilige Texteingabe | Optional min/max Laenge |
textarea | Mehrzeiliges Textfeld | Optional max Laenge |
yes_no | Zwei Buttons: Ja / Nein | Required |
checkbox | Checkbox mit Label | Muss angehakt sein wenn required |
choice | Dropdown oder Radio-Buttons | Eine Option muss gewaehlt sein |
date | Datepicker | Gueltiges Datum |
phone | Telefon-Eingabe | Telefonnummer-Format |
number | Zahleneingabe | Optional min/max |
signature | Name + Datum (auto-generiert) | Pflichtfeld |
Vorlagen-Bibliothek
Vordefinierte Formulare pro Einrichtungstyp (wie bei Notfallplaenen):
Schule:
- Einverstaendnis Schwimmunterricht
- Einverstaendnis Ausflug/Klassenfahrt
- Einverstaendnis Foto-/Videoaufnahmen
- Medikamentengabe-Erlaubnis
- Abmeldung vom Religionsunterricht
- Einverstaendnis Mediennutzung
Kita:
- Einverstaendnis Sonnencreme-Auftrag
- Abholberechtigung (Personen-Liste)
- Allergien und Unvertraeglichkeiten
- Einverstaendnis Waldtag
- Schlafzeiten-Vereinbarung
Altersheim:
- Einverstaendnis Medikamenten-Aenderung
- Einverstaendnis Aktivitaeten-Teilnahme
- Kontaktdaten Angehoerige aktualisieren
User-Flow: Formular erstellen
Lehrer → Space → Tab "Briefe & Umfragen" → "Neues Formular"
│
├── Vorlage waehlen:
│ ├── "Einverstaendnis Schwimmunterricht" (vorgefuellt)
│ ├── "Einverstaendnis Ausflug" (vorgefuellt)
│ └── "Leer — eigenes Formular"
│
├── Formular anpassen:
│ ├── Titel aendern
│ ├── Text anpassen
│ ├── Felder hinzufuegen/entfernen/umordnen
│ ├── Digitale Unterschrift: [Ja / Nein]
│ └── Frist setzen
│
└── [Formular senden]User-Flow: Eltern fuellen aus
Eltern → Space → sehen Formular-Karte
│
├── Klick → Formular oeffnet sich
│ ├── Ueberschrift + Erklaerungstext
│ ├── Felder ausfuellen
│ ├── Unterschrift: "Maria Mueller" (auto-Datum)
│ └── [Absenden]
│
└── Bestaetigung: "Formular eingereicht"Lehrer-Uebersicht
┌─────────────────────────────────────────────────────┐
│ Einverstaendnis Schwimmunterricht Frist: 01.05. │
│ ████████████████░░░░░░░░ 16/24 eingereicht (67%) │
│ │
│ Ergebnisse: │
│ ├── Kind kann schwimmen: Ja: 14, Nein: 2 │
│ ├── Gesundl. Hinweise: 3 Eintraege │
│ └── Alle Unterschriften: 16 vorhanden │
│ │
│ Ausstehend: 8 Familien │
│ [Erinnerung senden] [Alle Antworten als PDF] │
└─────────────────────────────────────────────────────┘Gemeinsame Infrastruktur
Tab-Struktur im Space
Der Space bekommt neben Chat, Aufgaben, Kalender, Dateien einen neuen Tab: "Briefe & Umfragen". Dieser Tab zeigt alle SpacePosts (Elternbriefe, Umfragen, Formulare) in einer chronologischen Liste mit Filter.
Abwesenheiten bekommen einen eigenen Tab: "Anwesenheit".
Mitteilungsheft bekommt einen eigenen Tab: "Mitteilungsheft" (nur fuer Mitarbeiter sichtbar; Eltern sehen es als separate Ansicht fuer ihr Kind).
SSE Events
| Event | Trigger |
|---|---|
post.created | Neuer Brief/Umfrage/Formular |
post.response | Jemand antwortet/stimmt ab |
post.reminder | Erinnerung gesendet |
absence.reported | Eltern melden Abwesenheit |
absence.acknowledged | Lehrer bestaetigt |
note.created | Neue Mitteilung im Heft |
note.acknowledged | Gelesen-Bestaetigung |
Berechtigungen
| Aktion | Mitarbeiter | Eltern | Schueler |
|---|---|---|---|
| Brief/Umfrage/Formular erstellen | Ja | Nein | Nein |
| Auf Brief/Umfrage/Formular antworten | Ja | Ja | Nein |
| Abwesenheit melden | Nein | Ja | Nein |
| Abwesenheit einsehen (eigene Klasse) | Ja | Nur eigenes Kind | Nein |
| Mitteilung schreiben | Ja | Ja (Antwort) | Nein |
| Mitteilung lesen | Ja (alle Schueler) | Nur eigenes Kind | Nein |
n8n-Integration (Pro)
Jeder Event kann als n8n-Trigger genutzt werden:
- "Wenn Krankmeldung eingeht → Email an Sekretariat"
- "Wenn Formular-Frist ablaeuft und < 80% → Erinnerung an Eltern"
- "Wenn Abwesenheit > 5 Tage → Schulleitung informieren"
- "Wenn neuer Brief → Push-Notification (wenn PWA installiert)"
Kalender-Integration
- Abwesenheiten erscheinen im Klassen-Kalender
- Formular-Fristen erscheinen als Kalender-Event
- Elternabend-Umfrage → Gewinner-Termin wird automatisch als Event angelegt
Chat-Integration
- Briefe/Umfragen werden als System-Nachricht im Space-Chat angezeigt (nicht als voller Text, sondern als Link-Vorschau mit Titel + Status)
- Erinnerungen werden als Chat-Nachricht gesendet
- Abwesenheits-Meldungen erscheinen als kurze Info im Klassen-Chat
Datenbank-Schema (SQL)
-- ═══════════════════════════════════════════════════════════
-- SpacePosts: Elternbriefe, Umfragen, Formulare
-- ═══════════════════════════════════════════════════════════
CREATE TABLE space_posts (
id VARCHAR(50) PRIMARY KEY,
space_id VARCHAR(50) NOT NULL REFERENCES spaces(id) ON DELETE CASCADE,
tenant_id VARCHAR(64) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
type VARCHAR(20) NOT NULL, -- 'letter' | 'poll' | 'form'
title VARCHAR(500) NOT NULL,
body TEXT,
config JSONB NOT NULL DEFAULT '{}',
author_id VARCHAR(255) NOT NULL,
visibility VARCHAR(20) NOT NULL DEFAULT 'all',
response_type VARCHAR(20) NOT NULL DEFAULT 'none',
response_deadline TIMESTAMP(3),
reminder_sent BOOLEAN NOT NULL DEFAULT false,
pinned BOOLEAN NOT NULL DEFAULT false,
closed BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(3) NOT NULL
);
CREATE INDEX space_posts_space_id_idx ON space_posts(space_id, created_at DESC);
CREATE INDEX space_posts_tenant_id_idx ON space_posts(tenant_id, type);
CREATE TABLE space_post_responses (
id VARCHAR(50) PRIMARY KEY,
post_id VARCHAR(50) NOT NULL REFERENCES space_posts(id) ON DELETE CASCADE,
user_id VARCHAR(255) NOT NULL,
response JSONB NOT NULL, -- { choice: "Ja" } oder { field1: "wert", ... }
comment TEXT,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_id)
);
CREATE INDEX space_post_responses_post_id_idx ON space_post_responses(post_id);
-- ═══════════════════════════════════════════════════════════
-- SpacePost-Templates: Wiederverwendbare Vorlagen
-- ═══════════════════════════════════════════════════════════
CREATE TABLE space_post_templates (
id VARCHAR(50) PRIMARY KEY,
tenant_id VARCHAR(64) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
type VARCHAR(20) NOT NULL,
title VARCHAR(500) NOT NULL,
body TEXT,
config JSONB NOT NULL DEFAULT '{}',
facility_type VARCHAR(50), -- 'schule', 'kita', etc. — NULL = alle
is_system BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- ═══════════════════════════════════════════════════════════
-- Abwesenheiten
-- ═══════════════════════════════════════════════════════════
CREATE TABLE absence_entries (
id VARCHAR(50) PRIMARY KEY,
tenant_id VARCHAR(64) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
student_user_id VARCHAR(255) NOT NULL,
student_name VARCHAR(255) NOT NULL,
date DATE NOT NULL,
end_date DATE,
reason VARCHAR(30) NOT NULL DEFAULT 'sick',
reason_text TEXT,
reported_by VARCHAR(255) NOT NULL,
reported_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
attest_required BOOLEAN NOT NULL DEFAULT false,
attest_received BOOLEAN NOT NULL DEFAULT false,
attest_file_id VARCHAR(50) REFERENCES file_items(id),
acknowledged_by VARCHAR(255),
acknowledged_at TIMESTAMP(3),
status VARCHAR(20) NOT NULL DEFAULT 'reported',
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(3) NOT NULL
);
CREATE INDEX absence_entries_tenant_date_idx ON absence_entries(tenant_id, date);
CREATE INDEX absence_entries_student_idx ON absence_entries(student_user_id, date);
-- ═══════════════════════════════════════════════════════════
-- Mitteilungsheft
-- ═══════════════════════════════════════════════════════════
CREATE TABLE mitteilungsheft_entries (
id VARCHAR(50) PRIMARY KEY,
tenant_id VARCHAR(64) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
space_id VARCHAR(50) NOT NULL REFERENCES spaces(id) ON DELETE CASCADE,
student_user_id VARCHAR(255) NOT NULL,
author_id VARCHAR(255) NOT NULL,
direction VARCHAR(20) NOT NULL, -- 'school_to_home' | 'home_to_school'
content TEXT NOT NULL,
category VARCHAR(20) NOT NULL DEFAULT 'info',
acknowledged_at TIMESTAMP(3),
acknowledged_by VARCHAR(255),
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX mitteilungsheft_space_student_idx
ON mitteilungsheft_entries(space_id, student_user_id, created_at DESC);Umsetzungs-Reihenfolge
| Phase | Modul | Aufwand | Ergebnis |
|---|---|---|---|
| A | SpacePost-Grundgeruest + Elternbriefe | ~5-6 Tage | Briefe mit Rueckmeldung + Fortschrittsbalken |
| B | Umfragen (Erweiterung SpacePost) | ~3-4 Tage | Ja/Nein + Mehrfachauswahl + Live-Ergebnis |
| C | Abwesenheiten | ~5-6 Tage | Eltern-Meldung + Lehrer-Uebersicht + Monatsansicht |
| D | Mitteilungsheft | ~4-5 Tage | Schueler-bezogener Lehrer-Eltern-Kanal |
| E | Formulare | ~5-6 Tage | Formular-Builder + Vorlagen + digitale Unterschrift |
| F | Vorlagen-Bibliothek + Erinnerungs-Cron | ~2-3 Tage | System-Vorlagen + automatische Erinnerungen |
Gesamt: ~24-30 Arbeitstage (~5-6 Wochen)
Empfohlene Reihenfolge: A → B → C → D → E → F
Phase A und B teilen sich das SpacePost-Modell und koennen schnell hintereinander gebaut werden. Phase C (Abwesenheiten) ist eigenstaendig. Phase D (Mitteilungsheft) baut auf dem Space-Kontext auf. Phase E (Formulare) erweitert SpacePost um den Formular-Builder. Phase F (Vorlagen) ist Polish.