- Industry
- Lifestyle concierge · UK errand services
- Type
- Telegram bot + client/admin web
- Role
- Architecture · bot · FastAPI · schema
- Roles
- Client · concierge team · admin
- Stack
- Telegram · Claude · FastAPI · Postgres/SQLite
- Proof
- 4 running screens · 4-table schema
The problem
Reservations, tickets, gifts and short trips still depend on facts a form usually misses: the full address, a phone number, the spelling of a name, the time window, the budget, and the things the person will not accept. Collecting those facts is slow. Making the booking is a second job. Finding out whether anyone is actually working on it is a third.
Constraints
Delivery stayed inside the client's stack, tenancy, compliance and media-ownership boundaries. Where a choice was forced (suite vs owned plane, BYOC vs CPaaS, local vs cloud models), the architecture section below records the trade-off rather than a marketing rewrite.
Self-serve apps leave that work with the client. A traditional personal assistant is priced for someone who needs help every day. The gap is the person who needs a few real-world tasks a month and wants them handled — not turned into another inbox.
| What goes wrong | Who feels it | What Bob changes |
|---|---|---|
| Request arrives without address, time or budget | Concierge team | Bob asks for one missing fact at a time — never invents it |
| Client cannot tell if anyone is working | Client | Each task has ordered stages and a written update log |
| Staff receive raw chat instead of a brief | Concierge team | Claude writes task type, requirements and action items |
| Price appears only after the work is done | Client | GBP estimate + 12.5% fee before handoff |
| Occasional and heavy users pay the same | Business | Free, Basic and Pro change the standard-task fee |
This is not a missed-call AI receptionist or a SIP voice agent. It is not a CCaaS dialer. Bob is chat-first concierge with a human finish line.
What the product does
- The client messages Bob on Telegram.
- Claude asks for real-world details and suggests options — addresses, phone numbers and names are never assumed.
- When the brief is complete, Bob quotes the booking in GBP, adds a 12.5% service fee, and asks if the price is acceptable. Card numbers are never taken in chat.
- If the client agrees, Bob ends with
TASK_READY. The bot posts a structured brief and full chat to the Telegram admin channel; the web app stores the task. - Claude proposes four to six stages. The first is always “Request Received”.
- The client follows progress on the web. An admin moves stages, assigns work, and writes updates.
Two task sizes sit on top of that flow:
- Breeze — a known, short action (usual salon, named restaurant, standard online order). Fee is £9 on every plan.
- Standard — research or harder arrangement (finding the right restaurant, sourcing a gift, getting tickets). Fee is £40, £30 or £15 depending on plan.
One door, three keys
| Role | Where they work | What they see and do |
|---|---|---|
| Client | Telegram → /dashboard, /task/{id} | Own requests, price, stage bar, notes. Cannot see other clients. |
| Concierge team | Telegram admin channel → admin web | Brief at handoff, then every client’s tasks, deadlines, stage controls. |
| Admin | /admin/login, /admin/dashboard | Operational view. Account must have is_admin — client login is rejected. |
Sample accounts in these captures:
| Person | Role | Sample request | |
|---|---|---|---|
| Maya Chen | maya@example.com | Client | Sushi table near Covent Garden; birthday gift |
| Jonah Ellis | jonah@example.com | Client | Two tickets for The 1975 |
| Ada | ada@example.com | Admin | Runs the task list — not the client view |
Client dashboard — only your work
Maya signs in at /login and lands on /dashboard. Jonah’s ticket request does not appear. Counts on this capture: one active task, one completed, nothing pending.
Honest chrome: “Total Spent” shows a fixed £520 placeholder in the current template — it is not calculated from task prices.
Client task page — read-only progress
“View Details” on the restaurant booking opens /task/1. Quote, stage bar, latest note, requirements and action list — no control to mark a stage complete. The way back to the team is Telegram.
The bar is at “Researching Options” — two stages done out of five. The note stored for that task: two rooms near Covent Garden can take four people at 19:15.
Admin dashboard — every client, one table
Ada signs in at /admin/login. The dashboard lists every task with client name joined from users through telegram_id. Filters cover status, type and deadline. Deadline on this screen is a demo rule: three days after created_at. Maya’s gift task deadline is already past — shown in red.
Admin task page — where work happens
/admin/task/1 is the operational view for the same restaurant booking Maya sees read-only:
- Client name, status, generated deadline
- Requirements and action items the bot stored
- Stage bar with “Complete Current Stage”
- Update box that posts a new note onto the task
Worked example — Maya’s restaurant booking
Sample message: table for four, sushi near Covent Garden, Friday around 19:00, chill but not too casual. Bob still collects phone, dietary limits and budget before the quote.
| Table | Row for this request |
|---|---|
users | Maya Chen, Telegram id 9001001, is_admin false |
tasks | Restaurant booking; status In Progress; price “£186 including 12.5% fee”; assigned Priya Shah |
task_stages | Request Received + Researching Options done; three stages open |
updates | Two rooms near Covent Garden can take four at 19:15 — waiting on quieter room |
Jonah’s ticket request uses Telegram id 9001002 — visible to Ada, not to Maya. That is client isolation by telegram_id, not by hope.
What the client pays
Membership changes the standard-task fee. Breeze stays £9. In chat, Bob estimates the underlying booking cost in GBP and adds 12.5% before asking the client to accept. Payment after agreement is handled by the concierge team — not in Telegram.
| Plan | Monthly | Breeze | Standard | Intended use |
|---|---|---|---|---|
| Free | £0 | £9 | £40 | 1–2 tasks a month |
| Basic | £50 | £9 | £30 | 3–5 tasks a month |
| Pro | £149 | £9 | £15 | 6+ tasks a month |
Maya’s “£186 including 12.5% fee” in the screenshot is an in-chat estimate example — not the membership fee itself.
Database — four tables
Postgres 14 from database/db-init.sql. Tasks point at people through telegram_id, not users.id, so a task can remain if web login is removed. Without DATABASE_URL, the same four tables land in SQLite (web_app/concierge.db) — that is what backs these screenshots.
| Table | Job |
|---|---|
users | Telegram id + email; bcrypt hash; is_admin gate |
tasks | One accepted request; requirements, action items, status, estimated_price text |
task_stages | Progress bar — Claude proposes 4–6 stages; staff complete from admin |
updates | Note history under the stages |
Indexes on tasks.telegram_user_id, task_stages.task_id, updates.task_id — client dashboard and task page stay one-query simple.
How the system flows
The handoff is the product decision. Until TASK_READY, the conversation is with Bob. After it, a person owns the booking and the web page is the record.
flowchart TD ask[Client messages Bob on Telegram] details[Bob collects address phone time budget] price[Bob quotes GBP plus 12.5 percent fee] handoff[Client agrees TASK_READY] save[Web app stores task stages brief] channel[Admin Telegram channel gets brief] work[Concierge completes booking] track[Client watches stages and notes] done[Admin marks task complete] ask --> details --> price --> handoff handoff --> save handoff --> channel save --> work --> track --> done
Architecture
The rule: the bot talks to Claude and the admin channel; both dashboards read and write through FastAPI.
flowchart TB clientWeb[Client web dashboard task] adminWeb[Admin web dashboard task] bot[Telegram bot] api[FastAPI web app JWT] claude[Claude API] channel[Telegram admin channel] db[(Postgres or SQLite)] clientWeb --> api adminWeb --> api bot --> api bot --> claude bot --> channel api --> db
Production compose puts Nginx and certificate renewal in front of the app. Local development serves FastAPI directly — how these screenshots were captured.
Engineering challenges
| Problem | Approach | Residual |
|---|---|---|
| Chat without structured handoff | TASK_READY + stored requirements and action items | Prompt discipline — not a second parser service |
| Client sees other people’s errands | Tasks keyed by telegram_user_id | Admin sees all — by design |
| Price shock after the fact | GBP estimate + 12.5% before handoff | Not a payment gateway in v1 |
| Staff need ops controls clients must not have | Separate admin routes + is_admin | Role is a DB flag, not OAuth federation |
| Local demo without Postgres | SQLite fallback with same four tables | Integer keys and 0/1 booleans |
My role
Architecture through working product: Telegram bot and Claude prompt, TASK_READY handoff, FastAPI client and admin templates, four-table schema, stage and update model, pricing rules in bot and web.
Telegram Claude FastAPI PostgreSQL JWT
Engineering outcomes
No invented task volume or concierge ROI. What the running UI and schema actually show:
- Telegram-first intake with explicit human handoff marker
- Client dashboard scoped to one Telegram identity
- Admin dashboard with stage completion and update posting
- GBP pricing rule (estimate + 12.5%) before
TASK_READY - Breeze vs Standard membership tiers on the pricing page
- Four-table schema with cascade deletes on stages and updates
- Honest gaps: Total Spent placeholder, demo deadlines, live bot needs secrets
Architectural insight
If the concierge team gets a paste of chat, you built a forwarding service. If the client cannot see stages, you built a black box. The product is the handoff — structured brief, agreed price, shared web record — with Claude as the intake clerk, not the owner of the booking.
Related: Multi-tenant AI receptionist (voice receptionist SaaS), AI chatbot development, multi-tenant SaaS, and full-stack product builds.
Production considerations
- Telegram handoff when LLM confidence low — human thread preserved.
- Secrets and webhook validation on public bot endpoints.
FAQ — buyer & architecture questions
Ten common questions about this case study, fit, and engagement.
Building a concierge product you own?
Share where clients start (Telegram, WhatsApp, web chat), how you price, who completes the booking, and what the client must see while waiting. The first reply is architecture — not a per-task quote.
Discuss Your Project