Beheer (Frontend)
UI-Architectuur & Design
De module Beheer bestaat uit een hoofdscherm BeheerScreen dat secties op een enkele pagina samenstelt, plus een aantal losse subschermen (audit-log, e-mailafzender, gebruikersdetail) en twee publieke schermen (uitnodiging accepteren, TOTP opnieuw inrichten). Het hoofdscherm hergebruikt API's en componenten uit features/billing, features/auth, features/agenda (de ontvangerselectie) en de backend-modules tenant en rbac. De teamberichten praten met de eigen backend-module beheer.
De secties op BeheerScreen worden conditioneel getoond op basis van permissies:
BillingSection: stelt de billing-componenten uitfeatures/billingsamen (verbruik, abonnement, facturen, betaalmethoden, limieten).TenantInfoSection: apotheeknaam, adres en logo, met crop-modal op web (LogoCropModal.web.tsx) en automatische schaling op native.- Sectie 'Gebruikers':
GebruikersList(gepagineerde tabel) met acties bewerken, verwijderen en TOTP-reset, plus de knoppen 'E-mail versturen' en 'Push versturen'. - Sectie 'Uitgenodigde gebruikers': openstaande uitnodigingen met acties opnieuw versturen of intrekken.
- Sectie 'Functies':
FunctiesListmet aanmaak-, bewerk- en verwijderacties. UnregisterSection: definitieve afmelding van de apotheek.
De teamberichten lopen via MailEmployeesModal (met een aparte MailEmployeesPreviewModal voor het server-side voorbeeld) en PushEmployeesModal. De ontvangerselectie (iedereen of een selectie van functies en personen) hergebruikt de UI van de agenda. De e-mailafzender wordt beheerd in EmailAfzenderScreen met SendingDomainCard, AddSendingDomainModal, DnsChecklist, DnsHelpBanner en SendTestEmailModal. De audit-log staat in AuditLogScreen (gepagineerde tabel met filters).
Destructieve admin-acties (gebruiker verwijderen, TOTP resetten, uitnodiging intrekken, apotheek afmelden) gaan via TotpConfirmModal, dat een TOTP-code of biometrie vraagt. Het verwijderen van een functie gaat via ConfirmDialog.
graph TD
A[app/beheer/index.tsx] --> B[BeheerScreen]
B --> C[BillingSection]
B --> D[TenantInfoSection]
B --> E[GebruikersList]
B --> F[FunctiesList]
B --> G[UnregisterSection]
B --> M1[NieuweGebruikerModal]
B --> M2[EditGebruikerModal]
B --> M3[NieuweOrEditFunctieModal]
B --> M4[MailEmployeesModal]
M4 --> M5[MailEmployeesPreviewModal]
B --> M6[PushEmployeesModal]
F --> P[FunctiePermissiesEditor]
AL[app/beheer/audit-log.tsx] --> ALS[AuditLogScreen]
EA[app/beheer/email-afzender.tsx] --> EAS[EmailAfzenderScreen]
EAS --> SDC[SendingDomainCard]
State & Data Flow
BeheerScreen houdt lokale staat bij voor gebruikers, functies en openstaande uitnodigingen en haalt deze op via beheerApi. TenantInfoSection heeft een eigen fetch via tenantApi. BillingSection gebruikt de billing-API uit features/billing. AuditLogScreen gebruikt auditLogApi met paginering en filters, EmailAfzenderScreen gebruikt sendingDomainsApi.
Mutaties (uitnodigen, bewerken, verwijderen, TOTP-reset, uitnodiging opnieuw versturen of intrekken) verlopen via beheerApi en werken na succes de lokale lijst bij. Logo-uploads gaan via multipart/form-data naar POST /api/tenant/logo/; de backend slaat het bestand op in S3 en geeft een signed URL terug. Op native wordt het beeld vooraf met expo-image-manipulator geschaald naar 512 x 512, op web volgt een crop-stap in LogoCropModal.
De teamberichten lopen in twee stappen. De e-mailcomposer vraagt eerst een server-side voorbeeld op via previewEmployeeMail, zodat het voorbeeld byte-identiek is aan de verzonden mail. Bij verzenden roept de composer sendEmployeeMail aan, de pushcomposer sendEmployeePush. Alle drie de endpoints (voorbeeld, mail verzenden, push verzenden) vereisen een recente step-up van de beheerder; de gedeelde step-up-flow (TOTP of biometrie) handelt de uitdaging af voordat het verzoek slaagt.
sequenceDiagram
participant UI as MailEmployeesModal
participant Api as beheerApi.ts
participant BE as Backend (features.beheer)
UI->>Api: previewEmployeeMail(subject, body)
Api->>BE: POST /api/beheer/mail-employees/preview/ (step-up vereist)
BE-->>Api: { subject, html, text, preview_logo_src }
Api-->>UI: voorbeeld (byte-identiek)
UI->>Api: sendEmployeeMail(subject, body, ontvangers)
Api->>BE: POST /api/beheer/mail-employees/ (step-up vereist)
BE-->>Api: { sent_to }
Api-->>UI: aantal verzonden
Navigatie & Routing
/beheer(app/beheer/index.tsx): hoofdscherm. Redirect naar/loginzonder sessie;ErrorStatemet variantforbiddenzondersettings.view./beheer/gebruiker/[id](app/beheer/gebruiker/[id].tsx): detailweergave van een gebruiker viaGebruikerDetailScreen./beheer/audit-log(app/beheer/audit-log.tsx): audit-log viaAuditLogScreen, vereistsettings.view_audit_log./beheer/email-afzender(app/beheer/email-afzender.tsx): e-mailafzender viaEmailAfzenderScreen, vereistsettings.manage_tenant./beheer/billing/activerenen/beheer/billing/done: deeplinks vanuit de Stripe-flow; vereisensettings.manage_billing./uitnodiging/[token](app/uitnodiging/[token].tsx): publieke route voor het accepteren van een uitnodiging viaUitnodigingScreen./totp-reset/[token](app/totp-reset/[token].tsx): publieke route voor het opnieuw inrichten van TOTP viaTotpResetScreen.
Gating binnen BeheerScreen gebeurt op basis van state.permissions. De checks settings.view, settings.manage_users, settings.manage_roles, settings.manage_tenant, settings.manage_billing en settings.view_audit_log bepalen welke secties en acties zichtbaar zijn.
Bestandsstructuur & Verantwoordelijkheden
src/features/beheer/screens/BeheerScreen.tsx: hoofdscherm dat alle secties orchestreert, fetches initieert en modals beheert.src/features/beheer/screens/GebruikerDetailScreen.tsx: detailweergave per gebruiker.src/features/beheer/screens/AuditLogScreen.tsx: gepagineerde audit-log met filters op gebeurtenis, ernst en periode.src/features/beheer/screens/EmailAfzenderScreen.tsx: beheer van e-mailafzenderdomeinen en DNS-controle.src/features/beheer/screens/UitnodigingScreen.tsx: publieke pagina voor het accepteren van een uitnodiging (wachtwoord instellen, eventueel TOTP-setup).src/features/beheer/screens/TotpResetScreen.tsx: publieke pagina voor het opnieuw inrichten van TOTP na een admin-reset.src/features/beheer/components/GebruikersList.tsx: gepagineerde lijst van actieve gebruikers (usePagedTable) met inline acties.src/features/beheer/components/NieuweGebruikerModal.tsx/EditGebruikerModal.tsx: uitnodigen en bewerken van een gebruiker.src/features/beheer/components/FunctiesList.tsx/NieuweOrEditFunctieModal.tsx/FunctiePermissiesEditor.tsx: rollen en hun permissies, gevoed doorGET /api/rbac/catalog/.src/features/beheer/components/MailEmployeesModal.tsx/MailEmployeesPreviewModal.tsx: e-mailcomposer en het server-side voorbeeld.src/features/beheer/components/PushEmployeesModal.tsx: pushcomposer (titel en bericht, geen voorbeeld).src/features/beheer/components/TenantInfoSection.tsx+LogoCropModal.tsx/LogoCropModal.web.tsx: apotheekgegevens en logo, inclusief crop- en upload-flow.src/features/beheer/components/SendingDomainCard.tsx,AddSendingDomainModal.tsx,DnsChecklist.tsx,DnsHelpBanner.tsx,SendTestEmailModal.tsx: e-mailafzender en DNS.src/features/beheer/components/BillingSection.tsx+Billing*: samenstelling van billing-componenten.src/features/beheer/components/UnregisterSection.tsx: afmeldknop met TOTP- of biometriebevestiging viauseStepUp.src/features/beheer/components/skeletons/: skeleton-varianten voor de hoofdsecties tijdens het laden.src/features/beheer/api/beheerApi.ts: client voor de teamberichten en voor/api/auth/admin/...en/api/rbac/....src/features/beheer/api/auditLogApi.ts: client voor/api/auth/admin/audit-log/.src/features/beheer/api/sendingDomainsApi.ts: client voor/api/settings/email/sending-domains/.src/features/beheer/api/tenantApi.ts: client voor/api/tenant/info/,/api/tenant/logo/,/api/tenant/billing/en de afmelding.src/features/beheer/types/beheer.ts/types/sendingDomains.ts: typedefinities.
Belangrijke bestanden
frontend/app/beheer/index.tsxfrontend/src/features/beheer/screens/BeheerScreen.tsxfrontend/src/features/beheer/components/MailEmployeesModal.tsxfrontend/src/features/beheer/components/PushEmployeesModal.tsxfrontend/src/features/beheer/api/beheerApi.tsfrontend/src/features/beheer/api/sendingDomainsApi.ts