CH
A list of emergency vet locations and their contact, address, and feline blood availability at a glance.

Personal · 2026 — Ongoing

View live

Poe's Promise

ReactTypeScriptViteNode.jsExpressPostgreSQLPrismaTanstack QueryWouter

Poe's Promise is a fullstack web application I built, from the initial idea to a live production deployment, conceived during one of the worst nights of my life and finished in the months after losing the cat it was named for.

The frontend is React 19 and TypeScript, bundled with Vite and styled entirely with Styled Components. I reached for TanStack Query for server state management and Wouter for routing. I chose Wouter specifically because it is a fraction of the size of React Router and more than capable of handling what the platform needs. The built frontend gets served as static files through an Nginx container, with a custom config to make sure client-side routing does not break on direct navigation or a page refresh.

The backend is Node.js and Express 5, also in TypeScript, with Prisma 7 sitting in front of a PostgreSQL 17 database hosted on Neon's serverless platform. I chose Neon specifically because the free tier is genuinely usable for a non-commercial project and the branching feature keeps development and production cleanly separated. The platform supports three distinct user types with appropriately scoped access: public visitors, partner location staff, and myself as the administrator, each restricted to exactly what they need to do and nothing more.

Everything is deployed on a Hostinger VPS through Coolify, which I set up partly because I wanted the deployment experience of something like Render without the per-service pricing that would have made running both a frontend and backend cost-prohibitive for a free community project. Coolify manages Traefik internally which handles routing and automatic SSL for both the main domain and the API subdomain. Pushes to a protected production branch on GitHub trigger automatic redeployments through a webhook so I am not manually pulling code onto the server every time I ship something.

The data model is built around the core problem of tracking feline blood availability by type across multiple locations belonging to multiple organizations. Inventory submissions are append-only, meaning every daily count is stored as a new record rather than overwriting the previous one. That gives me a full history for every location and lets me always surface the most recent count per blood type without losing any data. Every mutation goes through an audit log as well, which felt important given that people might actually be making medical decisions based on what this platform shows them.

Partners interact with the platform through a dedicated portal that walks new locations through a step by step onboarding flow covering organization setup, location details, and account configuration before they ever see the main dashboard. Once onboarded, the daily workflow is straightforward: staff log in, submit current unit counts for each feline blood type, and log out. The submission form is intentionally minimal because the goal was to make it something a vet tech could realistically complete between patients without it feeling like a burden. Partners can also post location notes for things like parking changes or temporary closures, and those notes surface directly in the public facing location details modal so users see them before they call or travel.

On the admin side I have full visibility across every organization, location, and partner account on the platform. I can manage partner onboarding, edit location details, review submission history, and monitor inventory trends across all locations from a single dashboard. The platform also includes a flagging system that allows partners to flag concerns or issues at their location which routes directly to me as the administrator to review and follow up on. It gives partners a channel to communicate something that does not fit neatly into an inventory update or a location note, and it gives me a way to stay on top of anything that needs attention without waiting for an email. When a flag is submitted the platform sends an immediate email notification through Resend so I am alerted in real time regardless of whether I happen to have the admin dashboard open. The same notification system handles partner onboarding emails and any other transactional communication the platform needs to send, keeping all outbound email flowing through a single reliable pipeline rather than scattered across different services.

One thing I had not anticipated when I started reaching out to potential partners is that not every organization can fit into a daily manual reporting model. Some larger networks manage blood availability through their own internal systems at a level a community platform like mine genuinely cannot match. Rather than treating that as a hard no, I built a second partner type into the platform. Organizations that opt out of reporting get a custom informational message displayed in place of inventory pills, with their contact information still visible so users know to call them directly. That came directly out of a real conversation during outreach, not something I planned for upfront, and I think it made the platform more honest and more useful as a result.

Users can enter their address or zip code to find the closest matching clinic near them, filter by blood type and only show open clinics.
When clicking on a location, this modal opens and gives more details that the exterior card doesn't have, more contact information, website details, a map, hours, and public facing notes if any are available from the location.
This is the location and inventory management section veterinary staff see when viewing their partner dashboard, specifically the home tab.

Next project

PGA Perfect 30