@startuml
title "Datenmodell: Personen_und_Vereine_Context"

!theme vibrant

package "Personen & Vereine" as PersonenContext {

    ' Eine Person ist ein Aggregate Root, das seine persönlichen Details,
    ' Adressen, Kontakte und Mitgliedschaften bündelt.
    class Person <<(A,green) Aggregate Root>> {
        ' Primärschlüssel aus LIZENZ01.DAT
        + oepsSatzNrPerson : VARCHAR(6)
        --
        + name : PersonenNameVO
        + geburtsdatum : Date
        + geschlecht : GeschlechtVO
        + nationalitaet : NationalitaetVO [cite: 6, 149, 181]
        + feiId : VARCHAR(10)
        + status : PersonenStatusVO ' z.B. Aktiv, Gesperrt
        --
        ' Methoden des Aggregates
        + aendereAdresse(neueAdresse)
        + fuegeMitgliedschaftHinzu(verein, mitgliedsNr)
        + setzeStatus(neuerStatus)
    }

    ' Ein Verein ist ebenfalls ein Aggregate Root.
    class Verein <<(A,green) Aggregate Root>> {
        ' Primärschlüssel aus VEREIN01.DAT
        + oepsVereinsNr : VARCHAR(4)
        --
        + name : VARCHAR(50)
        + bundesland : BundeslandVO
        ' Weitere Vereinsdetails wie Adresse, Kontakt...
    }

    ' Eine Entität innerhalb des Person-Aggregates. Sie hat eine eigene Identität,
    ' wird aber immer über die Person verwaltet.
    entity Mitgliedschaft {
        + mitgliedschaftId : UUID
        --
        ' Referenz zum Verein-Aggregat
        # oepsVereinsNr : VARCHAR(4) <<FK>>
        ' MITGLIEDSNUMMER aus LIZENZ01.DAT
        + mitgliedsNrImVerein : VARCHAR(8)
        + istHauptmitgliedschaft : boolean
        + von : Date
        + bis : Date
    }

    ' -- Value Objects (VOs) --
    ' VOs haben keine eigene Identität, sie beschreiben Eigenschaften.

    class PersonenNameVO <<VO>> {
        + familienname : string
        + vorname : string
    }

    class AdresseVO <<VO>> {
      + strasse : string
      + hausnummer: string
      + plz: string
      + ort: string
      + land: string
    }

    class KontaktVO <<VO>> {
      + typ: KontaktTyp ' Email, Telefon, Mobil
      + wert: string
    }

    ' -- Beziehungen --
    ' Das Person-Aggregat besitzt seine Mitgliedschaften (Komposition).
    Person "1" *-- "0..*" Mitgliedschaft
    ' Das Person-Aggregat nutzt Value Objects zur Beschreibung.
    Person "1" o-- "1" PersonenNameVO
    Person "1" o-- "0..*" AdresseVO
    Person "1" o-- "0..*" KontaktVO

    ' Die Mitgliedschaft verweist auf das Verein-Aggregat.
    ' Dies ist eine lose Kopplung über die ID, keine Komposition.
    Mitgliedschaft ..> Verein : "bezieht sich auf"
}

note right of Person
  **Aggregate Root: Person**
  Dieses Objekt ist der zentrale Einstiegspunkt
  für alle Operationen, die eine Person betreffen.

  **Beispiel:**
  Um eine Mitgliedschaft hinzuzufügen, ruft man
  `person.fuegeMitgliedschaftHinzu(...)` auf.
  Das `Person`-Objekt stellt sicher, dass z.B.
  nur eine Hauptmitgliedschaft existiert.
  Man ändert nicht direkt das Mitgliedschafts-Objekt.
end note

@enduml
