← Projects

Petcare AssistantDemo

2026 · Solo developer

AI assistant + CRM on LINE for vet clinics, grooming and boarding shops, running as a public demo. Customers ask, book, pay a deposit and cancel in the chat; the bot answers from the shop's own data and hands over to staff when a decision should not be left to AI.

94%eval pass rate over 225 runs (hold-out 71% → 84%)
10.7 mswebhook p95 at 100 messages/s
81 → 0.17 msa query RLS kept off its index
~2,200tests on real PostgreSQL in CI
  • Next.js
  • NestJS
  • PostgreSQL + pgvector
  • Drizzle
  • Redis / BullMQ
  • OpenRouter
  • LINE Messaging API
  • LIFF
  • Docker
  • Caddy

Three things that changed how I work

What I built

  • Designed and built a multi-tenant SaaS that gives vet clinics, grooming and boarding shops an AI assistant on LINE plus the CRM behind it (Next.js, NestJS, PostgreSQL + pgvector, Drizzle, Redis/BullMQ, OpenRouter, LINE Messaging API + LIFF)
  • Enforced tenant isolation with PostgreSQL row-level security set per transaction and an RLS test for every tenant table; every service validates input, checks permissions and writes an audit record in one transaction
  • Built a guarded LLM pipeline: tool calling for prices and bookings, prices computed in code (never by the model), RAG over each shop's knowledge base, and seven output guards; emergencies hand the chat to staff and alert the team
  • Measured AI quality with an eval suite and an untouched hold-out set: 94% across 225 scored runs, hold-out raised from 71% to 84%; compared models on quality, latency and safety, running at about $1.2 per 1,000 bot turns
  • Prevented double bookings with a PostgreSQL exclusion constraint, tested by racing real transactions; a BullMQ worker runs debounced bot turns, background memory extraction, reminders, follow-ups and per-contact AI spend caps
  • Load-tested the webhook at 100 msg/s (p95 10.7 ms, 0 errors) and cut a hot query from 81 ms to 0.17 ms after finding that row-level security kept PostgreSQL from using the index
  • Shipped with CI/CD: ~2,200 tests on real PostgreSQL, Docker images to GHCR, a 32-second SSH deploy behind Caddy that backs up before migrating, and nightly backups to Cloudflare R2 under a 30-day object lock

The problem

Thai pet shops (vet clinics, grooming, boarding) answer the same questions all day on LINE: how much is a grooming for a medium-sized dog, are you open on Sunday, can I book Friday at 2pm. A wrong price costs the shop money, and a bot that guesses is worse than no bot.

What I built

A multi-tenant SaaS: an AI assistant on LINE plus the CRM behind it. Customers get answers about services, hours and promotions, always from the shop’s structured data and never from the model’s own knowledge. Booking, prices and cancelling happen on small web pages that open inside LINE (LIFF), so the bot answers questions and sends the right button instead of collecting a booking over five messages.

Staff get a dashboard with an inbox, customer and pet records (allergies and temperament warnings show on the booking cards), calendars per staff member, a drop-off board, a boarding grid and the deposit slips to confirm.

Why it is interesting

The hard parts are not “call an LLM”. They are the ones that decide whether a shop can trust it: guarding prices, preventing double booking, isolating tenants, resisting prompt injection from chat, and keeping staff in control.

Status

A public demo at petcare.rattanun.dev for a sample shop, Happy Paws, on one 2 vCPU / 4 GB server. Anyone can chat with the bot on its LINE Official Account, and the dashboard has a read-only demo login. No real shop uses it yet.

Writing about this project

Other projects