A complete practice management system for a psychology practice in Namibia. Patient files, appointments, invoicing, medical aid billing, remittance processing, and 40+ reports — all accessible from a Flutter desktop app.
Behind every session is paperwork. Patient files with diagnoses, clinical notes, and treatment history. Appointments across multiple clinicians with different working hours. Invoices that need to be generated, sent to medical aids, and reconciled when payment comes back. Reports for supervisors, medical aids, and regulatory bodies.
Lets Talk Psych needed a system that could handle all of this — a proper tool their clinicians and admin staff could use throughout the day. We built them a full practice management system with a Laravel API backend and a Flutter desktop application that runs natively on their workstations.
The backend is a pure API — no web pages, no server-rendered HTML. Just a clean REST API with 275+ endpoints that the Flutter desktop app talks to. Every action a clinician takes — booking an appointment, adding a diagnosis, generating an invoice — is an API call to the Laravel backend.
We chose Flutter for the desktop app because it compiles to native code on Windows, macOS, and Linux from a single codebase. One team, one codebase, every platform. The app follows a clean architectural pattern, keeping the UI layer separate from the business logic and making everything testable.
Authentication is handled by OAuth 2.0. When a clinician logs in, they get a bearer token that's stored locally and sent with every request. Secure, stateless, and standard.
A patient file in the system isn't just a name and phone number. It's a full clinical record — ICD-10 diagnoses, consultation history, clinical notes, treatment reports, file reviews, referral sources, correspondence with medical aids, and status tracking. Everything a clinician or supervisor needs to understand a patient's journey, in one place.
Files can have multiple clients attached — think family therapy where one file covers several family members, but one person is the main member for billing. The system handles that with a pivot table that tracks who's the main member and who's a dependant.
The full ICD-10 diagnostic code library is built into the system. Clinicians select diagnosis codes during consultations, and those codes flow directly into invoices and medical aid claims. No separate lookup, no manual entry.
Progress notes, assessment reports, treatment summaries — all attached to the patient file with tracking for who wrote them and when. Reports have their own workflow: drafted, reviewed, finalised, sent.
Supervisors can request file reviews for clinicians they oversee. The system tracks which reviews were requested, which are done, and which are outstanding — essential for clinical governance and training.
Letters to medical aids, referral letters, report requests — every piece of correspondence is logged against the file with status tracking. Outstanding correspondence shows up in reports so nothing falls through the cracks.
Every file tracks who referred the patient — doctors, schools, other therapists, self-referral. This feeds into reports that show which referral sources drive the most business. Data-driven practice growth.
Patient files move through statuses — active, under review, discharged. Each status change is recorded with a timestamp and the user who made the change. Full history, always traceable.
Billing in healthcare is complex. A clinician sees a patient, records the consultation with a tariff code and ICD diagnosis, and the system needs to turn that into an invoice — with the correct rate for that specific medical aid, any tariff modifiers applied, and the right clinician's HPCNA credentials. Then batch those invoices by medical aid, generate a CSV in the exact format the medical aid expects, submit it, and later reconcile the payment that comes back.
We built the entire pipeline. One tap to generate an invoice from a consultation. One tap to batch all outstanding medical aid invoices. One upload to process a remittance and match payments to invoices. The system does the tedious work so the practice can focus on patients.
When a clinician records a consultation, they select the tariff code and diagnosis. Hit "Create Invoice" and the system pulls in the correct tariff amount for that medical aid (with effective date handling — rates change over time), applies any modifiers, attaches the clinician's HPCNA and NAMAF practice numbers, and generates the invoice. All the fields the medical aid needs are populated automatically.
If something changes — wrong tariff, different modifier — hit "Regenerate Invoice" and it recalculates everything. Invoices track both the original and modified amounts, so there's always a paper trail.
Medical aids don't process invoices one at a time — they want batches. The system groups outstanding invoices by medical aid, generates a CSV file with all 53 required fields (patient details, diagnosis codes, tariff codes, clinician credentials, amounts), and uploads it to S3 for secure download.
Each batch gets a unique code and tracks which invoices are included. The practice admin downloads the CSV, submits it to the medical aid, and the system knows exactly which invoices are pending payment. No spreadsheets, no manual tracking.
When the medical aid pays, they send a remittance file — a CSV showing which claims they paid and how much. The problem? Every medical aid uses a slightly different format. Our RemittanceSettlementService handles flexible field mapping, so it can parse remittances from any medical aid without custom code for each one.
The system matches payments to invoices, shows the original amount vs. what was settled vs. what's still outstanding, and lets the admin review everything before confirming. If an invoice was partially paid, the remaining balance is tracked. If a payment can't be matched automatically, the admin can assign it manually. It's the part of practice management that everyone hates — and we made it painless.
Booking an appointment isn't just "pick a time slot." The system knows each clinician's working hours, their scheduled breaks, their leave days, and public holidays. When you're booking, the API calculates non-working hours for that clinician so the app only shows available slots. No double-bookings, no "sorry I'm actually on leave that day."
Bookings support recurring appointments — weekly therapy sessions with a frequency and end date. They track status through the full lifecycle: pending, confirmed, done, no-show, cancelled, rescheduled. And every status change is audited, so if there's ever a dispute about a cancelled session, there's a complete trail of who changed what and when.
Multiple clinicians, each with their own schedules, working hours, break times, and leave. The system handles supervisor/supervisee relationships, professional credentials (HPCNA, NAMAF numbers), and per-clinician reporting.
When all clinicians are booked, prospective patients go on the waiting list with their preferred clinician, medical aid details, and target appointment date. When a slot opens up, the practice knows exactly who to call first.
When a patient doesn't show up, the booking is marked accordingly. Reports show no-show rates per clinician and rescheduled-without-show patterns — data that helps the practice understand and reduce missed appointments.
A practice management system is only as good as the insights it provides. We built 40+ specialised reports across financial, clinical, administrative, and correspondence categories. Every report supports date range filtering, clinician filtering, and medical aid filtering — because the answer to "how are we doing?" always depends on the context.
And because this is healthcare, every single change is audited. Who modified a patient file, when, and what they changed. It's not just good practice — it's required for regulatory compliance. The audit system tracks creates, updates, deletes, and restores across all critical models, with the user, IP address, and URL captured for every action.
Every choice serves the goal: a reliable, secure system that a psychology practice can depend on daily. No trendy-but-fragile tools — just proven technology that works.
The API backbone. The ORM makes the complex relationships between patients, files, consultations, invoices, and medical aids manageable. The queue system handles batch processing. Authentication is built in. It's not just a framework — it's the entire backend ecosystem.
One codebase, native apps on Windows, macOS, and Linux. Flutter compiles to native code, so the desktop app feels fast and responsive — not like a web app in a wrapper. Clean architecture keeps the UI and business logic separated.
Token-based authentication for the desktop app. Bearer tokens are stateless, secure, and work perfectly for a decoupled architecture. The clinician logs in once, the token is stored locally, and every API call is authenticated without re-entering credentials.
Medical aid batch CSVs, clinical documents, and exports are stored securely in the cloud. Time-limited secure links ensure that files can only be downloaded by authorised users. No files stored on the application server.
Healthcare demands accountability. Every create, update, delete, and restore across all critical models is logged with the user, timestamp, IP address, and the exact fields that changed. Essential for regulatory compliance and dispute resolution.
Reports need to be exportable. CSV and spreadsheet exports for financial reports, client lists, and medical aid data — formatted and ready for accountants, supervisors, or medical aid submissions.
We build systems that handle the complexity so you can focus on what matters. Whether it's healthcare, finance, or operations — if it's complex, we're interested.