diff --git a/Documentation/modelle.md b/Documentation/modelle.md new file mode 100644 index 0000000..5f34e86 --- /dev/null +++ b/Documentation/modelle.md @@ -0,0 +1,544 @@ +# Alle Modelle der vgui-cicd Django-Anwendung + +Dieses Dokument beschreibt alle Datenmodelle in der vgui-cicd Anwendung mit ihren Eigenschaften, Beziehungen und Verwendungszwecken. + +--- + +## App: dokumente + +Die Hauptmodelle für die Verwaltung von Dokumenten, Vorgaben und deren Metadaten. + +### Dokumententyp + +**Zweck**: Kategorisierung von Dokumenten (z. B. Richtlinie, Standard). + +**Wichtige Felder**: +- `name` (CharField, max_length=100, **PRIMARY KEY**) +- `verantwortliche_ve` (CharField, max_length=255): Die verantwortliche Verwaltungseinheit + +**Besonderheiten**: +- `__str__()` gibt den Namen zurück +- Dient als Klassifizierungskategorie für Dokumente + +**Meta**: +- `verbose_name = "Dokumententyp"` +- `verbose_name_plural = "Dokumententypen"` + +--- + +### Person + +**Zweck**: Repräsentiert Personen, die als Autoren, Prüfer oder in anderen Rollen tätig sind. + +**Wichtige Felder**: +- `name` (CharField, max_length=100, **PRIMARY KEY**) +- `funktion` (CharField, max_length=255): Funktionsbezeichnung der Person + +**Beziehungen**: +- Many-to-Many mit `Dokument` über `verfasste_dokumente` (Autoren) +- Many-to-Many mit `Dokument` über `gepruefte_dokumente` (Prüfer) + +**Besonderheiten**: +- `__str__()` gibt den Namen zurück +- `ordering = ['name']`: Alphabetische Sortierung + +**Meta**: +- `verbose_name_plural = "Personen"` + +--- + +### Thema + +**Zweck**: Thematische Einordnung und Kategorisierung von Vorgaben innerhalb von Dokumenten. + +**Wichtige Felder**: +- `name` (CharField, max_length=100, **PRIMARY KEY**) +- `erklaerung` (TextField, blank=True): Optionale Erklärung des Themas + +**Besonderheiten**: +- `__str__()` gibt den Namen zurück +- Der erste Buchstabe des Themas wird in Vorgabennummern verwendet + +**Meta**: +- `verbose_name_plural = "Themen"` + +--- + +### Dokument + +**Zweck**: Hauptmodell für ein einzelnes Dokument mit allen zugehörigen Metadaten und Inhalten. + +**Wichtige Felder**: +- `nummer` (CharField, max_length=50, **PRIMARY KEY**): Eindeutige Dokumentennummer +- `dokumententyp` (ForeignKey → Dokumententyp, on_delete=PROTECT): Klassifizierung +- `name` (CharField, max_length=255): Dokumenttitel +- `autoren` (ManyToManyField → Person, related_name='verfasste_dokumente') +- `pruefende` (ManyToManyField → Person, related_name='gepruefte_dokumente') +- `gueltigkeit_von` (DateField, null=True, blank=True): Gültig ab Datum +- `gueltigkeit_bis` (DateField, null=True, blank=True): Gültig bis Datum +- `signatur_cso` (CharField, max_length=255, blank=True): CSO-Signatur +- `anhaenge` (TextField, blank=True): Beschreibung von Anhängen +- `aktiv` (BooleanField, blank=True): Aktivierungsstatus + +**Beziehungen**: +- 1-to-Many mit `Vorgabe` (über related_name='vorgaben') +- 1-to-Many mit `Geltungsbereich` +- 1-to-Many mit `Einleitung` +- 1-to-Many mit `Changelog` + +**Besonderheiten**: +- `__str__()` formatiert als "nummer – name" + +**Meta**: +- `verbose_name = "Dokument"` +- `verbose_name_plural = "Dokumente"` + +--- + +### Vorgabe + +**Zweck**: Repräsentiert eine einzelne Vorgabe oder Anforderung innerhalb eines Dokuments. + +**Wichtige Felder**: +- `order` (IntegerField): Sortierreihenfolge für die Darstellung +- `nummer` (IntegerField): Nummer innerhalb eines Themas/Dokuments. Muss nicht eindeutig sein (z.B. für geänderte Vorgaben) +- `dokument` (ForeignKey → Dokument, on_delete=CASCADE, related_name='vorgaben') +- `thema` (ForeignKey → Thema, on_delete=PROTECT): Thematische Einordnung +- `titel` (CharField, max_length=255): Titel der Vorgabe +- `referenzen` (ManyToManyField → Referenz, blank=True): Verweise auf externe Referenzen +- `gueltigkeit_von` (DateField): Gültig ab Datum +- `gueltigkeit_bis` (DateField, blank=True, null=True): Gültig bis Datum (offen = unbegrenzt) +- `stichworte` (ManyToManyField → Stichwort, blank=True): Tags zur Kategorisierung +- `relevanz` (ManyToManyField → Rolle, blank=True): Relevante Rollen + +**Beziehungen**: +- Foreign Key zu `Dokument` und `Thema` +- Many-to-Many zu `Referenz`, `Stichwort`, `Rolle` +- 1-to-Many zu `VorgabeLangtext`, `VorgabeKurztext` +- 1-to-Many zu `Checklistenfrage` + +**Wichtige Methoden**: + +- `Vorgabennummer()` → str + - Generiert eine eindeutige, lesbare Kennummer + - Format: "{dokument.nummer}.{thema.name[0]}.{nummer}" + - Beispiel: "R0066.A.1" + +- `get_status(check_date=None, verbose=False)` → str + - Bestimmt den Status einer Vorgabe zu einem gegebenen Datum + - Parameter: `check_date` (Default: heute), `verbose` (Deutsche Beschreibung ja/nein) + - Rückgabewerte: + - "future": Vorgabe ist noch nicht gültig + - "active": Vorgabe ist aktuell gültig + - "expired": Vorgabe ist nicht mehr gültig + - Verbose-Ausgaben enthalten Datumsangaben + +- `sanity_check_vorgaben()` (statisch) → list + - Findet zeitliche Konflikte zwischen Vorgaben mit gleicher Nummer/Thema/Dokument + - Überprüft, ob sich Geltungszeiträume überschneiden + - Gibt Liste mit Konflikt-Dictionaries zurück + +- `clean()` + - Validiert die Vorgabe vor dem Speichern + - Ruft `find_conflicts()` auf + - Wirft `ValidationError` bei erkannten Konflikten + +- `find_conflicts()` → list + - Findet Konflikte mit bestehenden Vorgaben (ausgenommen self) + - Überprüft auf zeitliche Überschneidungen + - Gibt Liste mit Konflikt-Details zurück + +- `_date_ranges_intersect(start1, end1, start2, end2)` (statisch) → bool + - Prüft, ob zwei Datumsbereiche sich überschneiden + - `None` als Enddatum = unbegrenzter Bereich + - Gibt `True` bei Überschneidung zurück + +**Besonderheiten**: +- `__str__()` gibt "Vorgabennummer: titel" zurück +- Validierung von Gültigkeitszeiträumen ist implementiert +- Sehr wichtiges Modell im Geschäftslogik-Kontext + +**Meta**: +- `ordering = ['order']` +- `verbose_name_plural = "Vorgaben"` + +--- + +### VorgabeLangtext + +**Zweck**: Speichert ausführliche Textinhalte (Langtext) einer Vorgabe. + +**Wichtige Felder**: +- `abschnitt` (ForeignKey → Vorgabe, on_delete=CASCADE): Referenz zur Vorgabe +- Erbt von `Textabschnitt` (siehe App: abschnitte): + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Langtext-Abschnitt"` +- `verbose_name_plural = "Langtext"` + +--- + +### VorgabeKurztext + +**Zweck**: Speichert kurze Textinhalte (Kurztext) einer Vorgabe. + +**Wichtige Felder**: +- `abschnitt` (ForeignKey → Vorgabe, on_delete=CASCADE): Referenz zur Vorgabe +- Erbt von `Textabschnitt` (siehe App: abschnitte): + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Kurztext-Abschnitt"` +- `verbose_name_plural = "Kurztext"` + +--- + +### Geltungsbereich + +**Zweck**: Speichert den Geltungsbereich-Abschnitt eines Dokuments. + +**Wichtige Felder**: +- `geltungsbereich` (ForeignKey → Dokument, on_delete=CASCADE): Referenz zum Dokument +- Erbt von `Textabschnitt` (siehe App: abschnitte): + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Geltungsbereichs-Abschnitt"` +- `verbose_name_plural = "Geltungsbereich"` + +--- + +### Einleitung + +**Zweck**: Speichert die Einleitungs-Abschnitte eines Dokuments. + +**Wichtige Felder**: +- `einleitung` (ForeignKey → Dokument, on_delete=CASCADE): Referenz zum Dokument +- Erbt von `Textabschnitt` (siehe App: abschnitte): + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Einleitungs-Abschnitt"` +- `verbose_name_plural = "Einleitung"` + +--- + +### Checklistenfrage + +**Zweck**: Repräsentiert eine Frage für die Checkliste zu einer Vorgabe. + +**Wichtige Felder**: +- `vorgabe` (ForeignKey → Vorgabe, on_delete=CASCADE, related_name='checklistenfragen') +- `frage` (CharField, max_length=255): Text der Checklistenfrage + +**Besonderheiten**: +- `__str__()` gibt den Fragetext zurück + +**Meta**: +- `verbose_name = "Frage für Checkliste"` +- `verbose_name_plural = "Fragen für Checkliste"` + +--- + +### VorgabenTable + +**Zweck**: Proxy-Modell für `Vorgabe` für die Darstellung von Vorgaben in Tabellenform. + +**Besonderheiten**: +- Proxy-Modell (kein eigenes Datenbankschema) +- Ermöglicht alternative Django-Admin-Ansicht +- Erbt alle Felder und Methoden von `Vorgabe` + +**Meta**: +- `proxy = True` +- `verbose_name = "Vorgabe (Tabellenansicht)"` +- `verbose_name_plural = "Vorgaben (Tabellenansicht)"` + +--- + +### Changelog + +**Zweck**: Dokumentiert Änderungen und Versionshistorie für Dokumente. + +**Wichtige Felder**: +- `dokument` (ForeignKey → Dokument, on_delete=CASCADE, related_name='changelog'): Referenz zum Dokument +- `autoren` (ManyToManyField → Person): Personen, die die Änderung vorgenommen haben +- `datum` (DateField): Datum der Änderung +- `aenderung` (TextField): Beschreibung der Änderung + +**Beziehungen**: +- Foreign Key zu `Dokument` +- Many-to-Many zu `Person` + +**Besonderheiten**: +- `__str__()` formatiert als "datum – dokumentnummer" + +**Meta**: +- `verbose_name = "Changelog-Eintrag"` +- `verbose_name_plural = "Changelog"` + +--- + +## App: abschnitte + +Modelle für die Verwaltung von Textabschnitten, die von mehreren Modellen geerbt werden. + +### AbschnittTyp + +**Zweck**: Klassifizierung von Textabschnitten (z. B. "Beschreibung", "Erklärung", "Anleitung"). + +**Wichtige Felder**: +- `abschnitttyp` (CharField, max_length=100, **PRIMARY KEY**): Name des Abschnitttyps + +**Besonderheiten**: +- `__str__()` gibt den Namen zurück + +**Meta**: +- `verbose_name_plural = "Abschnitttypen"` + +--- + +### Textabschnitt (abstrakt) + +**Zweck**: Abstrakte Basisklasse für Textinhalte, die mit anderen Modellen verknüpft sind. + +**Wichtige Felder**: +- `abschnitttyp` (ForeignKey → AbschnittTyp, on_delete=PROTECT, optional) +- `inhalt` (TextField, blank=True, null=True): Der Textinhalt +- `order` (PositiveIntegerField, default=0): Sortierreihenfolge + +**Besonderheiten**: +- Abstrakte Klasse (wird nicht direkt in der Datenbank gespeichert) +- Wird von anderen Modellen geerbt: `VorgabeLangtext`, `VorgabeKurztext`, `Geltungsbereich`, `Einleitung`, `Referenzerklaerung`, `Stichworterklaerung`, `RollenBeschreibung` + +**Meta**: +- `abstract = True` +- `verbose_name = "Abschnitt"` +- `verbose_name_plural = "Abschnitte"` + +--- + +## App: referenzen + +Modelle für die Verwaltung von Referenzen und Verweisen auf externe Standards. + +### Referenz (MPTT-Tree) + +**Zweck**: Hierarchische Verwaltung von Referenzen und externen Normen (z. B. ISO-Standards, Gesetze, übergeordnete Vorgaben). + +**Wichtige Felder**: +- `id` (AutoField, **PRIMARY KEY**) +- `name_nummer` (CharField, max_length=100): Nummer/Kennung der Referenz (z. B. "ISO 27001") +- `name_text` (CharField, max_length=255, blank=True): Ausführlicher Name/Beschreibung +- `oberreferenz` (TreeForeignKey zu self, optional): Parent-Referenz für Hierarchien +- `url` (URLField, blank=True): Link zur Referenz + +**Beziehungen**: +- Many-to-Many mit `Vorgabe` +- MPTT Tree-Struktur für hierarchische Referenzen + +**Wichtige Methoden**: + +- `Path()` → str + - Gibt die vollständige Pfad-Hierarchie als String zurück + - Format: "Referenz → Subreferenz → Unterreferenz (Beschreibung)" + - Beispiel: "ISO → 27000 → 27001 (Information Security Management)" + +**Besonderheiten**: +- Verwendet MPPT (Modified Preorder Tree Traversal) für Baumoperationen +- `get_ancestors(include_self=True)`: Gibt alle Vorfahren zurück +- `unterreferenzen`: Related_name für Kindreferenzen +- Sortierung: Nach `name_nummer` + +**Meta**: +- `verbose_name_plural = "Referenzen"` +- **MPTTMeta**: + - `parent_attr = 'oberreferenz'` + - `order_insertion_by = ['name_nummer']` + +--- + +### Referenzerklaerung + +**Zweck**: Speichert Erklärungen und zusätzliche Informationen zu einer Referenz. + +**Wichtige Felder**: +- `erklaerung` (ForeignKey → Referenz, on_delete=CASCADE): Referenz zur Referenz +- Erbt von `Textabschnitt`: + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Erklärung"` +- `verbose_name_plural = "Erklärungen"` + +--- + +## App: stichworte + +Modelle für die Verwaltung von Stichworte und Tags. + +### Stichwort + +**Zweck**: Einfache Tag/Keyword-Modell zur Kategorisierung von Vorgaben. + +**Wichtige Felder**: +- `stichwort` (CharField, max_length=50, **PRIMARY KEY**): Das Stichwort + +**Beziehungen**: +- Many-to-Many mit `Vorgabe` + +**Besonderheiten**: +- `__str__()` gibt das Stichwort zurück + +**Meta**: +- `verbose_name_plural = "Stichworte"` + +--- + +### Stichworterklaerung + +**Zweck**: Speichert Erklärungen zu Stichworten. + +**Wichtige Felder**: +- `erklaerung` (ForeignKey → Stichwort, on_delete=CASCADE): Referenz zum Stichwort +- Erbt von `Textabschnitt`: + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Erklärung"` +- `verbose_name_plural = "Erklärungen"` + +--- + +## App: rollen + +Modelle für die Verwaltung von Rollen und deren Beschreibungen. + +### Rolle + +**Zweck**: Definiert Rollen/Positionen im Unternehmen (z. B. "Geschäftsleiter", "IT-Sicherheit", "Datenschutzbeauftragter"). + +**Wichtige Felder**: +- `name` (CharField, max_length=100, **PRIMARY KEY**): Name der Rolle + +**Beziehungen**: +- Many-to-Many mit `Vorgabe` (über `relevanz`) + +**Besonderheiten**: +- `__str__()` gibt den Namen zurück +- Wird verwendet, um Rollen zu markieren, die von einer Vorgabe betroffen sind + +**Meta**: +- `verbose_name_plural = "Rollen"` + +--- + +### RollenBeschreibung + +**Zweck**: Speichert detaillierte Beschreibungen und Informationen zu einer Rolle. + +**Wichtige Felder**: +- `abschnitt` (ForeignKey → Rolle, on_delete=CASCADE): Referenz zur Rolle +- Erbt von `Textabschnitt`: + - `abschnitttyp` (ForeignKey → AbschnittTyp, optional) + - `inhalt` (TextField, blank=True, null=True) + - `order` (PositiveIntegerField, default=0) + +**Meta**: +- `verbose_name = "Rollenbeschreibungs-Abschnitt"` +- `verbose_name_plural = "Rollenbeschreibung"` + +--- + +## Allgemeine Hinweise zur Modellverwaltung + +### Primärschlüssel-Strategie +- Viele Modelle verwenden CharField-basierte Primärschlüssel (`name`, `nummer`, `stichwort`) +- Dies ermöglicht direkte Verwendung von Strings als Identifikatoren +- Vorteil: Lesbarkeit; Nachteil: Umbenennungen sind kritisch + +### On-Delete-Strategien +- **PROTECT**: Verwendet für wichtige Beziehungen (z. B. Dokumententyp, Thema, AbschnittTyp) + - Verhindert versehentliches Löschen von Daten, auf die verwiesen wird +- **CASCADE**: Verwendet für Unterkomponenten (z. B. Vorgabe → Dokument) + - Löscht abhängige Datensätze automatisch +- **SET_NULL**: Nur bei optionalen Referenzen (z. B. Oberreferenz in Referenz-Tree) + +### Validierungsmechanismen +- **Vorgabe.clean()**: Validiert Gültigkeitszeiträume +- **Vorgabe.find_conflicts()**: Prüft zeitliche Überschneidungen +- Wird von Django-Admin automatisch aufgerufen vor dem Speichern + +### MPTT (Modified Preorder Tree Traversal) +- Verwendet in `Referenz` für hierarchische Strukturen +- Ermöglicht effiziente Abfragen von Vorfahren und Nachkommen +- Zusätzliche Datenbank-Felder für Tree-Management (automatisch verwaltet) + +### Textabschnitt-Vererbung +- Mehrere Modelle erben von `Textabschnitt` +- Wird verwendet für Lang-/Kurztexte, Erklärungen, Beschreibungen +- `order`-Feld ermöglicht Sortierung mehrerer Abschnitte + +### Datumsverwaltung +- `gueltigkeit_von`: Immer erforderlich für Vorgaben +- `gueltigkeit_bis`: Optional; `None` bedeutet unbegrenzte Gültigkeit +- `_date_ranges_intersect()` prüft korrekt auf Überschneidungen mit None-Werten + +### Many-to-Many-Beziehungen +- Vielfach verwendet für flexible Zuordnungen (Autoren, Stichworte, Rollen, Referenzen) +- `related_name`-Attribute ermöglichen rückwärts Zugriff +- Beispiel: `dokument.vorgaben.all()`, `person.verfasste_dokumente.all()` + +--- + +## Zusammenfassung der Beziehungen + +``` +Dokumententyp ← Dokument +Person ← Dokument (Autoren/Prüfer) +Dokument → Vorgabe (1-to-Many) +Dokument → Geltungsbereich (1-to-Many) +Dokument → Einleitung (1-to-Many) +Dokument → Changelog (1-to-Many) + +Thema ← Vorgabe +Vorgabe → VorgabeLangtext (1-to-Many) +Vorgabe → VorgabeKurztext (1-to-Many) +Vorgabe → Checklistenfrage (1-to-Many) +Vorgabe ← Referenz (Many-to-Many) +Vorgabe ← Stichwort (Many-to-Many) +Vorgabe ← Rolle (Many-to-Many) + +Referenz → Referenz (Hierarchie via MPPT) +Referenz → Referenzerklaerung (1-to-Many) + +Stichwort → Stichworterklaerung (1-to-Many) + +Rolle → RollenBeschreibung (1-to-Many) + +AbschnittTyp ← Textabschnitt (von verschiedenen Modellen geerbt) +``` + +--- + +## Entwicklungsrichtlinien + +- Alle Modelle sollten aussagekräftige `__str__()`-Methoden haben +- `verbose_name` und `verbose_name_plural` sollten auf Deutsch sein (für Django-Admin) +- Validierungslogik (z. B. `clean()`) sollte implementiert werden für komplexe Business-Logic +- Related-Names sollten aussagekräftig und konsistent sein +- Textinhalte sollten die `Textabschnitt`-Basisklasse erben +- Datumsverwaltung: Immer auf None-Werte bei `gueltigkeit_bis` achten, wenn Vorgaben noch aktiv sind. diff --git a/argocd/deployment.yaml b/argocd/deployment.yaml index ab2534c..a9541c5 100644 --- a/argocd/deployment.yaml +++ b/argocd/deployment.yaml @@ -25,7 +25,7 @@ spec: mountPath: /data containers: - name: web - image: git.baumann.gr/adebaumann/vui:0.957-xss + image: git.baumann.gr/adebaumann/vui:0.958 imagePullPolicy: Always ports: - containerPort: 8000 diff --git a/pages/templates/base.html b/pages/templates/base.html index e377297..cd71670 100644 --- a/pages/templates/base.html +++ b/pages/templates/base.html @@ -215,7 +215,7 @@
Version {{ version|default:"0.957-xss" }}
+Version {{ version|default:"0.958" }}