cd ~cases/kids-cafe-bot.md

case 02LIVE · RUNNING AT THE CLIENT

A Telegram bot that took the phone calls out of a kids' café's bookings

A kids' café took party and playground bookings only by phone and in messengers. I built a Telegram bot that handles bookings, an availability calendar, reminders and records for the owner.

Timeline
~2 weeks to production · ~3 weeks to handover
Stack
Python · aiogram 3 · SQLite · SQLAlchemy async · APScheduler · Telethon e2e · pytest · systemd
Built by
Forge Logic
723automated tests at the end — 49 at the start
~2 wksfrom the first line of code to production
3roles: client, staff, admin
42live e2e scenarios right through Telegram — 8 at the start
157findings in the first code audit → 8 refactoring phases
16development and polishing phases
A Telegram bot that took the phone calls out of a kids' café's bookings0:30

What was broken

Bookings came in by phone and messages. Nobody saw the full picture of availability. Two big parties renting the whole café could land at the same time.

Workshops were often cancelled for lack of kids. People signed up, but nobody told them in time when a group was filling up.

Client requirements

  • No separate website or domain at the start — Telegram only.
  • The owner changes prices and packages herself, without a developer.
  • A warm tone, because the audience is parents with kids.

The solution

The bot has three independent “entrances” by role. On start it detects who is writing: admin, staff or client. Everyone sees only their own menu.

Bot diagram: Telegram → role detection → role menu → service layer → SQLite; the scheduler reads the same database
  • Client side. Booking the playground, a party, a workshop or a table. Registering a child’s birthday. “My bookings” and “My details”. Contacts with a map link.
  • Staff panel. Bookings for today and the coming days, “done” / “no-show” marks, the bot’s QR code for the reception desk. Access via a one-time invite code from the admin.
  • Admin panel. Editing packages, prices, workshops, animators and tables. Viewing and cancelling bookings. Newsletters to those who opted in. Stats. An error log.
  • The service layer sits between the menus and the database. All business logic lives here: prices, availability checks, input validation. Button handlers only call these functions, so one rule isn’t duplicated in four places.
  • The database is SQLite. One file on disk, no separate server — enough for one café. The test database is fully isolated.
  • The scheduler runs tasks on a timetable: reminders a day before a booking and yearly birthday greetings for the kids.

Development story

feat(core)#01

Kick-off and the first working bot

What happened: the owner had no ready vision of how it should work.

How we fixed it: we wrote a spec, went through every pain point, settled the feature set and built the skeleton.

fix(animators)#02

An animator can't be at two parties

What happened: an animator can only be at one party at a time, even if the café isn’t fully rented. The first version forced you to pick every animator or cancel the booking.

How we fixed it: a separate choice for each slot, with a “Don’t choose” button. Animators busy at that time simply aren’t in the list.

fix(roles)#03

Each role sees only its own menu

What happened: the admin and staff saw the client menu alongside their own.

How we fixed it: a single function detects the role at entry. Each role sees only its own panel.

ops(audit)#04

Audit and refactoring

What happened: after a dozen phases, technical debt piled up. The audit found 157 issues.

How we fixed it: eight refactoring phases. The four critical findings — all about data races — were closed in a dedicated phase.

fix(state)#05

Stale menus after a server restart

What happened: after a server restart, old menus piled up for the admin. The bot kept dialog state only in memory.

How we fixed it: moved dialog state into the same SQLite database. It now survives restarts, and the bot cleans up its old messages.

fix(notify)#06

New-booking alerts didn't reach the admin

What happened: notifications about new bookings didn’t reach the admin.

How we fixed it: the notification logic only looked at the owner and staff. Fixed.

Mini App mockup

Based on the working bot, I made a clickable Telegram Mini App mockup: the same flows, but with a visual calendar, cards and one screen instead of a chain of messages.

01 HomeHome
02 Choosing a packageChoosing a package
03 Date and free hoursDate and free hours
04 Guests and animatorsGuests and animators
05 Photo zone and workshopPhoto zone and workshop
06 ConfirmationConfirmation
07 Staff panelStaff panel
The café name, people and animators in the mockup are made up; prices are illustrative. The step logic comes from the working bot.

Lessons

  • Green tests don’t mean good UX. Almost every inconvenience was found by a live run-through, not by 700+ automated tests.
  • Commits between phases. Every new feature touched the data core, and without a rollback point one bad run would have cost a day.
  • Scope grows by itself. In a week the booking bot became a CRM with three roles. A pause to “live with the product” would have given more than one more feature.

Result

The bot runs on a server as a system service with auto-restart.

  • Clients book parties, the playground, workshops and tables.
  • Staff see the schedule and mark visits.
  • The admin manages prices and gets failures in Telegram.