The idea was not mine. I was handed a concept for a Phuket service, and my job was to turn it into a working system. Somewhere between six buttons and the first real request, PostgreSQL appeared.
In July I was brought onto a project with a fairly clear idea.
People who live on Phuket wanted to gather into one Telegram bot the things that usually exist separately from each other: renting housing, bikes and cars, visas and border runs, currency exchange, useful information and help in emergencies.
The project already had people who understood the local market, negotiated with partners and worked out what the service should be.
My part was different: to assemble it technically.
That is how “Neznaika about Phuket” appeared.
In the beginning there were six buttons
The first outline looked almost harmless:
- property;
- cars and bikes;
- visa and border run;
- currency exchange;
- SOS and useful info;
- the channel.
Looked at from a distance, you might decide this is about an evening’s work. That is a dangerous distance.
Because behind the button “Rent a bike” a scenario appears fairly quickly.
What kind of transport is needed?
For how long?
From what date?
Is delivery required?
Where to?
How do we contact the person?
Then you need to show a summary, allow the data to be corrected, save the request and hand it to whoever will handle the order.
Border runs are more fun still: direction, stamp type, day or night trip, children, travel date, seat in the minibus, contact number, pickup point, surcharges and the final price.
A button gradually turns into a small business process.
I was assembling a graph, not a chat
I built the bot as a set of connected scenarios.
There are nodes with text.
There are buttons.
There are variables.
There are conditions.
There are transitions between branches.
There are external requests.
There are states that must be remembered between messages.
This turned out to be more convenient than trying to picture the whole project as one long dialogue.
The user sees several messages in Telegram. I see a graph.
And the bigger the bot became, the more obvious it was that the messages are not the main thing here. The main thing is where the person arrived, what they have already chosen, and what the system should do next.
Then a place for requests was needed
I did not want to overcomplicate the first versions ahead of time. So requests from the different branches started accumulating in Google Sheets: rentals separately, border runs separately, property, currency exchange.
For a small project a spreadsheet is a wonderful thing. You can open it with your eyes. You can fix data quickly. You can hand it to a manager without a separate admin panel and weeks of building something nobody needs yet.
So for a while the architecture looked roughly like this:
Telegram → scenario → request → Google Sheets
For a first working version that was enough.
Then the request grew a second end
If the bot has collected a request, that does not yet mean anything has happened. A person has to see it.
So the next piece of the system appeared around the managers. The request arrives in Telegram. A manager can accept it or decline. After the button is pressed the status changes. The user gains the ability to see their own requests.
Which means a small operating system gradually formed around the bot:
client → request → manager → status → client
Nobody said “let us build a CRM”. It simply turned up inside one day.
Property broke the simple architecture
With bike requests everything is fairly linear. Collect the data, hand it over, wait for an answer.
Property works differently. A person needs options. Options have a district, a price, a number of rooms, a rental term and other parameters. Partners may keep their listings each in their own place. The user wants to filter the catalogue, look at several offers, choose a specific one and only then send a request.
And here the spreadsheet stopped being merely a spreadsheet of requests. I started using it as a data source for a catalogue. And that is entirely different work.
With a small number of listings everything looks fine. Then one more partner appears. Then more data. Then the bot has to filter it quickly for each user.
And one day it becomes clear that Google Sheets is slow not because Google is bad. I simply asked a spreadsheet to impersonate a database.
So PostgreSQL is appearing now
This is the part I am rebuilding. The idea is fairly simple.
Partners do not need to change their usual way of working just because we now have a bot. They can keep their data where it suits them. And a separate process periodically picks up the changes and puts them into PostgreSQL. From there the bot gets the catalogue for search and filtering.
It comes out roughly like this:
partner sources → sync → PostgreSQL → bot
For me this is far more interesting than simply “installed Postgres”. The database did not appear because architecture looks more respectable with one. It appeared at the moment when real usage made the old solution inconvenient.
I generally like this way of growing systems. First the simplest thing that works. Then a problem. Then the next layer. Not the other way round.
In parallel the bot kept expanding
Besides the commercial branches, a large section of useful information appeared.
Documents.
Immigration questions.
Passports.
Police.
Road accidents.
Medicine.
Emergency numbers.
Various everyday situations on the island.
As a result there are no longer several linear dialogues inside, but a fairly large graph with its own menus, returns, fallback scenarios and separate pieces of logic.
And somewhere around then the phrase “a bot with services” stopped describing what was happening. It is more a small interface between a person and a pile of scattered things around them.
And then a request arrived
On 11 August the bot received a real currency exchange request.
Not a test one. Not mine. Not from someone on the team who can be told “I am about to break this, do not touch it”.
Someone simply opened the bot, went through the scenario and sent a request.
One user. One request. No beautiful growth charts.
But for the project it turned out to be a rather important moment.
While you are the only user of a system, a strange button remains a strange button. You can redo it tomorrow. You can delete half a branch. You can clear the table. You can break something in the evening and fix it in the morning.
When another person arrives, inside that same system there suddenly appear:
- their time;
- their money;
- their contact details;
- their expectation of a result.
And the architecture stops being exclusively your own problem.
The first people are already changing what I build
The next question appeared almost immediately. What do we do when there are several managers?
Send the request to all of them?
First to accept takes it?
Should it be hidden from the rest?
Show the client’s contact straight away or only after acceptance?
What happens if two people press the button at the same time?
A week ago these questions could calmly be postponed. Now they are the next part of development.
And that, perhaps, is the most interesting thing in the whole project. The architecture is starting to be defined not by my idea of a beautiful system. It is starting to be defined by the behaviour of the people inside it.
What is actually mine here
Not the idea of the service. Not knowledge of Phuket. Not the partner agreements.
I am the assembler of this system. What comes to me is scattered requirements, real processes and the constraints of Telegram. And then it all has to become one thing: scenarios, state, requests, integrations, catalogues, managers, statuses, synchronisation and now PostgreSQL.
That is probably why I am putting this project in “Lab” rather than “Work”. It is not finished. I may open today’s graph in a month and discover half the architecture is gone. And here that is normal.
Because what interests me is exactly the moment of turning.
You are given an idea.
You assemble a prototype.
Then the prototype starts doing real work.
And then people come into it.
And only then does development begin.
The bot: @neznaika_phuket_bot. The project is evolving, so individual scenarios and the internal architecture are still changing.