---
title: Heartbeat Pharmacy Platform
description: >-
  A full e-commerce platform for a Greek pharmacy, owned outright (no per-transaction SaaS bill), with AI shrinking SKU
  enrichment from days to hours.
lang: en
source: https://jimrarras.com/en/projects/heartbeat-pharmacy/
fetched: '2026-09-19T06:40:32.175Z'
---

Lead Developer

A full e-commerce platform for a Greek pharmacy, owned outright (no per-transaction SaaS bill), with AI shrinking SKU enrichment from days to hours.

- **10,417** products in the first full sync

- **1 min** between stock updates

- **69** catalogue tools an AI assistant can call directly

## Stack
## The situation

Heartbeat is a Greek pharmacy with a physical shop, where stock already lived in the till system. They wanted their own online store, with no per-order commission going to somebody else’s platform, and without hiring a second person just to type product descriptions. They brought me on as the only developer on the project. Instead of one large program I delivered separate systems that work together, so any one of them can stop or be updated without taking the rest down.

## A store they own

The code, the database and the server belong to the pharmacy. No platform takes a cut of each order, and no third party’s pricing change can raise the cost of running the shop overnight.

![The Heartbeat Pharmacy homepage: a top bar with the pharmacy phone number and free-shipping terms, a wide search field, a row of category links, and a seasonal banner reading Ενέργεια για κάθε μέρα](https://jimrarras.com/images/projects/heartbeat-pharmacy/storefront.webp)

The storefront: search, categories and the delivery terms all above the fold

A product page has to answer the questions a pharmacist gets asked at the counter. Price with VAT shown plainly, whether it is in stock today, how soon it arrives, what the shipping will cost to your address.

![A product page for Lamberts Natural Pea Protein: gallery thumbnails on the left, the large product image in the middle, and on the right the price of 33,87 euro with VAT noted, a buy button, the stock line and a shipping calculator](https://jimrarras.com/images/projects/heartbeat-pharmacy/product.webp)

How it works

- **Store:** a Next.js 16 storefront on a Medusa 2 backend, with PostgreSQL, Redis and Meilisearch.
- **Search:** Meilisearch through InstantSearch, results arriving as the customer types.
- **Checkout and mail:** a bank gateway integration, Turnstile on the forms, and order email through Resend with React Email templates.
- **Monitoring:** PostHog for usage and Sentry for errors only, with personal data scrubbed before any report leaves the server.

## One person, thousands of product codes

Nineteen top-level categories, each with its own subcategories, is a lot of shelf to keep tidy for a pharmacy that also has a counter to run.

![The categories page: cards for Makeup, Perfumes, Mother and Baby, Vitamins and Supplements, Slimming and Sport, and Pharmacy, each listing its subcategories as pills with a plus-ten-more link](https://jimrarras.com/images/projects/heartbeat-pharmacy/catalogue.webp)

The catalogue has its own system, separate from the store. One person picks products, asks for a draft description, checks the text and the images, and only then does the product reach the storefront.

The point was never to have the machine write instead of a person, but to stop the person starting from a blank page on every single code.

![Pixel art illustration of a product management screen: filters on the left, a product list with tick boxes in the middle and an edit form on the right](https://jimrarras.com/images/projects/heartbeat-pharmacy/pim-admin.webp)

The catalogue: filters, bulk selection and editing on one screen

How it works

- **Catalogue backend:** Express 5 with TypeORM over two separate PostgreSQL databases, one for data and one for logs only, so audit-record noise never weighs on the catalogue.
- **Enrichment:** the Anthropic SDK and Google GenAI for drafts, Puppeteer 25 with in-house evasions for catalogues that expose no API, BullMQ queues on Redis for bulk jobs, and S3 for images.
- **Admin:** React 19 with Vite and TanStack Router, Query and Table, a Tiptap text editor and Recharts dashboards.
- **Checks:** the integration tests bring up a real PostgreSQL in Docker with Testcontainers on every run, no mocks.

## The shelf and the screen agree

Stock lives in the pharmacy’s own system, not on the site. A service reads it and sends it to the store every minute, so nothing gets sold that is not on the shelf.

![Pixel art illustration of the data flow: shelves of records on the left, a server with a Medusa head in the middle and a shop window on the right, with arrows pointing rightwards](https://jimrarras.com/images/projects/heartbeat-pharmacy/data-flow.webp)

From the pharmacy's own database to the server, and from there to the storefront

How it works

- **First sync:** a full one, all 10,417 products; after that only what changed since last time travels.
- **Resilience:** retries with growing backoff, a lock so two syncs never run at once, a circuit breaker, a DRY\_RUN mode for testing without writes, and logs that rotate daily.
- **Packing:** a separate service asks every 30 seconds for new courier vouchers and prints them on the packing bench’s thermal printer; the picking list carries the customer’s name only, never the address.
- **Prices:** all price arithmetic lives in one dependency-free package pinned to a version and shared by the backend and the admin, so there are never two versions of the same calculation.

## Links

The catalogue does not only have a screen for people: it exposes 69 tools to an AI assistant, which works on the same data locally, with nothing opened to the internet.

## Related work

- Live: [theheartbeat.gr](https://theheartbeat.gr/) (pre-launch)

- Kleidarakos B2B & Papanikolaou Doors: another large commerce build, but B2B instead of B2C
- pooq.gr: WooCommerce commerce engineering, extending a store instead of replacing it
