EST. 2025

- Case 05 · Healthcare

AI assistant for a medical clinic.

The clinic's practice management system does not expose its database, so every visit report had to be clicked out of the program by hand. Today an automated job does it every evening after hours, and the team will soon ask about the data in plain language in a chat with an AI assistant that never sees a patient's identity. Everything runs on the clinic's own server.

Client
Medical clinic, a dozen or so staff
Industry
Healthcare
Services
AI Chatbot, Automation, Integrations
Duration
in progress
Year
2026

- Before

access to the practice system's database
none
every report clicked out of the program, day by day
by hand
the only time the program isn't under load
evening

Situation

The clinic runs on a commercial practice management system: visits, schedule, insurer settlements. The vendor gives no access to the database, and during office hours the program is too busy to take on more work.

The owner wanted two things: visit data leaving the program on its own, and staff able to ask about it in plain language, without an IT person. One boundary condition from the very first conversation: patient identities never reach any language model.

What wasn't working

The data was in the program, but the program gave it to no one beyond the screen.

  • Every report meant the same sequence: log in, visits view, date, printer, print preview, export, save file. Day after day, by hand.
  • The export is a printout turned into CSV: a facility preamble, a header wrapped across two lines, the doctor in a separate row instead of a column. It had to be cleaned before any analysis.
  • A question like "how many patients of a given insurer did we have in August" needed someone to sit down and count.

What we built

Three components, each with one job.

  • Extractor (.NET 8, UI Automation): logs into the practice system on a technical account with the front-desk role and clicks through the interface the way a person would. It doesn't touch the database, doesn't read the visit grid off the screen, and never runs during office hours. It merges the daily files into one flat table with doctor and date columns.
  • Database and chat: the files land in PostgreSQL, and the team gets channels in Rocket.Chat with a Python bot connected to the Claude API. The bot turns a question asked in Polish into a read-only query and answers in the channel.
  • Insurance reconciliation tool for the front desk: matches daily visit lists against insurer settlements. The nightly exports are its input, so it got fresh data with no extra work.

How it works day to day

In the evening a scheduled task runs the extractor for the last four days. Days that already have a file are skipped, the current day is always refreshed, so an interrupted run completes itself the next evening. Every file must contain the requested date in its content, otherwise the day is rejected: better a gap than visits under the wrong date. A failure on one day doesn't stop the rest.

A few rules that cost us the most to learn: dates in ISO format only, because 07-08-2026 means different things in Poland and in the US, and one day a model will be generating the arguments; a hard 62-day limit on the range, so a typo can't trigger hundreds of passes through a medical system's GUI; the physical printer button is never clicked.

Patient data, GDPR and costs

Before anything is sent to the model, national ID numbers (PESEL), first names, surnames, phone numbers, e-mails and addresses are replaced with tokens like OSOBA-0001. The mapping stays in a local database, separately for each chat room, and the bot puts the real values back only in the answer, on the clinic's side.

Every query goes into an audit log: who, when, what about and at what cost. The daily budget is counted in cost, not tokens, because prompt caching inflates the token counter many times over. Data access is set per department. One change along the way: the chat and database were going to run on a VPS in the EU, but the clinic's server turned out to be powerful enough, so everything runs at the client's and the data never leaves the facility.

Status and what we learned

The extractor has been running in production since September 2026 and exports a day in about 25 seconds. The first version needed 4 to 5 minutes because it searched the entire control tree, visit grid included; a shallow search that skips tables gave a tenfold speed-up. Loading into the database and the chat are under construction.

Honestly: if the vendor offered an API or a scheduled export, the extractor would be unnecessary and we would have started with the chat. UI automation is a last resort, not a first choice, and it needs watching after every program update. Here there was no other way, so we built it to prefer stopping over clicking the wrong thing.

Data flow

  1. 01Evening: the scheduler starts the extractor
  2. 02Login to the practice system on a technical account
  3. 03Daily report exported to CSV
  4. 04Merging and date check in the file
  5. 05Loading into PostgreSQL and the insurance reconciliation tool
  6. 06Question in chat, pseudonymization, AI model
  7. 07Answer in the department channel with the data restored

Project goal

export of one day from the practice system
~25 s

measured · measured on the clinic's server, September 2026

personal data sent to the model
0

scope

chat, database and bot on the clinic's server
on-prem

scope

- What's next

Next step: feeding the database from the nightly exports and the chat in production, then the 60-day forward schedule the owner asked for. Got a system that won't give up its data? A free consultation takes 30 minutes, and an audit for PLN 699 net ends with a document covering architecture, scope, risks, a fixed price and a deadline, deducted in full from the implementation price: get in touch.

- Stack

  • .NET 8
  • PYTHON
  • POSTGRESQL
  • ROCKET.CHAT
  • CLAUDE API

- Have a similar process?

Tell us what
eats your hours.

We'll get back within 4 business hours with questions, or straight away with a proposal for how to wire it up. No strings attached.

contact-form

The data controller is PRODAUT Sp. z o.o. We use your data to reply to your enquiry. If you consent to advertising cookies, a hash of your e-mail is sent to Google Ads for conversion measurement. Privacy policy.

Prefer a call? Pick a slot for a 30-minute consultation →

- See also

- Let's start

Want the same result
in your company?

A 30-minute call, zero cost. Tell us where you lose hours and we'll come back with an estimate of how many you can get back.

PRODAUT Sp. z o.o. · Sułków 36, 48-120 Baborów · District Court in Opole, 8th Commercial Division of the National Court Register · KRS 0001242863 · NIP 7481597304 · REGON 544821885 · Share capital PLN 5,000

© 2026 PRODAUT · All rights reserved
Privacy policy·Cookies·GDPR
Made with in Katowice