VolunteerProduction2024-present

Zosimades Nursing Home of Ioannina: Healthcare Ops Stack

Volunteer Lead Developer & Maintainer

Three systems that took the Zosimades Nursing Home of Ioannina off paper: clinical operations, inventory management, and a handheld scanner for shift inventory counts. Built as volunteer work, in production daily.

Results

systems in daily use at the home
3
areas of the clinical platform, from admission to discharge
14
ICD-10 codes, 10,259 of them with Greek descriptions
27,015
staff roles in the new release, ready to install
13
Zosimades Nursing Home of Ioannina: Healthcare Ops Stack

Stack

  • Bun + Elysia
  • Hono
  • PostgreSQL 18
  • TypeORM + Drizzle
  • MinIO
  • React 19 + TanStack
  • Better Auth
  • Expo React Native
  • Docker + Coolify

The home

The Zosimades Nursing Home of Ioannina looked after its residents on paper: files in cabinets, medication schedules in notebooks, a store room counted by eye. I was asked to move the institution onto a computer without changing the way staff work through a shift. I built three systems that run there every day now, and I keep maintaining them.

The home runs the June 2026 release today. The new release is ready to install and brings the biggest changes: new medication administration, the staff roles of a care home, and a new deploy process. The upgrade was rehearsed first on a copy of the home’s data. Below I say what runs today and what comes with the new release.

The screenshots of the clinical platform come from a local install of the new release, with invented residents and staff. No name or detail on these screens belongs to a real person.

A shift starts on one screen

The platform's dashboard: a list of what needs attention (a pending admission, staff documents and medicines that are expiring), today's doses each with an administer button, the shift and the on-duty pharmacy
In the new release: what needs attention today, today's doses and the shift, on one screen

Today the dashboard shows bed occupancy, admission applications on hold, the day’s shift and the activity of the last 48 hours. In the new release it puts first what should not wait: admission applications on hold, staff documents that have expired or are about to, medicines in stock that are about to expire. Below them are today’s doses, each with its own administer button, the shift supervisors and the pharmacy on duty for the home.

A resident’s record, with safety always on top

Today each resident’s record has eleven tabs. In the new release it is organised in seven groups, from the overview and clinical notes to contacts and administration. No question needs a search through three cabinets any more.

Above all of them sits a safety strip: allergies, resuscitation wishes, risks, diet and isolation. Whichever group a nurse opens, the strip is the first thing on the screen.

A resident's record at Clinical, Safety: a strip with allergies, a DNR flag, risks and diet, and cards for critical information, allergies, risk flags and falls
In the new release: the safety strip sits above every part of the record
The same record's overview on a tablet: the safety strip, today's doses with one held, and the latest notes from the shift, the doctor and the family
On a tablet, in the new release: today's doses and the latest notes, in the nurse's hand
How it works
  • Backend: Bun and Elysia in strict TypeScript, over one shared data source: 14 domain modules today and 21 in the new release (residents, admission, medical record, medication, pharmacy, staff, billing, discharge, complaints, visitors, emergencies, data access requests, data retention and more).
  • Data: PostgreSQL 18 with TypeORM, Redis 7 for cache, and file storage in MinIO through its S3 API. The new release brings 88 migrations instead of 9, about 160 entities instead of 66, and Silo in place of MinIO.
  • Access: Better Auth, role checks on the API routes and mandatory TOTP for administrators, doctors and nurses. The new release has 13 roles, TOTP for the head nurse and the auditor too, and a permission matrix for 858 API routes that a test checks on every change.
  • Integrity: every uploaded file keeps a SHA-256 checksum, so tampering can be detected.
  • Frontend: React 19 with TanStack Router and Query, with Greek as the main language and full English: 10 areas in the menu and 51 screens today, 12 and 93 in the new release.

Every dose, once, with a time and a name

The medication administration screen: today's counters, the completed 07:00 and 08:00 rounds, and the 14:00 round open with the resident's allergy and risks beside the dose
In the new release: administration rounds by the hour, with allergies beside every dose

Medication administration is the biggest change in the new release. There it is organised in rounds, by hour and by resident. Beside each dose sit the resident’s allergies, risks and diet, and each dose is recorded once, with a time and the person who gave it. Anything not given, whether refused, held or missed, goes to a list the doctor follows up.

A monthly administration record for September: five medicines by hour and day, with the nurse's initials in every cell and marks for a refusal and a hold
In the new release: who gave every dose, all month, with a PDF export
How it works
  • Doses: created automatically from the doctor’s orders, for today and tomorrow.
  • Deadlines: a pending dose turns overdue after 30 minutes and closes as missed after 2 hours.
  • Double check: high-alert and controlled medicines ask for a second checker or a written reason.
  • Follow-up: every refusal, hold or missed dose lands on the doctor’s list, and the monthly record keeps the initials of whoever gave each dose.

Diagnoses and pharmacy, in Greek

Doctors code diagnoses by searching in Greek. «Άνοια» (dementia) in chapter V returns vascular dementias, dementia in Alzheimer’s disease and the remaining categories, each with its code.

The catalogue holds 27,015 ICD-10 codes, 10,259 of them with Greek descriptions, and 686 ICPC-2 codes. The search tolerates spelling slips and works on Greek or English text.

An ICD-10 search for «άνοια» (dementia) in chapter V: a list of codes with Greek descriptions, chapter and block
Coding diagnoses with Greek search terms

Orders to the pharmacies the home works with move from draft through submitted, confirmed and shipped to delivered. In the new release, the next step is a button on every row.

In the new release, deliveries are received with their lot numbers and expiry dates, with a witness for controlled drugs, so stock knows from the start what expires and when.

Orders to the pharmacies: six orders at different stages, from draft to delivered, with a button for the next step
In the new release: every order with its next step

Care plans that do not slip

The list of active care plans sorted by next review, with one overdue at the top
Whatever is overdue comes first

Every care plan has a next review date, and the list is sorted by it: anything overdue comes first. In the new release, risk reassessments (Braden, MMSE, Barthel) and staff documents that are about to expire work the same way.

How it works
  • Automation: scheduled jobs from 10 job modules today, among them the audit-log integrity check and the backups. The new release has 41 jobs from 25 job modules, including the three shift hand-over briefings at 06:45, 14:45 and 22:45.
  • Reminders: care plan reviews and residents’ expiring documents reach staff as notifications, instead of waiting for someone to remember them. The new release adds reassessments and staff documents.

The store room knows what it has and when it expires

Consumables and medicines now have a quantity, a location and an expiry date. The system shows what is running out and what is going out of date before it becomes a problem, rather than someone finding out at the moment they need it.

Inventory is a separate system from the clinical platform, because different staff open it and it changes at a different pace.

Pixel-art design mockup for inventory management: a list of items with quantities, bars and expiry dates, with an attachments preview alongside
A design mockup of the stock screen, not a screenshot of the running system
How it works
  • Backend: Hono with Drizzle ORM and Better Auth over PostgreSQL 18, inside a Turborepo workspace.
  • API contract: a shared package of Zod schemas between backend and frontend, giving type-safe calls without code generation.
  • Frontend: Vite, React, TanStack Router and Query, Tailwind.
  • Checks: 208 automated tests across 33 backend files, with Vitest and ESLint in CI and container images on every push.

Counting on a phone, even with no network

Pixel-art illustration of the scanning app: a phone reading a QR code, a card with the item and its quantity, and an OFFLINE indicator in the corner
Scanning keeps working when the store room's Wi-Fi drops

Stocktaking happens on an Android phone inside the store room: scan, quantity, next item. The Wi-Fi there is weak, so the app does not wait for the network. It writes locally and submits in batches once the connection returns, so a whole shift is not lost because the line went down.

How it works
  • Platform: Expo and React Native, with an internal Android build through EAS.
  • Workflows: item lookup, expiry, counts, receiving, fast receiving, picklists, environmental readings and a submission queue.
  • Offline: every request is cut off at 3 seconds and falls back to a local SQLite database, and scans leave the queue in batches.
  • Auth: a bearer token held in the device’s secure store.

Two systems, one computer on site

The nursing home has no IT department. Both systems run on the same computer inside the building, behind one shared proxy that tells apart which of them a person is opening, with certificates the home’s browsers accept without warnings.

How it works
  • Networking: each stack in Docker containers, with only the proxy open to the host, so the backends are never exposed.
  • Proxy: a single nginx in front of both frontends, with mkcert certificates for internal HTTPS.
  • Database upgrade: a move from PostgreSQL 16 to 18 in May 2026, rehearsed end to end on a test machine first, with row counts compared before and after. Migrations run under an advisory lock against concurrent runs, with checksum verification and a database snapshot before every deploy.
  • Safety catch: the new deploy process, first used for the new release, puts the previous version back on its own when a health check fails after a deploy.
  • Checks: 342 test files in the new release of the clinical platform, against 125 in the one running today: unit tests, integration tests against a real PostgreSQL, migration tests and end-to-end Playwright scenarios.
  • Internal-only deployment (at the nursing home). No public URL.
  • Repos: jimrarras/healthcare (monorepo), jimrarras/ims (monorepo)

NEXT STEP

Want something like this for your business?

Send me a couple of lines about your project, or give me a call. You will hear back from me, not from a subcontractor.

Display preferences

Text

Text size
Line spacing
Letter spacing

Color

Contrast

Motion and images

Reading

Reading aid
No changes