Zum Inhalt

Organizations-App-Referenz

Die Organizations-App bietet Mandantenfähigkeit mit rollenbasierter Zugriffskontrolle (RBAC). Benutzer können mehreren Organisationen angehören, jede mit eigenen Einstellungen, Mitgliedern und Daten. Diese App ist die Grundlage, von der alle anderen Apps für Berechtigungsprüfungen und Datenfilterung abhängen.

Übersicht

Speicherort: app/organizations/

Zweck: Mandantenfähige Organisationsverwaltung mit RBAC

Wichtige Modelle: Organization, OrganizationMembership, OrganizationInvitation, OrganizationSettings

Verwendet von: Alle anderen Apps hängen von dieser App für Berechtigungsprüfungen, organisationsbezogene Datenfilterung und Berechtigungs-Mixins ab.


Dateistruktur

organizations/
├── models.py                # 4 Modelle
├── views/                   # Views-Paket (3 Module)
│   ├── __init__.py          # Re-exportiert alle 16 Views
│   ├── organization_views.py    # 5 CBVs + 3 FBVs (CRUD, Wechsel, Einstellungen)
│   ├── member_views.py          # 3 FBVs (Mitgliederliste, Entfernen, Rollenwechsel)
│   └── invitation_views.py      # 5 FBVs (Senden, Liste, Annehmen, Ablehnen, Meine)
├── forms.py                 # OrganizationSettingsForm
├── urls.py                  # 16 URL-Patterns
├── signals.py               # Auto-Erstellung Standard-Org bei Benutzererstellung
├── middleware.py             # OrganizationMiddleware + switch_organization()
├── utils.py                 # 11 Berechtigungs-Hilfsfunktionen
├── mixins.py                # OrgPermissionMixin, DelegatedPermissionMixin
├── admin.py                 # Django-Admin-Konfiguration (4 Model-Admins + 1 Inline)
├── services/
│   ├── __init__.py
│   └── numbering_service.py # Chargen-/Eimer-Nummerierung
└── templates/organizations/ # 13 HTML-Templates

Modelle

Siehe Datenbankmodelle - Organizations-App für vollständige Feldreferenz.

Organization

Mandantenfähige Entität. Felder umfassen Name, org_type (personal/family/cooperative/commercial/club), Beschreibung, Logo (auf 300x300px skaliert) und Aktiv-Status.

Wichtige Methoden:

  • get_owners() -- QuerySet der Inhaber-Benutzer
  • get_admins() -- QuerySet der Admin- und Inhaber-Benutzer
  • user_is_member(user) -- bool
  • user_role(user) -- Rollen-String oder None

OrganizationMembership

Benutzer-Organisations-Beziehung mit rollenbasiertem Zugriff. Erzwingt eine Eindeutigkeitsbedingung auf (organization, user).

Rollen: owner, admin, member, viewer

Wichtige Methoden:

  • can_manage_members() -- nur owner/admin
  • can_delete_organization() -- nur owner
  • can_edit_resources() -- owner/admin/member
  • can_delete_resources() -- nur owner/admin

OrganizationInvitation

E-Mail-Einladungssystem mit UUID-Tokens, 7-Tage-Ablauf und Status-Verfolgung (pending/accepted/declined/expired).

Status-Übergänge: pending kann zu accepted, declined oder expired wechseln. Alle drei sind Endzustände.

Wichtige Methoden:

  • is_valid() -- prüft, ob ausstehend und nicht abgelaufen; markiert automatisch als abgelaufen, wenn das Ablaufdatum überschritten ist
  • accept(user) -- erstellt Mitgliedschaft und markiert als akzeptiert
  • decline() -- markiert als abgelehnt
  • effective_status -- Property, das den wahren Status einschließlich impliziter Ablaufs berechnet

OrganizationSettings

Organisationsspezifische Einstellungen: Datumsformat, Zeitzone, Einheitensystem, Sprache, Branding-Farben (primär/sekundär), MFA-Richtlinie, E-Mail-Benachrichtigungseinstellungen und Chargen-/Eimer-Nummerierungsvorlagen.


Middleware

OrganizationMiddleware

Speicherort: app/organizations/middleware.py

Fügt jeder Anfrage Organisationskontext hinzu:

Attribut Beschreibung
request.current_organization Aktive Organisation (oder None für den "Alle Organisationen"-Modus)
request.user_organizations Alle Organisationen des Benutzers (QuerySet)
request.org_colors Organisations-Branding-Farben (Dict mit primary- und secondary-Schlüsseln)

Priorität der Organisationsauswahl:

  1. Session-Variable current_organization_id (Benutzer hat Organisation gewechselt oder "Alle" gewählt)
  2. Erste Organisation nach Mitgliedschafts-Beitrittsdatum
  3. None (nicht authentifiziert)

Wenn der Session-Wert explizit auf None gesetzt ist, sieht der Benutzer Daten aus allen seinen Organisationen. Wenn die Session-Variable fehlt, verwendet das System standardmäßig die erste Organisation.

switch_organization() -- Hilfsfunktion zum Wechseln der aktuellen Organisation via Session. Übergeben Sie None, um zur "Alle Organisationen"-Ansicht zu wechseln.


Berechtigungs-Hilfsfunktionen

Speicherort: app/organizations/utils.py

11 Funktionen für zentralisierte Berechtigungsprüfungen:

get_user_role(user, organization)           # Gibt Rolle oder None zurück
get_user_organizations(user)                # Gibt QuerySet zurück
user_is_member(user, organization)          # Gibt bool zurück
user_can_view(user, resource)               # Gibt bool zurück
user_can_create(user, organization)         # Gibt bool zurück
user_can_edit(user, resource)               # Gibt bool zurück
user_can_delete(user, resource)             # Gibt bool zurück
user_can_manage_members(user, organization) # Gibt bool zurück
user_can_delete_org(user, organization)     # Gibt bool zurück
user_can_change_org_settings(user, org)     # Gibt bool zurück
filter_by_user_organizations(queryset, user, request) # Gibt gefiltertes QuerySet zurück

Berechtigungsmatrix:

Aktion Inhaber Admin Mitglied Betrachter
Ressourcen anzeigen Ja Ja Ja Ja
Ressourcen erstellen Ja Ja Ja Nein
Eigene Ressourcen bearbeiten Ja Ja Ja Nein
Alle Ressourcen bearbeiten Ja Ja Nein Nein
Ressourcen löschen Ja Ja Nein Nein
Mitglieder verwalten Ja Ja Nein Nein
Einstellungen ändern Ja Ja Nein Nein
Organisation löschen Ja Nein Nein Nein

Siehe Berechtigungssystem für detaillierte Dokumentation.


Berechtigungs-Mixins

Speicherort: app/organizations/mixins.py

OrgPermissionMixin

Wiederverwendbarer Model-Mixin für organisationsbasierte Berechtigungsprüfung. Fügen Sie ihn zu jedem Modell hinzu, das einen organization-ForeignKey und optional ein created_by-Feld hat.

Methoden:

  • user_can_view(user) -- jedes aktive Organisationsmitglied kann anzeigen
  • user_can_edit(user) -- Admins/Inhaber können alles bearbeiten; Mitglieder können eigene Datensätze bearbeiten
  • user_can_delete(user) -- nur Admins/Inhaber können löschen

Konfiguration: Setzen Sie das Klassenattribut permission_owner_field auf den Namen des Feldes, das den Ersteller des Datensatzes speichert (Standard: 'created_by').

Verwendet von: QueenBreeding, ColonySplit, InventoryItem, InventoryTransaction, ProductSale, WarehouseLocation

DelegatedPermissionMixin

Mixin für untergeordnete Modelle, die Berechtigungsprüfungen an ein übergeordnetes Modell delegieren (z.B. Statusänderungsdatensätze, die Berechtigungen von ihrer übergeordneten Entität erben).

Konfiguration: Setzen Sie das Klassenattribut permission_delegate_field auf den Namen des ForeignKey, der auf das übergeordnete Modell verweist.

Verwendet von: BreedingStatusChange (delegiert an breeding), SplitStatusChange (delegiert an split)


Views

Organisation CRUD

View Typ Zweck
OrganizationListView CBV Liste aller Organisationen des Benutzers mit Mitgliederzahlen
OrganizationDetailView CBV Organisationsdetails, Mitglieder, Bienenstock-/Aktivitätsstatistiken
OrganizationCreateView CBV Organisation erstellen, automatisch Inhaber-Mitgliedschaft für Ersteller
OrganizationUpdateView CBV Organisationsdetails aktualisieren (Name, Typ, Beschreibung, Logo)
OrganizationDeleteView CBV Löschen mit Kaskaden-Warnung und Anzeige abhängiger Datenzahlen
switch_org_view FBV Zu anderer Organisation wechseln
switch_to_all_orgs_view FBV Zu "Alle Organisationen"-Ansicht wechseln
organization_settings_view FBV Organisationseinstellungen anzeigen und aktualisieren

Mitgliederverwaltung

View Typ Zweck
member_list_view FBV Aktive Mitglieder mit Rollen auflisten
member_remove_view FBV Mitglied entfernen (verhindert Selbstentfernung und Inhaber-Entfernung durch Nicht-Inhaber)
member_role_change_view FBV Mitgliederrolle ändern (nur Inhaber können zum Inhaber befördern)

Einladungsverwaltung

View Typ Zweck
invitation_send_view FBV E-Mail-Einladung senden, Duplikate und bestehende Mitglieder validieren
invitation_list_view FBV Alle Einladungen für eine Organisation auflisten
invitation_accept_view FBV Einladung annehmen, E-Mail-Übereinstimmung prüfen, Mitgliedschaft erstellen
invitation_decline_view FBV Einladung ablehnen, E-Mail-Übereinstimmung prüfen
my_invitations_view FBV Gültige ausstehende Einladungen für den aktuellen Benutzer anzeigen

Formulare

OrganizationSettingsForm

Speicherort: app/organizations/forms.py

Formular zur Bearbeitung von Organisationseinstellungen.

Felder: date_format, time_zone, unit_system, language, primary_color, secondary_color, E-Mail-Benachrichtigungsschalter, Chargen-/Eimer-Nummerierungsformat-Felder (einschließlich benutzerdefinierter Formateingaben).

Widgets: HTML5-Farbwähler für Branding-Farben, Auswahl-Dropdowns für Nummerierungsformat, Texteingaben für benutzerdefinierte Nummerierungsvorlagen.

Validierung: Benutzerdefinierte Chargen- und Eimer-Format-Validierung über NumberingValidator, wenn die Option "Benutzerdefiniert" ausgewählt ist.


Services

NumberingService

Speicherort: app/organizations/services/numbering_service.py

Generiert Chargen- und Eimer-Kennungen mit konfigurierbaren Vorlagen.

Wichtige Methoden:

  • generate_charge_identifier(organization, honey_type, harvest_year) -- gibt str zurück
  • generate_bucket_number(organization, charge_identifier) -- gibt str zurück

Verwendet select_for_update() für thread-sichere Sequenz-Inkrementierung.

Tokens: {YEAR}, {TYPE}, {LABEL}, {SEQ} für Chargen; {CHARGE}, {SEQ}, {EIMER}, {BUCKET} für Eimer.

NumberingValidator

Validiert benutzerdefinierte Nummerierungsvorlagen. Prüft Token-Existenz, Format-Spezifikationen und Eindeutigkeitsanforderungen.


Signale

create_default_organization

  • Auslöser: post_save auf User (nur bei Erstellung)
  • Aktion: Erstellt automatisch eine persönliche Organisation namens "{username}'s Beekeeping" mit Inhaber-Mitgliedschaft für jeden neuen Benutzer
  • Zweck: Stellt sicher, dass alle Daten von Anfang an einer Organisation zugehören

URL-Patterns

organizations/                                → OrganizationListView (organization-list)
organizations/create/                         → OrganizationCreateView (organization-create)
organizations/<pk>/                           → OrganizationDetailView (organization-detail)
organizations/<pk>/edit/                      → OrganizationUpdateView (organization-update)
organizations/<pk>/delete/                    → OrganizationDeleteView (organization-delete)
organizations/<pk>/switch/                    → switch_org_view (organization-switch)
organizations/switch/all/                     → switch_to_all_orgs_view (organization-switch-all)
organizations/<pk>/members/                   → member_list_view (member-list)
organizations/<pk>/members/<user_id>/remove/  → member_remove_view (member-remove)
organizations/<pk>/members/<user_id>/change-role/ → member_role_change_view (member-role-change)
organizations/<pk>/invite/                    → invitation_send_view (invitation-send)
organizations/<pk>/invitations/               → invitation_list_view (invitation-list)
organizations/invitations/accept/<token>/     → invitation_accept_view (invitation-accept)
organizations/invitations/decline/<token>/    → invitation_decline_view (invitation-decline)
organizations/my-invitations/                 → my_invitations_view (my-invitations)
organizations/<pk>/settings/                  → organization_settings_view (organization-settings)

Siehe auch