Back to index
02Work

Painel de Chamadas

Real-time patient calling

My role
Full stack developer — extension, WebSocket server and panel
Client
Wi Consultoria
Sector
Health unit waiting room
Period
2024 — present
Status
In production
View live(opens in a new tab)

Proprietary code. Private client system — the repository isn’t public.

Numbers

4

pieces in the ecosystem

Extension, call server, TV panel and API.

0

lines changed in PEC

Integration is by DOM injection — the health record stays untouched.

WS

real-time delivery

WebSocket pub/sub, no polling on the TV.

A

Context

PEC is federal software installed in the municipality. We can’t modify it — but the professional works inside it all day. Calling the next patient was, in practice, shouting down the corridor or a TV showing a static list nobody updated.

B

The problem

Trigger a call from a system that isn’t ours, deliver it in real time to a TV that may be in another room, and do it in a way the unit can install by itself — no technician on site, no changes to PEC and no dependency on a perfect network.

C

The approach

A browser extension injects a “call” button into PEC’s own attendance screen, reading the context already there. The click becomes a POST to a dedicated Fastify server, which publishes the call over pub/sub and pushes it by WebSocket to the panel subscribed to that room. The panel shows the name and uses the browser’s speech synthesis to say it out loud. No heavy message broker, no polling and no state that’s hard to debug.

D

Architecture

  1. 01

    Extension inside PEC

    Injects the button into the attendance list and keeps room, triage and call template locally. DOM-level integration, because PEC’s code isn’t ours to change.

    • Chrome Extension
    • React
  2. 02

    Call server

    Fastify receives the call, normalises the panel identifier and publishes it over pub/sub. A small dedicated service: if it goes down, nothing else goes with it.

    • Fastify
    • WebSocket
    • Redis
  3. 03

    TV panel

    A Next.js page subscribed to that room’s channel. It receives over WebSocket, shows the name in large type and speaks it with the browser’s speech synthesis.

    • Next.js
    • Web Speech API
  4. 04

    Alerts in the record

    The same extension also reads the citizen open on screen and fetches alerts from our API — useful information surfacing inside the workflow that already exists.

    • Express
    • REST
E

The hard parts

Integrating with no permission to modify

DOM injection into third-party software is fragile by nature: a PEC update can change the structure underneath you. The defence was keeping the contact surface minimal and explicit — read as little as possible, in one place, failing quietly instead of breaking the screen.

Addressing the right TV

One unit can have several panels; one city, many units. The panel identifier is derived and normalised identically on both ends — if the extension and the panel disagree by one character, the call goes nowhere. One normalisation rule, written once.

F

What’s mine

  • Browser extension injecting the call button and alerts into PEC
  • Fastify server with WebSocket and call pub/sub
  • The TV panel: large-type layout, queue and speech synthesis
  • Panel-identifier normalisation shared across both ends
G

Outcome

The waiting room started running itself: the professional clicks where they were already working and the patient hears their own name. It’s the module that explains itself fastest to someone who has never seen the system — and the one that best shows that good integration is the kind that doesn’t need permission to exist.

What I took from it

  1. 01A small dedicated service beats a module inside the monolith when failure has to stay contained.
  2. 02Real time over WebSocket is the easy part; addressing the right recipient is the hard part.
  3. 03The best integration is the one the user never notices is an integration.

Stack