Partner
Praxisnetz Nürnberg Süd e.V.
Case study08
Regional appointment exchange for medical practices with specialty-based search, secure booking and automated billing

Partner
Praxisnetz Nürnberg Süd e.V.
Industry
Healthcare
Core technologies
React · Express · PostgreSQL
At a glance
For Praxisnetz Nürnberg Süd e.V., DuoByte built a closed web platform where member practices offer open appointments to each other and book them for their patients. Every booking triggers confirmations to both practices and two PDF invoices with sequential numbers. Members get access only after confirming their email address and being approved by an administrator.
Our role: DuoByte built the platform end to end: data model, backend, frontend, invoicing and automated deployment.
Project work
How the project came together: from the context and requirements through implementation to where it stands today.
Context
Praxisnetz Nürnberg Süd e.V. was founded in 1998 as a registered association and brings together primary care physicians, specialists and other healthcare providers in and around Nuremberg. The association runs continuing education and quality circles, develops shared care pathways and works with hospitals, pharmacies and other networks.
The appointment platform connects medical practices, psychotherapists, medical care centers (MVZ) and hospitals. Appointments between these organizations used to be arranged by phone or through individual personal contacts. Finding out whether another practice had capacity meant calling and asking.
Challenge
The network needed a closed platform where practices publish open time slots and other members book them for specific patients. That requires clear rules: a slot can only be taken once, even if two practices try to book it at the same moment. A practice must not offer overlapping slots or book its own appointments.
Every successful referral also has to be invoiced. Each of the two practices involved needs its own invoice with a sequential number, and the invoice must not change later, even if a practice updates its address or bank details afterward.
Because the platform handles patient names and the practices' bank details, an email address alone cannot be enough to get in. New members have to confirm their address and be approved by the network. Patient names on a booked appointment are visible only to the two practices involved, and an invoice only to its recipient.
Solution
Practices create open appointments with date, time and duration and assign one or more appointment types. In addition to the centrally maintained types, each practice can define its own labels, such as "acute consultation". The system stores them as personal templates for later slots.
The search shows all open, upcoming appointments from other practices as a list, a week view or a month view. Users filter by date range, time window, specialty, appointment type or free text. For each offer, the searching practice sees the provider's name, specialties and contact details.
When booking, the practice enters the patient's name and picks one of the appointment types the provider allowed. Both sides immediately receive an email with date, time, appointment type and the other practice's contact details, with the invoice attached as a PDF. Under "My appointments" each practice sees what it has offered and booked, and its invoices are available for download in a separate area.
When a member is deactivated, the system automatically cancels that member's open slots. The practice receives an Excel list of its already booked appointments, including the other side's contact details, so no arrangement gets lost. Network administrators have their own tools:
Implementation
The frontend is a React 19 application with TypeScript, Vite and Tailwind CSS, with TanStack Query keeping API data current. The backend runs on Express 5 and TypeScript, and Prisma maps the data model to PostgreSQL. Every request is validated against Zod schemas before it reaches the business logic.
Booking is implemented as a conditional update: the database marks a slot as booked only if it is still open at that moment. If two practices try at the same time, the second one gets a clear message instead of a double booking. When a slot is created, the backend checks whether it overlaps with open or booked slots of the same practice.
Invoice numbers come from a per-year counter that is incremented in the same database transaction that creates the invoice. Each invoice stores a snapshot of recipient and issuer data, and the PDF generated with PDFKit is kept unchanged in the database. A uniqueness constraint prevents a second invoice for the same booking and role.
The invoice states that the amount is collected by SEPA direct debit and shows the IBAN only in masked form, and frontend and backend both verify German IBANs by their check digits at registration. Passwords are stored only as hashes, and short-lived access tokens are renewed through refresh tokens that are replaced on every renewal. Login, password reset and address lookup are rate limited, and address autocomplete via OpenRouteService runs through the backend so the API key never reaches the browser.
A multi-stage Docker build produces one image for frontend and backend, and the container applies pending Prisma migrations on startup. GitHub Actions deploys changes separately to a development and a production environment, with Nginx handling TLS and reverse proxying. Logs record method, path, status and response time, but no request content.
Outcome
Members of the practice network see other practices' open appointments in one place and book them directly for their patients. Confirmation and invoice are created with the booking itself, with no extra administrative step.
Network administrators manage memberships, specialties, appointment types and invoice issuer data in the same interface. Data model, migrations and deployment are versioned in the repository, so the platform can be developed further in a traceable way.
System architecture
Technologies were combined to suit the task, operating model and long-term maintainability.
Related services
Backend experience from Germany's ePA, an appointment platform for a practice network, and architectures that account for GDPR Article 9 and Section 393 SGB V.
Learn moreProtected portals for customers, dealers and members: orders, bookings and documents as self-service, with clear roles and permissions.
Learn moreKeep exploring
Next case study

Your project
Tell us what your system needs to do. We bring structure to requirements, architecture and delivery.