Ga naar inhoud

Team (Backend)

Technisch Ontwerp

De module Team ontsluit medewerkersgegevens binnen dezelfde tenant. Team heeft geen eigen modellen; het aggregeert User, ProfileSettings (privacy) en Role (functietitel). De kernlogica zit in services.py en past de privacy-filtering server-side toe: alleen gebruikers met visible_to_team=True komen in de lijst, en telefoonnummer, e-mailadres en werkdagen worden alleen meegegeven als de medewerker de bijbehorende deeloptie heeft aangezet.

De query bouwt op auth.services.membership.member_users_qs(tenant) met is_active=True, plus select_related/prefetch_related op ProfileSettings en roles. Het telefoonnummer wordt versleuteld opgeslagen en pas ontsleuteld wanneer share_phone=True, zodat versleutelde velden niet onnodig worden gelezen. Vaste werkdagen komen uit features.rooster.services.get_vaste_werkdagen_by_employee en worden alleen opgehaald als minstens een teamlid op de pagina werkdagen deelt. De functietitel komt uit _role_label_for_user (alfabetisch samengevoegde rolnamen, anders "Geen functie gekoppeld"). Heeft een gebruiker geen ProfileSettings, dan geldt volledige zichtbaarheid als default.

flowchart TD
    REQ[GET /api/team/members/] --> P{paginate == '1'?}
    P -->|Nee| L1[services.list_visible_team_members] --> FLAT[Response: items]
    P -->|Ja| L2[services.list_visible_team_members_page] --> Q[_apply_search op naam en functie]
    Q --> PG[clamp_page_size 10/50/100 + parse_page]
    PG --> FILTER[_member_payload: privacy-filtering]
    FILTER --> PAGED[Response: results, page, total, total_pages, next]
    FILTER --> S3[generate_signed_url avatar]

Datamodel (ERD)

Het teamoverzicht aggregeert User (basisgegevens), ProfileSettings (privacy-voorkeuren en avatar) en Role (functietitels).

erDiagram
    User ||--o{ Role : "users m2m"
    User ||--|| ProfileSettings : "profile_settings"
    User {
        int id PK
        string first_name
        string last_name
        string email
        string phone_number "versleuteld"
        boolean is_active
    }
    ProfileSettings {
        int id PK
        int user_id FK
        boolean visible_to_team
        boolean share_phone
        boolean share_email
        boolean share_work_days_with_team
        string avatar_s3_key
    }
    Role {
        int id PK
        int tenant_id FK
        string name
        string code
    }

API & Communicatie

GET /api/team/members/: haalt de zichtbare teamleden op. De view kent twee responsvormen.

  • Zonder paginate=1 (de standaard, gebruikt door de frontend): de platte vorm { "items": [...] }.
  • Met paginate=1: de gepagineerde vorm { "results": [...], "page", "page_size", "total", "total_pages", "next" }. Parameters: page (1-gebaseerd), page_size (gesnapt naar 10, 50 of 100; ongeldige waarden vallen terug op 10) en q (zoeken op voornaam, achternaam of functienaam).

Elk teamlid bevat id, first_name, last_name, role, avatar_url (signed S3-URL of leeg), phone_number, email, vaste_werkdagen (lijst van {day_index, dagdeel_name}) en een privacy-object met share_phone, share_email, share_work_days en visible_to_team. Velden waarvoor geen toestemming geldt, komen leeg terug.

Foutafhandeling & Statuscodes

  • 200 OK: succesvolle aanvraag. Zijn er geen zichtbare medewerkers, dan is items (of results) leeg.
  • 401 Unauthorized: de gebruiker is niet geauthenticeerd.

Autorisatie & Beveiliging

  • Toegang: de view gebruikt uitsluitend IsAuthenticated. Team is een basismodule zonder required_permission; er is geen RBAC-gate.
  • Tenant-isolatie: member_users_qs(tenant) beperkt de lijst tot actieve medewerkers van de eigen apotheek.
  • Privacy-enforcement: filtering gebeurt server-side in _member_payload. Velden zonder toestemming worden leeggelaten en het telefoonnummer wordt alleen ontsleuteld bij share_phone=True. Avatars worden via een signed S3-URL geleverd.

Bestandsstructuur & Verantwoordelijkheden

  • backend/features/team/views.py: TeamMemberListView, die de platte en gepagineerde respons afhandelt.
  • backend/features/team/services.py: list_visible_team_members, list_visible_team_members_page, _member_payload, _base_team_queryset, _apply_search en _role_label_for_user.
  • backend/features/team/serializers.py: TeamMemberSerializer, TeamMemberPrivacySerializer, VasteWerkdagTeamSerializer en TeamMemberListResponseSerializer.
  • backend/features/team/urls.py: het members/ endpoint.

Belangrijke bestanden

  • backend/features/team/services.py
  • backend/features/team/views.py
  • backend/features/team/serializers.py

API & Communicatie (Swagger)