DMS — Konzept "Beste DMS in Wirtschaft & Schulwelt"
Status: Konzept v1 (2026-05-03). Vorbereitet als Grundlage für die Reparatur + den großen Umbau am 03.05.
Ziel: Aus dem heutigen DMS (Tag-System mit 4 Ansichten) ein State-of-the-Art-DMS machen, das in beiden Märkten — Schulen und mittelständischer Wirtschaft — den Standard setzt. Inspiriert von M-Files (Metadata-First), DocuWare (Workflow + IDP), ELO (Compliance), Paperless-ngx (UX), Folderit/Box (Smart Folders).
0. Sofort-Reparatur (vor jedem Feature-Bau)
| Bug | Fix |
|---|---|
🔴 Upload kaputt auf jeder Tenant-Box (SignatureDoesNotMatch) | Agent-Update + nginx-Rewrite, Code committed (siehe project_dms_morgen.md) |
| 🔴 DMS-Hub öffnet Mein Fach | DMS-Welt-Icon (Hub) navigiert auf neue Route /dms (institutionelles DMS), Mein Fach bleibt auf /mein-fach (Top-Bar Inbox-Icon) |
| 🟡 "Mein Fach (DMS)"-Naming verwirrend | Im Apps-Settings rename "DMS & Mein Fach" → "Mein Fach" (rein persönlich); neuer App-Eintrag "Dokumenten-Management" für die institutionelle Sicht |
Routing-Klärung:
/dms→ Institutionelles DMS (Cross-Space, Tenant-weit, alle Dokumente die ich sehen darf)/mein-fach→ Persönliches Fach (PERSONAL + INBOX scope)/spaces/:id/files→ Space-DMS (innerhalb eines Spaces)- Alle drei Sichten teilen sich das Document-Modell, unterscheiden sich nur im Filter.
1. Was die Besten haben — Feature-Recherche
M-Files — Metadata-First
- "Find by what it is, not where it's filed" — kein Folder-Zwang
- Vault-Konzept mit Klassen (Invoice, Contract, Report, ...)
- AI-gestützte Metadaten-Vorschläge (Intelligent Metadata Layer)
- Federated: zeigt Inhalte aus SharePoint/GDrive ohne Migration
- Beziehungen zwischen Docs ("dieses Dokument gehört zu diesem Projekt + diesem Kunden")
DocuWare — Workflow + IDP
- Drag-and-Drop Workflow-Designer für mehrstufige Freigaben
- Intelligent Document Processing: AI liest gescannte Dokumente, extrahiert Felder
- Rechnung kommt rein → AI weiß: Lieferant + Betrag + Fälligkeitsdatum → Workflow startet
- Native E-Signatur
- E-Mail-Integration (Outlook plugin)
ELO Digital Office
- Auto-Indexierung beim Import
- Records Management mit Aufbewahrungsfristen + Legal Hold
- Vollständige Audit-Trail-Kette
Paperless-ngx (Open Source)
- Nested Tags (Hierarchie max. 5 tief, Auto-Inheritance)
- Custom Fields pro Dokument-Typ
- Correspondents + Document Types als zweite Ordnungsachse neben Tags
- Auto-Lernen: System merkt sich Tag-Vorschläge basierend auf bisherigen Zuordnungen
- OCR + Volltextsuche (Tika + ngx)
- Flach-strukturiert, keine klassischen Ordner
Folderit / Box / SharePoint
- Smart Folders: dasselbe Dokument erscheint in mehreren Sichten (Projekt-Ordner UND Kunden-Ordner UND Jahres-Ordner)
- Saved Searches als virtuelle Ordner
- Public-Share-Links mit Expiry, Passwort, Watermark
Schul-Spezifika (DSGVO, DSchVO NRW)
- Aufbewahrungsfristen: 5 Jahre für die meisten Schülerdaten, 50 Jahre für Abschlusszeugnis-Duplikate
- Pflicht zur Löschung nach Ablauf (Storing beyond retention = unrechtmäßig)
- Pflicht zur Übergabe ans Archiv vor Vernichtung
- Schulrechtliche Akten-Klassen (BASS NRW): Schülerakte, Klassenakte, Personalakte, Verwaltungsakte
- §8a SGB VIII Kinderschutz: 10 Jahre, Vier-Augen-Prinzip
Wirtschaft-Spezifika
- Vertragsmanagement mit Kündigungsfristen-Reminder
- Rechnungseingangs-Workflow mit AI-OCR
- HR-Akten mit Personal-Datenschutz
- Projekte mit Cross-Referenzen
- §147 AO (Steuer): 6/8/10 Jahre für Geschäftsunterlagen
2. Unsere Architektur — Konsolidiert
Existierende Bausteine (live):
- ✅ Document-Modell mit
DocumentScope(PERSONAL / SPACE / GLOBAL / INBOX) - ✅ Per-Tenant S3 (AES-256-GCM verschlüsselte Credentials)
- ✅ Volltextsuche (Postgres tsvector, deutsch)
- ✅ Tag-System (DocumentTag join table)
- ✅ Versionierung (parentId + version)
- ✅ Soft-Delete + Restore + Star + Lock
- ✅ Audit-Log
- ✅ ClamAV
- ✅ Postfach (INBOX) + Verteiler-Drop
- ✅ Chat-Anhänge wandern direkt ins DMS
- ✅
prilog://file/<id>Internen-Link-Schema mit Resolver - ✅ Vier Ansichten: Liste / Kacheln / Ordner / Zeitstrom
Was fehlt für State-of-the-Art:
- ❌ Mehrere Ordner-Hierarchien ("Multiple folder systems")
- ❌ Smart Folders / Saved Searches als virtuelle Ordner
- ❌ Custom Fields pro Document Type (z.B. Rechnung: Lieferant, Betrag, Fälligkeit)
- ❌ Document Types als Klassifikation (Vertrag, Rechnung, Schülerakte, ...)
- ❌ Verschachtelte Tags (Hierarchie wie Paperless-ngx)
- ❌ OCR für gescannte PDFs + Bilder
- ❌ Auto-Klassifikation (AI-gestützte Tag/Type-Vorschläge)
- ❌ Aufbewahrungsfristen (Retention Policies) mit Auto-Aktion
- ❌ Legal Hold (sperrt Doc auch gegen Retention-Löschung)
- ❌ Workflow-Engine über Dokumente (Freigabe-Ketten) — wir haben Flow-Designer, müssen ihn ans DMS andocken
- ❌ E-Signatur (digital signing)
- ❌ Public-Share-Links mit Expiry + Watermark
- ❌ WebDAV-Mount (oder Desktop-Sync — Konzept existiert)
- ❌ Office-Integration (Word/Excel direct edit) — Tiptap haben wir, MS-Office wäre Bonus
- ❌ E-Mail-zu-DMS (Mail an spezielle Adresse → wandert ins DMS)
- ❌ Vorlagen-Bibliothek (Templates)
- ❌ Annotationen auf PDFs (Kommentare in/an Dokumenten)
- ❌ Beziehungen zwischen Dokumenten ("gehört zu Projekt X" + "gehört zu Kunde Y")
3. Architektur-Entscheidungen
3.1 Klassifikation — die drei Achsen
┌──────────────────────────┐
│ Ein Dokument │
└──────────────────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
1. Document-Type 2. Tags (n) 3. Folder-Refs (n)
(was es IST) (Schlagwörter) (wo es HÄNGT)
z.B. "Vertrag" "wichtig", "2026" verschiedene Ordner-
hierarchienErgebnis: Ein Dokument kann gleichzeitig
- ein Document-Type sein (Vertrag, Rechnung, Schülerakte, ...) — exklusiv
- mehrere Tags haben (verschachtelt, wie Paperless-ngx)
- in mehreren Ordnern in mehreren parallelen Ordner-Bäumen sein
3.2 Mehrere Ordner-Hierarchien — der Kern-Twist
Problem: Schule will Akten nach Klasse sortiert und nach Akten-Typ und nach Schuljahr sehen. Wirtschaft will nach Projekt und nach Kunde und nach Dokument-Typ sehen.
Lösung: Multiple Folder Systems — der Tenant-Admin definiert pro Tenant beliebig viele Ordner-Hierarchien (Folder-Trees). Jede Hierarchie ist ein eigener Baum mit eigener Bedeutung.
Beispiel Schule:
- Hierarchie "Schuljahr": 2025-26 → Klasse 7b → Lukas Meier
- Hierarchie "Akten-Art": Schülerakten → Anmeldungen / Zeugnisse / Bescheinigungen
- Hierarchie "Verwaltung": Personal / Finanzen / Verträge / Beschwerden
Beispiel Wirtschaft:
- Hierarchie "Kunde": Acme GmbH → Verträge / Rechnungen
- Hierarchie "Projekt": Projekt-X → Phase 1 / Phase 2
- Hierarchie "Jahr": 2026 → Q1 / Q2 / ...
Ein Dokument hängt gleichzeitig in mehreren Ordnern aus unterschiedlichen Hierarchien. Verschieben in einer Hierarchie ändert nichts an den anderen.
3.3 Smart Folders / Saved Searches
Eine "Saved Search" ist ein gespeicherter Filter, der wie ein Ordner aussieht. Beispiele:
- "Alle ungelesenen Rechnungen über 10.000 €"
- "Verträge mit Kündigungsfrist in den nächsten 30 Tagen"
- "Schülerakten Klasse 7b — Schuljahr 2025-26"
Smart Folders erscheinen in der Sidebar wie normale Ordner, sind aber dynamisch. User kann sie personal oder shared anlegen.
3.4 Document Types + Custom Fields
Tenant-Admin definiert Document Types mit zugehörigen Custom Fields:
DocumentType: "Schülerakte"
fields:
- schuelerName: text, required
- klasse: text, required
- schuljahr: select [2025-26, 2024-25, ...]
- akteArt: select [Anmeldung, Zeugnis, Bescheinigung]
- aufbewahrungBis: date # auto-berechnet aus akteArt
retentionPolicy: "schule-schuelerakte" # verweist auf Retention-RegelDocumentType: "Rechnung"
fields:
- lieferant: text
- rechnungsnummer: text, unique
- betrag: money
- faelligAm: date
- bezahltAm: date, optional
retentionPolicy: "ao-§147-10jahre"Beim Upload kann der User einen Type wählen, OCR/AI macht Vorschläge.
3.5 Retention Policies + Legal Hold
RetentionPolicy "ao-§147-10jahre"
duration: 10 years
trigger: "rechnungsdatum" # Custom-Field
action_after: archive # oder delete | shred | offer_to_archive
legalHoldOverride: true
RetentionPolicy "schule-schuelerakte"
duration: 5 years
trigger: "schulaustritt"
action_after: offer_to_archive # wird dem Operator angeboten
RetentionPolicy "schule-zeugnis-duplikat"
duration: 50 years # BASS NRWLegal Hold: Admin markiert ein Doc als "rechtlich gesperrt" → Retention-Aktion wird ignoriert. Audit-Log dokumentiert wer + warum.
3.6 Tags — verschachtelt mit Auto-Inheritance
Wie Paperless-ngx: Tag-Hierarchie max. 5 tief.
Verwaltung > Formulare > Anmeldung- Beim Setzen werden Eltern-Tags automatisch mitgesetzt
- Beim Entfernen werden Kinder mit-entfernt
3.7 Beziehungen zwischen Dokumenten
Document A: Vertrag mit Acme GmbH
relations:
- { type: "BELONGS_TO", target: "Acme GmbH" (Contact) }
- { type: "BELONGS_TO", target: "Projekt-X" (Document) }
- { type: "RELATED_TO", target: Rechnung-2026-042 (Document) }
- { type: "SUPERSEDES", target: Vertrag-2024-Acme }Backend-Modell: neue Tabelle document_relations. Web-Client zeigt sie im Detail-Panel als verlinkte Karten.
4. UX — die "DMS-Hub"-Sicht
4.1 Navigation (linke Sidebar)
┌────────────────────────────┐
│ 📁 DOKUMENTE │
│ ├ ⭐ Favoriten │
│ ├ 🕐 Zuletzt │
│ ├ ⚡ Smart Folders │
│ │ ├ Eingang heute │
│ │ ├ Verträge < 30 Tage │
│ │ └ + Neu anlegen │
│ ├ 🗂 Ordnersysteme │
│ │ ├ 📂 Schuljahr │
│ │ │ ├ 2025-26 │
│ │ │ └ 2024-25 │
│ │ ├ 📂 Verwaltung │
│ │ │ ├ Personal │
│ │ │ └ Finanzen │
│ │ └ + Hierarchie anlegen │
│ ├ 🏷 Tags │
│ │ ├ Wichtig (47) │
│ │ ├ Klausur (12) │
│ │ └ ... │
│ ├ 📋 Dokument-Typen │
│ │ ├ Vertrag (8) │
│ │ ├ Rechnung (24) │
│ │ └ Schülerakte (143) │
│ └ 🗑 Papierkorb │
└────────────────────────────┘4.2 Hauptbereich
┌──────────────────────────────────────────────────────────┐
│ [Toolbar: Hochladen] [Neu] [⚙ Ansicht: Kacheln ▼] │
│ [Suche 🔍] │
│ Filter: [Typ ▼] [Tag ▼] [Datum ▼] [Custom-Field ▼] │
├──────────────────────────────────────────────────────────┤
│ │
│ Ergebnisse (47) │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ Doc1 │ │ Doc2 │ │ Doc3 │ ... │
│ └──────┘ └──────┘ └──────┘ │
│ │
└──────────────────────────────────────────────────────────┘4.3 Ansichten (4 bestehende + 1 neu)
- Liste (klassisch) — bleibt
- Kacheln mit Vorschau-Thumbnails (PDF-Page-1, Bilder, Office-Preview) — erweitern um echte Thumbnails
- Ordner — wird zur aktiv gewählten Ordner-Hierarchie ("Brille auf eine Hierarchie")
- Zeitstrom — bleibt
- NEU: Tabelle — wie Excel, mit Custom-Field-Spalten je Document-Type. Sortierbar, filterbar.
4.4 Detail-Panel (rechte Seite)
┌────────────────────────────────────────┐
│ Titel der Datei │
│ Typ: Schülerakte · v3 · 2.3 MB │
├────────────────────────────────────────┤
│ Vorschau (PDF/Image/Text) │
├────────────────────────────────────────┤
│ Aktionen: │
│ [Download] [🔗 Internen Link] │
│ [✍ Bearbeiten] [📤 Teilen] [🗑] │
├────────────────────────────────────────┤
│ Metadata: │
│ Schüler: Lukas Meier │
│ Klasse: 7b │
│ Aufbewahrung: bis 2031-08 │
├────────────────────────────────────────┤
│ Tags: │
│ [Anmeldung] [2025-26] [+] │
├────────────────────────────────────────┤
│ In Ordnern: │
│ 📂 Schuljahr/2025-26/7b │
│ 📂 Akten-Art/Schülerakten/Anmeldung │
│ [+ In weiteren Ordner ablegen] │
├────────────────────────────────────────┤
│ Beziehungen: │
│ → gehört zu: Lukas Meier (Person) │
│ → folgt auf: Anmeldung-2024.pdf │
│ → verwandt: Zeugnis-7b-2025.pdf │
├────────────────────────────────────────┤
│ Versionen (3) · Audit-Log (12) │
│ Sicherheit · Aufbewahrung │
└────────────────────────────────────────┘5. Daten-Modell
5.1 Bestehend (bleibt)
Document— Kern-ModellDocumentTag— TagsTag— Tag-DefinitionInboxDropMeta— Postfach-MetaDistribution— Verteiler
5.2 Neue Tabellen
// Mehrfache Ordnerhierarchien pro Tenant
model FolderTree {
id String @id @default(cuid())
tenantId String
name String // "Schuljahr", "Verwaltung", "Kunde"
description String?
iconEmoji String? // optional Visual
sortOrder Int @default(0)
createdBy String
createdAt DateTime @default(now())
folders Folder[]
@@index([tenantId])
}
// Ein Knoten in einer Hierarchie
model Folder {
id String @id @default(cuid())
tenantId String
treeId String
parentId String? // null = top-level
name String
iconEmoji String?
sortOrder Int @default(0)
createdBy String
createdAt DateTime @default(now())
tree FolderTree @relation(fields: [treeId], references: [id], onDelete: Cascade)
parent Folder? @relation("FolderHierarchy", fields: [parentId], references: [id], onDelete: Cascade)
children Folder[] @relation("FolderHierarchy")
placements DocumentFolderPlacement[]
@@index([tenantId, treeId])
@@index([parentId])
}
// Many-to-many: ein Dokument in beliebig vielen Ordnern (auch ueber Trees hinweg)
model DocumentFolderPlacement {
id String @id @default(cuid())
documentId String
folderId String
placedBy String
placedAt DateTime @default(now())
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
folder Folder @relation(fields: [folderId], references: [id], onDelete: Cascade)
@@unique([documentId, folderId])
@@index([folderId])
}
// Verschachtelte Tags
model Tag {
// bestehend, neu:
parentId String? // null = top-level
parent Tag? @relation("TagHierarchy", fields: [parentId], references: [id], onDelete: SetNull)
children Tag[] @relation("TagHierarchy")
}
// Document Types
model DocumentType {
id String @id @default(cuid())
tenantId String
key String // "schuelerakte", "rechnung"
label String // "Schülerakte"
iconEmoji String?
description String?
retentionPolicyId String?
fields Json // [{ key, label, type, required, options }]
createdAt DateTime @default(now())
documents Document[]
@@unique([tenantId, key])
@@index([tenantId])
}
// Document → Type
model Document {
// bestehend, neu:
documentTypeId String?
documentType DocumentType? @relation(fields: [documentTypeId], references: [id])
customFields Json? // { schuelerName: "Lukas", klasse: "7b", ... }
retentionUntil DateTime? // berechnet aus DocumentType + customFields
legalHold Boolean @default(false)
legalHoldReason String?
legalHoldBy String?
legalHoldAt DateTime?
}
// Saved Searches / Smart Folders
model SavedSearch {
id String @id @default(cuid())
tenantId String
ownerUserId String? // null = shared
name String
iconEmoji String?
query Json // { tags: [...], type: "...", customFields: {...}, dateRange: ..., scope: ... }
sortOrder Int @default(0)
createdAt DateTime @default(now())
@@index([tenantId])
}
// Beziehungen zwischen Dokumenten
model DocumentRelation {
id String @id @default(cuid())
fromId String
toId String
relationType String // "BELONGS_TO" | "RELATED_TO" | "SUPERSEDES" | "PART_OF"
createdBy String
createdAt DateTime @default(now())
from Document @relation("RelationFrom", fields: [fromId], references: [id], onDelete: Cascade)
to Document @relation("RelationTo", fields: [toId], references: [id], onDelete: Cascade)
@@unique([fromId, toId, relationType])
@@index([fromId])
@@index([toId])
}
// Retention Policies
model RetentionPolicy {
id String @id @default(cuid())
tenantId String
key String
label String
durationDays Int
triggerField String? // "rechnungsdatum", "schulaustritt", "createdAt"
actionAfter String // "archive" | "delete" | "offer_to_archive"
legalHoldOverride Boolean @default(true)
createdAt DateTime @default(now())
documentTypes DocumentType[]
@@unique([tenantId, key])
}
// Public Share Links
model PublicShareLink {
id String @id @default(cuid())
documentId String
slug String @unique // 32-char random
passwordHash String?
expiresAt DateTime?
watermark Boolean @default(false)
maxViews Int?
views Int @default(0)
createdBy String
createdAt DateTime @default(now())
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
@@index([slug])
@@index([documentId])
}
// E-Signaturen (geplant Phase 4)
model DocumentSignature {
id String @id @default(cuid())
documentId String
signerUserId String
signedAt DateTime
signatureHash String
ipAddress String?
// ...
}6. Phasenplan
Phase 0 — Reparatur (DAG 1, 2-3h)
- ✅ Code committed (siehe project_dms_morgen.md)
- 🟢 Agent-Update auf shared-Hosts → nginx-Rewrite → DB-Endpoint-Fix → Backend-Restart
- 🟢 Routing:
/dmsneue Route, DMS-Hub-Welt zeigt institutionelles DMS, nicht Mein Fach
Acceptance: Upload funktioniert auf allen Tenants, DMS-Hub zeigt nicht Mein Fach.
Phase 1 — Mehrfache Ordnerhierarchien (Tag 1-2)
- DB-Migration:
folder_trees,folders,document_folder_placements - Backend-Endpoints: CRUD Trees + Folders, Drop-into-Folder, Read-by-Tree
- Web-Client: Sidebar-Sektion "Ordnersysteme" mit dynamisch ladbaren Trees, Tree-Anlegen-Modal, Drag-and-Drop in Ordner
- Settings → DMS → "Ordnersysteme" zum Anlegen / Verwalten
Acceptance: Admin legt Tree "Schuljahr" + "Akten-Art" an, Doc kann in beiden gleichzeitig liegen, Sidebar zeigt beides parallel.
Phase 2 — Verschachtelte Tags + Smart Folders (Tag 2-3)
- DB-Migration:
tags.parentId - Tag-Auto-Inheritance (Save Tag → Eltern-Tags rein, Remove → Kinder raus)
- DB-Migration:
saved_searches - Backend: CRUD Saved-Search + GET-Resolver (führt Query gegen Document aus)
- Web-Client: "Smart Folders"-Sektion in Sidebar, "Aus aktueller Suche speichern"-Button
Acceptance: Tag-Tree mit 3 Ebenen, Save Search "Verträge < 30 Tage" speichert + erscheint in Sidebar.
Phase 3 — Document Types + Custom Fields (Tag 3-5)
- DB-Migration:
document_types,documents.documentTypeId,documents.customFields - Backend: CRUD Document-Types, Validation, Custom-Field-Filter im Search
- Web-Client:
- Settings → DMS → Document-Types (CRUD-UI mit Field-Designer)
- Beim Upload: Type-Picker, danach Custom-Field-Form
- Tabellen-Ansicht: Spalten = Custom-Fields des aktuellen Types
- 2-3 Default-Types vorbereitet (Vertrag, Rechnung, Schülerakte) — als Vorlage importierbar
Acceptance: Admin legt Type "Schülerakte" mit 5 Feldern an, Upload zeigt Form, Tabellenansicht zeigt Spalten.
Phase 4 — Beziehungen + erweiterte Detail-Sicht (Tag 5-6)
- DB-Migration:
document_relations - Backend: CRUD Relations
- Web-Client: Detail-Panel um "Beziehungen"-Sektion erweitern, Relation-Picker
- Bidirektionale Anzeige (X gehört zu Y → Y wird auch in X gezeigt)
Acceptance: Vertrag verlinkt mit Kunden-Kontakt + Folge-Vertrag, Detail zeigt beide Richtungen.
Phase 5 — Retention + Legal Hold (Tag 6-7)
- DB-Migration:
retention_policies,documents.retentionUntil + legalHold + legalHoldReason - Backend: Retention-Cron läuft täglich, prüft Docs deren
retentionUntil< heute, führtactionAfteraus - Web-Client:
- Settings → DMS → Retention-Policies
- Doc-Detail zeigt "Aufbewahrung bis" + Legal-Hold-Toggle
- Banner "Wird in 7 Tagen archiviert" für ablaufende Docs
- Admin-UI: Liste auslaufender Docs mit Quick-Actions
Acceptance: Schul-Akte mit Schulaustritt → wird nach 5 Jahren automatisch archiviert. Legal Hold blockt Aktion.
Phase 6 — Public-Share-Links (Tag 7-8)
- DB-Migration:
public_share_links - Backend:
- POST /documents/:id/share — Slug + Passwort + Expiry generieren
- GET /share/:slug — public route, ggf. Passwort-Form, dann Download/Preview
- Watermark-Renderer (PDF mit Logo + Empfaenger-Email + Zeitstempel als Overlay)
- Web-Client: "Teilen"-Modal im Detail-Panel
- Audit: jeder Aufruf eines Public-Links wird geloggt
Acceptance: Doc geteilt mit 7-Tage-Expiry + Passwort, Externer öffnet ohne Login + Auto-Watermark mit IP.
Phase 7 — OCR + Auto-Klassifikation (Tag 8-10)
- Tesseract-Integration auf Backend (Per-Tenant-Worker oder zentral)
- Beim Upload: PDF/Image → OCR-Job in Queue → extrahierter Text in
documents.content→ tsvector aktualisiert - Auto-Type-Vorschlag: Klassifikator lernt aus bestehenden Zuordnungen (einfacher Naive-Bayes über Wort-Häufigkeit)
- Custom-Field-Extraktion: Regex-Library pro DocumentType (z.B. Rechnung → IBAN, Betrag, Datum)
Acceptance: Gescannte PDF hochgeladen → 30s später durchsuchbar. Zweite Rechnung des gleichen Lieferanten → System schlägt Type "Rechnung" + Lieferant vor.
Phase 8 — Workflows ans DMS andocken (Tag 10-11)
- Process-Engine bekommt neue Component-Kinds:
dms.upload— Wartet auf Upload eines Dokuments mit bestimmtem Typedms.approve— Dokument zur Freigabe vorlegen, Stakeholder bestätigt/lehnt abdms.sign— E-Signatur einholendms.archive— Dokument archivieren
- Beispiel-Flow "Rechnungseingang": Upload → OCR → Approval (Buchhaltung) → Bezahlt-Markierung → Archiv
Acceptance: Drag-and-Drop einer Rechnung startet Flow, Buchhalter bekommt Aufgabe, Approve → Status auf "bezahlt" gesetzt.
Phase 9 — E-Signatur (Tag 11-13)
- DB-Migration:
document_signatures - Backend:
- Sign-Request endpoint: erstellt Anfrage, sendet Mail/Push an Empfänger
- Empfänger öffnet, bestätigt → SHA256-Hash über (Doc-Hash + Timestamp + UserId + IP) wird gespeichert
- eIDAS-konform "fortgeschritten" (kein qualifizierter Schlüssel, das wäre Phase X)
- Web-Client: Sign-Dialog mit Vorschau + Bestätigung
- PDF-Export mit Signatur-Block am Ende
Acceptance: Vertrag wird zur Signatur an 3 Personen gesendet, alle bestätigen, signiertes PDF mit allen 3 Signaturen + Audit-Trail.
Phase 10 — Annotationen + Vorlagen + Sonstiges (Tag 13-15) — LIVE 2026-05-03
- ✅ Thread-Kommentare am Document (DocumentAnnotation, Resolve/Reopen, optionale Page/Pos-Anker fuer kuenftiges Inline-Highlighting)
- ✅ Template-Library: jedes Doc als Vorlage markierbar mit Kategorie, "Neu aus Vorlage"-Picker im DMS-Hub mit Scope-Wahl PERSONAL/SPACE
- ✅ Mail-zu-DMS:
dms-<slug>@mail.prilog.chat(User-Alias, ein/aus/rotieren), eingehende Mails via Stalwart-Webhook landen in Mein Fach (Body als .txt + Anhaenge als einzelne Documents) - WebDAV-Mount: spaeter (Desktop-Sync-Client deckt das Use-Case bereits ab)
- PDF-Annotation-Highlighting im PDF.js-Viewer: spaeter (Daten-Modell steht bereits, UI nachzuziehen)
Acceptance: Kommentar-Thread am Doc → Resolve, "Neu aus Vorlage" → kopiertes Doc im DMS, Mail an dms-Alias → Anhaenge in Mein Fach.
7. Quick-Wins für Tag 1 (DAG 1 sofortige Sichtbarkeit)
- Routing-Fix — DMS-Welt-Icon →
/dms(institutionell), Mein Fach bleibt eigene Welt - Phase 1 (Ordnerhierarchien) — der größte UX-Sprung. Macht aus dem heutigen Ein-Tag-System ein "echtes" DMS-Gefühl
- Tabellen-Ansicht (vorbereitend für Phase 3) — auch ohne Custom Fields schon mal da haben
Ergebnis nach Tag 1: User landet im DMS-Hub, sieht seine Spaces als parallele Ordner-Hierarchie + neue eigene Hierarchien, kann Docs in mehrere Ordner gleichzeitig hängen.
8. Was wir NICHT bauen (bewusst)
- Keine eigene Office-Suite — Tiptap reicht für Notizen, MS Office Online wäre zu teuer
- Keine eigene OCR-Engine — Tesseract ist gut genug, kein eigener Trainings-Aufwand
- Keine qualifizierte E-Signatur (eIDAS) — viel zu komplex (HSM, Trust-Service-Provider). Stattdessen "fortgeschritten" — reicht für 95% der Anwendungsfälle
- Kein Compliance-Auditor-Tool — wir liefern Audit-Logs, das Reporting darauf ist Nische
- Kein WORM-Storage — S3-Object-Lock ist möglich aber teuer, Phase X
- Keine Migrations-Toolchain für SharePoint/etc. — Nice-to-have, später
9. Marktpositionierung
Tagline: "Das DMS, das beides versteht — den Schul-Alltag und die Buchhaltung."
USPs gegenüber:
- DocuWare/M-Files: viel günstiger, integrierter ins ganze Schul-/Workspace-Erlebnis, deutsche Sprache nativ
- Paperless-ngx: keine Self-Hosting-Pflicht, Multi-User, Schul-Compliance bereits drin
- NextCloud Files: spezialisiert statt generisch, mit Workflow + Retention out-of-the-box
- ELO: günstiger, einfacher, Cloud-First, ohne Verkaufsgespräch buchbar
Preis-Modell (Vorschlag): in das bestehende Per-Active-User Pro (3 EUR/User) inkludiert, Pro-Modul-Preis für AI-Klassifikation (Phase 7) optional.
10. Risiken + Mitigations
| Risiko | Mitigation |
|---|---|
| Schul-Datenschutz-Anforderungen unterschätzt | Phase 5 Retention von Anfang an mitdenken, Schul-Use-Cases mit Lehrer testen |
| OCR-Performance auf großen PDFs | Queue-System (Bull/Redis), Tenant-übergreifender Worker-Pool |
| Custom-Field-Schema-Drift bei Type-Updates | Migrations-Konzept: Type-Update versioniert, alte Docs behalten alte Schema |
| Datenmenge wächst schneller als S3-Quota | Per-Tenant-Quota-Monitoring + Auto-Mahnungen + Hetzner-Object-Storage als günstige Alternative für kalte Daten |
| Folder-Hierarchien werden zu tief | UX-Limit (max 5 Ebenen pro Tree, klar kommuniziert) |
| Migration der alten "Tags-as-Folders"-Brille auf echte Folders | Ein-Klick-Migration: für jeden Top-Level-Tag mit "/"-Hierarchie ein Folder-Tree erzeugen |
11. Nächste Schritte (Reihenfolge für 03.05.)
- Morgen früh — Phase 0 (Reparatur Upload + Routing-Fix) — 2h
- Mittag — Diskussion: dieses Konzept durchgehen, Prioritäten festlegen, ggf. Zuschnitt auf MVP
- Mittag-Abend — Phase 1 starten (Mehrfache Ordnerhierarchien)
- Tage 2-15 — Phasen 2-10 nach festgelegter Priorität
Default-Zuschnitt für MVP-1 (1 Woche): Phase 0 + 1 + 2 + 3 (Folders + Tags + Document-Types). Damit hat das DMS schon den "großen Sprung" gegenüber heute. Phase 4-10 als Roadmap-Story für Verkauf.
Anhang — Feature-Vergleichs-Matrix
| Feature | Heute | Phase 1 | Phase 5 | Phase 10 | M-Files | DocuWare | Paperless-ngx |
|---|---|---|---|---|---|---|---|
| Volltextsuche | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Tags | ✅ flach | ✅ verschachtelt | ✅ | ✅ | ✅ | ✅ | ✅ |
| Mehrere Ordnerhierarchien | ❌ | ✅ | ✅ | ✅ | ✅ | ⚠ | ❌ |
| Smart Folders | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Document Types + Custom Fields | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| OCR | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| Auto-Klassifikation | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ⚠ |
| Retention Policies | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ⚠ |
| Legal Hold | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Versionierung | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Public-Share-Links | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ⚠ |
| E-Signatur | ❌ | ❌ | ❌ | ✅ | ⚠ | ✅ | ❌ |
| Workflow-Engine | ❌ ext. | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ |
| Beziehungen | ❌ | ❌ | ❌ | ✅ | ✅ | ⚠ | ❌ |
| Schul-Compliance | ❌ | ❌ | ✅ | ✅ | ⚠ | ⚠ | ❌ |
| Pro-Active-User-Pricing | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
| Open-Source-Kern | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| Deutsche UI nativ | ✅ | ✅ | ✅ | ✅ | ⚠ | ✅ | ⚠ |
⚠ = nur teilweise / nur über Plugins