Skip to content

INDUSTRY

Software for clinics, therapists and care teams

A clinic management system, a psychologist workspace, an operating-room app and nutrition tracking: how we separate health data, and what we do not claim.

SHORT ANSWER

In healthcare we have built ClinicPulse, a multi-tenant clinic management system; PsiLog for psychologists; ProcedureLogic for spine surgery teams; and FitZen for nutrition tracking. In ClinicPulse tenant isolation sits in the database as 34 row-level-security policies across ten tables, and sensitive fields are encrypted with AES-256-GCM. We make no HIPAA or medical-device certification claim; we show which protections we built and how.

Why should tenant isolation for clinic data live in the database?

In multi-tenant clinic software, leaving isolation to the application layer is risky: one missing where clinic_id = … filter exposes another clinic’s patient record. So ClinicPulse does not rely on application code behaving. The first migration creates ten tables and row-level security together, admin policies come in a separate migration, and there are 34 policies in total.

Profiles, clinics, staff, subscriptions, patients, appointments, treatments, documents and WhatsApp logs share one schema. Adding a clinic is one row; no clinic needs its own deployment or its own database.

Row-level security protects rows, not what is inside a field. Sensitive fields are therefore encrypted as well: lib/encryption.ts uses AES-256-GCM with a 12-byte IV and an enc: prefix. The key is a 64-character hex string, and without it the app refuses to start, so an environment that forgot the key cannot quietly write plain text.

Staff join through invite links, and a platform admin manages clinics and subscriptions from a separate panel. Which fields to encrypt is decided with you during discovery, based on your data model.

How are appointment reminders sent over WhatsApp?

ClinicPulse’s reminders had to go over WhatsApp. That comes with a technical constraint: Meta’s message templates are per-language and must be approved. lib/whatsapp.ts talks to the Meta Graph API and picks the template by the clinic’s language; nothing is sent unless the clinic carries an approved template for its own language.

Reminders 24 hours before an appointment are triggered from the api/cron/reminders route. The send endpoint is capped at ten requests a minute, so uncontrolled sending cannot go past that limit. WhatsApp logs are kept in the same schema as patients and appointments. Which channel a reminder uses, how many hours ahead it goes and in which language are product rules, and we write them with you during discovery to match how your clinic works.

The interface is in Turkish and English and PDF templates are built in. The Vitest suite has eight files covering admin, API, constants, environment variables, i18n, subscriptions, utilities and validations. ClinicPulse is live as an installable PWA; because it is our own product, we can walk through its decisions and code in detail.

How do a therapist and a client look at the same data and see different things?

PsiLog is client, session and therapy-plan management for psychologists. Two sides look at the same record but must not see the same thing: the psychologist sees session notes and risk assessments, the client sees their own plan, homework and mood log.

Both surfaces live in one Next.js app, in separate route groups. Under (dashboard) are the psychologist’s clients, calendar, session notes, billing and settings; under (portal)/portal are the client’s assessments, plan, sessions, homework, documents and mood log. Who sees what is defined in row-level-security policies, not in the interface.

The domain was built step by step in eleven migrations: the initial schema, therapy plans, session notes, assessments, mood entries, homework, risk assessments, consent forms, admin, subscription expiry and storage. Each step arrives with its own RLS policies; no table is added without them.

Clients join by invitation, with consent forms as part of the flow. Reminder and invite emails go through API routes, and expired subscriptions are closed on the database side by a cron job. PsiLog is in development, in Turkish and English, with unit tests on Vitest.

Who manages the content of an app used in the operating room?

ProcedureLogic is a mobile workspace that brings orthopedic procedures, scheduling and team coordination together. A spine procedure is dozens of steps, checklists and confirmations, and every surgeon’s preferences deviate a little from the standard flow. The team needs the right step and the right surgeon preference in front of them in the operating room.

Procedures such as ACDF, PCF and TLIF are modelled as ordered cards. Each card has checklist and confirmation items, and progress is tracked by card index and completion statistics. Surgeon preferences use a delta system: the standard card stays fixed and the surgeon-specific difference is layered on top, so updating a standard procedure does not mean fixing a separate copy for every surgeon.

Scheduled cases are listed with date, time, hospital and operating room. The app reads from Firebase; content is entered only through the Next.js admin panel and no procedure is embedded in the mobile bundle, so changing a step does not wait for a store update.

The mobile app and panel were delivered to the client, with user management, an analytics dashboard and an EAS / Vercel deployment guide as part of the handover. It is an archive project.

How do you show an AI result without turning it into a health claim?

FitZen is a nutrition tracking app that analyses meals from a photo. There are two traps: presenting model output as definitive health information, and depending on the model itself.

For the first, foods, portions and nutrients are shown as estimates, and the user reviews the result before saving it to the diary. An analysis attempt and a saved entry are not the same thing. No food detected and a service that cannot respond are separate states, and permission denial or a cancelled selection is never confused with an analysis failure.

For the second, model calls go through a proxy on a Cloudflare Worker. The model name is embedded in the mobile bundle, so when a provider retires a version every released build would start failing. An alias table in the proxy maps retired names to a living model; exactly that happened for gpt-5.2-chat-latest on 3 September 2026, and no store update was needed.

A dietitian portal, fasting tracking and a community are part of the same product, with dietitian session credits consumed through server functions. FitZen is live on iOS and Android in 11 languages and rated 4.4 on the App Store.

What if a service must not start without a health declaration and a signed document?

Health data does not only appear in clinics; it shows up in businesses such as exercise studios. In the app we rebuilt for PeakUp Training Studio, members, trainers and the studio owner share one Expo app, with a separate Next.js panel for the owner.

The rule was not left to code review. A package cannot be purchased without a tablet-signed contract and a PAR-Q (Physical Activity Readiness Questionnaire) on file; it is a document gate. The six-stage member analysis is a flexible template whose stages and fields are edited from the panel without code changes.

A shared package carries zod schemas and business rules (VAT, absences, package deductions), and the same rule is validated on the client and in database CHECK constraints. 36 database and RLS tests, contract checks and unit tests run under one command, and nothing deploys unless it is green. In the closing audit no finding counted as closed until a test had been written to catch it.

The app is live on iOS and Android as the 2.0.0 update to the existing store listing. The client’s 19-item request list served as the acceptance criteria.

What do we say about HIPAA, KVKK and certification?

To be clear: for none of the health projects on this site do we claim HIPAA compliance, medical-device certification or approval by an audit body. Those are not labels software earns on its own; they are assessed together with the organisation’s processes, contracts and hosting decisions.

What we can describe are the protections that live in the code:

  • Tenant isolation in the database: 34 RLS policies in ClinicPulse, and in PsiLog RLS policies arriving with every migration.
  • Field-level encryption: AES-256-GCM in ClinicPulse, and the app will not start without its key.
  • Consent: consent forms in PsiLog; in PeakUp no package opens without a signed contract and a PAR-Q.
  • Rate limits: the endpoint that messages patients is capped at ten requests a minute.

Our most detailed KVKK example is an education project: at ozelokul.com consent records point at versioned, immutable legal texts, account deletion anonymises personal fields, and the tables cleared are recorded. The same approach can be applied to health data; we recommend deciding which records to keep, and for how long, together with your legal adviser. This section is not legal advice.

Frequently asked questions

Do you build HIPAA-compliant software?

We do not claim HIPAA compliance or certification for the projects on this site. Compliance depends on the organisation’s processes, contracts and hosting decisions as well as the software. The part we build is the technical protection: tenant isolation in the database, encryption of sensitive fields, consent records and rate limits. We write down during discovery which requirements are targeted and prepare the scope and proposal accordingly.

Do you encrypt patient data?

In ClinicPulse sensitive fields are encrypted in lib/encryption.ts with AES-256-GCM, a 12-byte IV and an enc: prefix. The key is a 64-character hex string, and without it the app refuses to start, so a misconfigured environment cannot write plain text. Row-level security decides who can see which record; encryption decides whether a field is readable in a database backup.

Does every clinic need its own deployment?

Not in ClinicPulse. Adding a clinic is one row; isolation comes from 34 row-level-security policies across ten tables rather than from filters in application code. Staff join through invite links and a platform admin manages clinics and subscriptions from a separate panel. If an organisation wants a separate database or its own servers, that is an architecture option we discuss during discovery.

Should the practitioner dashboard and the client portal be separate apps?

Not necessarily. In PsiLog both live in one Next.js app in separate route groups: the psychologist dashboard holds clients, the calendar and session notes, and the client portal holds the plan, homework and mood log. Who sees what is defined in row-level-security policies, not in the interface. One app keeps maintenance lower; if a separate store app is needed, the mobile side is planned on its own.

How do you add an AI feature without it reading as medical advice?

In FitZen model output is presented as an estimate and is not saved to the diary until the user reviews it. No food detected and a service failure are separate states, so the user understands what happened. Because model calls go through a Worker proxy, the app keeps working when a provider retires a model. The wording and disclaimers on screen are written with you during the design stage.

Can we update procedure and protocol content without a developer?

Yes; ProcedureLogic was built for exactly that. Content is entered only through the Next.js admin panel and the mobile app reads from Firebase; with no procedure embedded in the bundle, changing a step needs no store update. Surgeon preferences are kept as differences layered on the standard card, so updating a standard procedure does not mean fixing every surgeon’s copy separately.

Who owns the source code and accounts?

You do. The domain, servers, database and service accounts are opened in your name. At delivery we hand over the full source code, the design files and every credential.

Do you use templates or off-the-shelf admin panels?

No. We design the user screens and the admin panel screens for your project and build them from scratch, so the panel follows your workflow.

RELATED STUDIO NOTES

If you have an idea in mind,
let’s talk.

It starts with an intro call. We define the scope and timeline together, then send you a written proposal.

hello@amgsoftwarestudio.com