A full-stack spa booking platform on AWS, with a natural-language concierge that books appointments for guests and an operations console with an AI assistant for staff, all on a fully serverless backend.
Spa booking is a transactional domain where wrong answers have real cost. A concierge inventing availability or double-booking is worse than no concierge at all. The goal: a natural-language booking experience that feels effortless for guests, but is grounded in live data and structurally unable to confirm a slot that doesn't exist.
PureZen runs the full lifecycle: browse services, check availability, book, reschedule, cancel, and look up history through conversation, with a separate administrative console for schedule management and operational insight.
A chat-first booking experience. Guests describe what they want in plain language (“A deep-tissue massage next Tuesday afternoon”); the system resolves the service against the real catalog, checks live availability, and walks them through booking, rescheduling, cancelling, or reviewing past appointments. The conversation state persists per session.
A staff portal with dashboards for daily overview, schedule, guests, users, and analytics. plus an AI assistant that answers operational questions by querying live data (“How many bookings tomorrow?”, “What are this week’s trends?”, “Show me this guest’s history”). Each answer is produced from a real database query, not the model’s memory.
You can explore it yourself; the admin console opens in a read-only demo, with the dashboards and AI assistant live while changes are disabled so the shared data stays intact.
A serverless design on AWS with no always-on application compute to maintain. The static frontend is delivered from S3 via CloudFront; API traffic flows through API Gateway to a containerized Lambda.
Guest and staff experiences share one backend, with deterministic booking logic and AI only where language adds value.
Two interfaces use the same application and data layer.
The frontend is static, cached at the edge, and separated from application compute.
The API scales with demand and owns booking rules, auth, and tool execution.
Availability and bookings stay deterministic; Claude handles language and tool selection.
The concierge never answers from training knowledge. Services are resolved against the real catalog, availability and bookings come straight from DynamoDB, and the booking, reschedule, and cancel flows are deterministic state machines. Claude’s job is to understand intent and phrase the response when it physically can’t surface a slot the database didn’t return. That keeps every booking action traceable back to a specific query.
A regex-based intent router handles the common, well-formed requests, including dates, times, service names, and booking IDs, without a model call, and Claude (Haiku 4.5) is invoked for the genuinely conversational or ambiguous turns. Keeping the model a fallback rather than the front door means lower latency and predictable cost on the hot paths.
The staff assistant is built on Anthropic tool use, in a structure inspired by the Model Context Protocol: a clean separation between the model, a registry of typed tools, and the live data behind them; this is implemented as a focused in-app tool layer rather than a full MCP server. The tools, including get_bookings_by_date, get_staff_roster, get_customer_history, get_trends, get_upcoming_bookings, and more, are typed data operations the model can call to answer a question, then summarize. The model decides which data to fetch; the tools guarantee it’s always real.
The most reliable features used the least AI. Anything with an exact answer, such as availability, trend counts, or a guest’s history, is a deterministic function reading live data, which is faster, cheaper, and more predictable than asking a model. The LLM is reserved for language understanding and phrasing, where it’s genuinely the right tool.
PureZen began as an AWS Academy capstone using the infrastructure available in that environment, including EC2, load balancing, VPC networking, routing tables, and IAM. That first generation gave me hands-on experience with traditional AWS infrastructure, but the Academy environment was intentionally constrained and temporary.
The second generation moved the application outside the Academy environment: the frontend was hosted on Vercel and the FastAPI backend ran on Hetzner. That removed the Academy lifecycle constraint, but it still left the application split across external hosting and persistent backend compute.
The third generation brought the application back to AWS and re-platformed it around managed services: container-image Lambda + API Gateway for the FastAPI backend, DynamoDB for application data, private S3 + CloudFront for frontend delivery, and AWS CDK v2 for reproducible infrastructure. The local Ollama runtime dependency was also removed from the deployment path in favor of managed Anthropic inference.
Each move removed a constraint from the previous version instead of rebuilding for novelty.
EC2, load balancing, VPC networking, routing, and IAM.
Static frontend with a persistent FastAPI backend outside the Academy lifecycle.
Lambda, API Gateway, DynamoDB, private S3, CloudFront, and AWS CDK.
An early environment loss, when the system existed only AWS Academy, made reproducibility a first-class concern. The stack is now declared in AWS CDK, so the entire environment (compute, gateway, CDN, data, IAM, and frontend deploy with cache invalidation) rebuilds from code rather than memory.