All articles
21 · Product & analysis · 2026.01 · 5 min

The process behind the form in a clinic application system

In the system I am building for Kadir Yücebaş, the application form is only the visible part of the work. In this note I explain how I think about applications reaching the clinic team, how their status is followed, and how bilingual interfaces share one data model.

01The work that starts where the form ends

When designing an application form, the first thing that comes to mind is the fields: what information to ask for, which fields are required, how to order them. On the independent project I am building for Kadir Yücebaş it was tempting to start there too. But the real need of the project was somewhere else. Receiving an application, delivering it to the clinic team and following its progress are connected tasks. However well the form is designed, if it is unclear what happens after submission, both the applicant and the clinic team are left in a gap.

So I tried to think of the system as a flow from the very beginning. Clinic applications and preliminary assessment are handled within one structure. Turkish and English application interfaces, a clinic administration panel and notification services work together as different faces of the same system. What matters to me is that each of these faces makes sense to its own user while sharing the same reality underneath.

02Two languages, one data model

When building a bilingual application interface, the easiest path can look like writing a separate form for each language. It is fast in the short term, but in the long term it produces two separate realities. When a field is added or a validation rule changes, two places need updating, and at some point the two quietly drift apart.

On this project I chose to connect the Turkish and English forms to the same data model through shared schemas. The language changes the text the user sees, not the structure of the application. So when an application is opened in the administration panel, it reads the same way regardless of which language it came from. Shared schemas have another benefit: the checks the interface performs and the data the server accepts are fed by the same definition. That reduces mismatches that otherwise build up unnoticed between the two layers.

layers
Turkish application interface ──┐
English application interface ──┼──> shared schemas ──> service layer ──> Drizzle + PostgreSQL
Clinic administration panel   ──┘                            │
                                                             └──> email notification and document generation

03The admin side is a user interface too

In projects like this, the administration panel often ends up as an afterthought. The screens the applicant sees are prepared with care, while the screens the team uses every day get rushed because they count as internal tools. I think the opposite: the person running the process is the person using the administration panel. How they see an application, how quickly they reach the information they need and how they move to the next step directly shape the quality of the process.

In the clinic administration panel, reviewing applications and following their status are parts of the same flow. My aim there is a structure that does not create extra work for the team but always makes visible where the process stands. Working in a health-related context, I also deliberately keep one boundary: the system does not make assessments, the clinic team does. The software's job is to deliver information to the right person in an orderly and complete way.

The form is where the process begins; the real work starts after submission.

04Status tracking and notifications

From the applicant's point of view, the most uncomfortable thing is uncertainty. Submitting a form and hearing nothing back makes you wonder whether anything is happening at all. That is why I placed status tracking close to the center of the system. An application has a status, and that status carries meaning both on the administration side and in how the applicant follows the process.

Notification and email flows come in here. The email side, which runs on Nodemailer, carries information to the relevant parties at certain points in the process. The document generation component turns the information in an application into an orderly output. In flows like this, the approach I prefer is to think of notifications as tied to the status of the application. When sending an email is a rule that has to be remembered separately somewhere, it becomes easy to forget. When it is handled together with the status, consistency improves, and when the flow changes later it is clear where to make the change.

05The data layer and the runtime environment

The Next.js applications share the same data layer through Drizzle and PostgreSQL. What I like about Drizzle is that the schema definition reads clearly on the TypeScript side and queries can be written together with their types. In a structure where fields like those of an application may change over time, seeing the database schema in the same place as the code makes changes safer. Docker helps keep the development and runtime environments close to each other.

On this project I work across the web, service and data layers. The advantage is being able to follow, in one mind, how a change spreads from the form to the database, then to the administration panel and the notifications. The downside is that keeping this integrity requires discipline. Shared schemas and a single data model are the most concrete tools of that discipline.

Related articles
  1. 22From software to hardware: a building-washing drone and Raspberry Pi displaysR&D and hardware2025.125 min
  2. 23A telemetry interface on Raspberry Pi: staying smooth while data flowsR&D and hardware2025.115 min