Full-stack work on a digital art-therapy platform — a real-time collaborative canvas, scheduling, auth, and the infrastructure under it.
ArtAICare is a digital art-therapy platform where patients and therapists meet in live sessions. It needed a lot built on top of that core idea: a canvas the two of them could draw on at the same time, scheduling that booked real clinicians without clashing, account security fit for health data, and the day-to-day tooling to keep it all running.
The platform was already in use with real sessions, so nothing could break while I worked on it. A clinical product also raises the bar — patient artwork and records can only be seen by the people meant to see them, and you can't lose a session's work.
I worked across the stack: Node and Express with TypeScript on the back end, React on the front, MongoDB and Redis underneath, and Python services for the AI parts. The piece I spent the most time on was the real-time canvas — getting two people's drawing, video, and audio onto one screen without lag or conflicts. Around it I rebuilt scheduling, added two-factor auth, translated the whole app, and set up the deploy pipeline and admin tooling so the rest could move faster.
The canvas now carries live two-person sessions with recording, replay, and version history; booking runs on a two-click, timezone-aware flow with automated reminders; and deploys are automated with rollback on failure. It's in production at therapy.artaicare.com.
The core of the product — a drawing surface a patient and therapist share during a live session, kept in sync over WebSockets alongside the session's video and audio. On top of it I built a few therapy modes (image and collage work, photo editing with a before/after compare, and a storytelling mode with chapters and scenes), recording and replay so the therapist can look back over a session, and a way to fork a drawing and reopen an earlier version partway through.
A multiplayer version of the canvas for therapist-led webinars: a lobby and host controls, breakout rooms, chat and reactions, and saving the finished piece together with its audio.
A 3D space where patients show the work they made in therapy, in place of the old flat gallery. Since that work is also a clinical record, the therapist controls what stays visible and what gets shared back.
I redid booking from the ground up. Therapists paint their weekly availability, patients book in two clicks across time zones, and two requests for the same slot are settled atomically so it can't go twice. Reschedules, cancellations, no-shows, and 24-hour and 1-hour email reminders sit on top, and a confirmed booking opens straight into its session room.
TOTP two-factor — optional for patients, required for admins — with admin-assisted reset and an email recovery path. I also closed a couple of gaps: patient records are readable only by the assigned therapist, and the canvas checks you belong to a room before it lets you onto its data channel.
Took the whole interface through a translation pass — auth, canvas, scheduling, community, chatbot, and the tutorials — so the app works in more than one language end to end.
Liora, an in-app help assistant that answers from the product's own documentation through a retrieval pipeline, with prompts that adjust to the user's role and a kill switch for admins. The Python side runs the image and recommendation models and a music generator, watched by a small process that restarts anything that crashes.
An admin panel for the team running the service: role-based permissions with an audit trail, feature flags, settings, metrics, moderation, a file browser, and logs. The community side too — posts and comments with search and saved items, direct messaging, and a support-ticket queue wired into email.
CI/CD with separate dev and production deploys that roll back when a release fails, PM2 keeping the processes up, and an email outbox with a retry worker. On security: the backend sits behind Nginx, Redis got a password and the host a firewall, requests are rate-limited, leaked secrets were rotated out of the setup docs, and unfilled template variables can no longer slip into outgoing mail.