
AI Concierge Across a Regional Hotel Group — 370 Leads, 92-96.8% Self-Service, Second Property Live in Half the Time
An AI concierge live across Facebook Messenger, LINE, and the brand website for a regional hotel group — 370 cumulative booking leads with no down week, 92-96.8% of conversations handled without a human, and a second property live in 7 days against the first one's 14.
All Case Studies
Auto Financial OpsAutomated Expense Entry into PEAK — 12 of 12 Bill Types Read Correctly, 45 of 48 Real Documents Passed
AI ChatbotOne Owner, 50 Chats a Day — a LINE AI Bot That Took 90% of Them Across 3,260 SKUs
Auto Financial OpsSix Legal Entities, One Message, Every Morning at 07:00 — Multi-Property Hospitality Group
Auto Financial Ops873 Students Off a 900-Parent Group Chat — and 293 Families Found Sitting Under a Silent Do-Not-Chase Flag
Auto Financial OpsA Clinic Group Found Its Own Revenue Report Overstated by 135% — 21.4 Million Against a Real 9.1 Million
AI ChatbotLINE AI File Memory — 30-Second Searches Cut to Under One Second, Delivered 23 Days Early

873 Students Off a 900-Parent Group Chat — and 293 Families Found Sitting Under a Silent Do-Not-Chase Flag
Full Case Study
The Client
A private K-12 school of 873 students across 29 classrooms, collecting tuition from roughly 900 families.
Money arrived three ways at once — slips posted in a shared parent group, slips sent through social messages, and cash handed directly to class teachers. One finance teacher was responsible for reading all three and recording them in a book of her own.
The problem was never that the school could not collect. It was that nobody knew precisely who owed what until somebody opened a file and went through it name by name.
The Challenge: 900 Parents Watching Each Other Pay
One group chat where everyone sees everything. Every time one parent posted a slip to confirm a payment, the other 899 saw the name, the amount, and who had not posted yet. That is not an inconvenience. That is a privacy problem.
A payment-notification channel many parents could not use. The school had a notify button linked to an online form, but many parents could not complete it because they had no account with that provider. The school never had a complete picture of who had paid.
Three routes in, and the most dangerous one is cash. If a teacher takes cash and it does not reach the finance office that day, the system chases a parent who has already paid.
In the old records, "paid" was a row that had been deleted. The survey turned up three things that changed the whole design:
- •The old process deleted the debt row once it was paid — the status "paid" was represented by the absence of that row
- •Outstanding balance was whatever was not highlighted on a printed page
- •Apart from tuition and bus fees, no payment history was kept at all. Other charges went onto one combined receipt and could not be separated back out
There was no existing database to migrate. There was an emptiness to build into.
A list of charge types that never finishes. The project began believing there were 11 types of charge. The real count was around 19 to 20. More importantly, the finance teacher can create a new charge type herself at any time — so the list will never be complete. A system designed on the assumption that every type is known on day one breaks in month two.
What it costs to leave alone. Arrears nobody can see in aggregate do not disappear — they accumulate. And the longer they run, the harder they are to chase, and the more they strain a relationship with a family who will be sending their child here for years yet.
The Client Rejected the First Quotation — but Not Over Price
The first quotation went out as a four-tier menu with discounts. The school's director rejected its shape, not its numbers.
She asked for three things:
- •Treat it as phase one of the school's long-term platform, not a job that ends. Her words were "technology partner".
- •One scope, one price. Agree what is in it, price it once, and anything that arrives later is a new project rather than a package upgrade.
- •Connect to what exists, do not replace it. The school already had a student registry system.
She also added requirements that were not on the menu at all: parent identity verification stronger than a student code, support for one parent with several children and one child with several guardians, a mandatory staff approval step before an AI-read slip counts as money, role-based permissions with an audit trail, backup and restore, full data export, training and handover documents, and a pilot group before going near all 900 families.
Then she asked five questions, none of them about features. Before agreeing, she sent five questions that were really all one question about trust: who owns the data, the export rights and the source code; you mentioned spreadsheets, so what is the real long-term database; what is the approach to security, privacy and backups; what does the warranty cover and how fast are bug fixes; and what happens after the warranty ends.
All five were answered from what the quotation already promised, with no new conditions invented — plus one straight opinion: use the spreadsheet for phase one, because that is what was priced, but a real database is the correct long-term home once the school starts holding health records and incident notes. And no promise was made to build on a real database now, because that work was not in the price.
The Boundary with the Other Vendor — the Most Important Agreement in the Project
Partway through, the school engaged a separate software company for its actual accounting system. So the line between the two was written down, together:
| The school's registry system | This system |
|---|---|
| The school's real books | The counter staff |
| Student registry | The conversation with parents |
| What each family is billed | Reading the slip image |
| Official outstanding balances | Catching a slip sent twice |
| Official receipts | Working out which parent this is |
| Instalment agreements | Proposing what this payment should settle |
| The staff approval screen | |
| The record of who did what, when | |
| The message back to the parent |
And rule number one: whenever the two disagree, the school's registry system is right.
Designing for a future connection was given away free, because it was cheap to do. Designing the actual interface to the other system is a separate, separately priced piece of work.
The Solution: Three Separate Programmes, and One Guarded Exit
One idea holds the whole design up: a message about money cannot be recalled once it has been sent. So there is exactly one way out, and that door has a guard on it.
| Name | What it is | Why it exists |
|---|---|---|
| The main system | 142 steps — everything the school actually touches | This is the product |
| The warehouse keeper | A small programme that is the only thing allowed to touch the data | The main system never touches storage directly. The day the school moves to its registry system, only this one programme changes. It also refuses to overwrite auto-calculated columns, which would corrupt the whole sheet |
| The postmaster | A small programme that is the only thing that can send a message | Every safety switch lives here |
A fourth, smaller one watches the other three and raises an alert the moment any of them fails.
The Nine Steps a Single Payment Travels
| Step | What happens |
|---|---|
| 1 | The parent links their account — student code plus their own phone number in one message. Wrong number is refused, and the child's name is never revealed |
| 2 | They send the slip image — it goes to storage first, so the evidence exists before anything else happens |
| 3 | The AI reads it — amount, date, time, bank reference |
| 4 | Duplicate check — has this reference been seen before? If so, the row is kept and flagged, and nothing that counts money counts it again |
| 5 | Whose is it — matched against the account link. Parent has two children and it is ambiguous, so a staff member decides. The system does not guess |
| 6 | Proposes what it settles — in the order the school confirmed. One payment can settle several charges, across several children |
| 7 | A person approves — money does not move until this happens, and approval is refused outright if the settlement lines do not add up to exactly the amount received |
| 8 | It is recorded — who approved, their role at that moment, the value before and after, the exact time. It cannot be edited or deleted |
| 9 | The parent is told — what was paid, which child, which charge, what remains, visible only for the children that account is entitled to see |
The rule that makes it safe: at step 2 the money is recorded as awaiting verification, never as paid, until a human at step 7 says so — and the parent receives "we are checking this", not "we have received your payment".
Chasing, Split Into Three Separate Actions
08:00 on a working day -> Build the batch (nobody has been contacted)
One message per family, not per child
The longest-overdue child sets the tone
Every family skipped is counted and named
A staff member reads -> Approve the batch (nobody has been contacted)
Finance or admin only — the director cannot approve
10:00 and 14:00 -> Send (only now does a parent hear anything)
And re-check everything first: has it been paid,
has the amount changed, is a slip awaiting review,
is today a no-send day
Approving is not sending. That gap is deliberate — it is exactly the window in which a parent pays, and a system that sends the instant it is approved will chase somebody who has already paid.
The Director Has Fewer Rights Than Her Own Staff, on Purpose
| Role | Can approve money | Can approve a chase batch |
|---|---|---|
| Director | No | No — view only, at her own request |
| Admin | Yes | Yes |
| Finance | Yes | Yes |
| Class teacher | No | No — cash receipts only, in a private chat |
The reason: whoever hands out permissions must not be the person who can approve money. Otherwise they can quietly grant themselves the right and then approve their own work. Separating those two is what gives the audit trail any meaning.
Signing in is a two-step process for the same reason. A staff member introduces themselves in the group, which records who they are and grants them zero rights. An admin then has to assign the role. Until both steps are done, every command from that person is refused and logged.
Things Built for Free, Because the School Described Real Detail
| What the school said | What was built |
|---|---|
| Different charges fall due on different dates | Bus fees carry their own due date, separate from tuition, and apply only to children actually behind on that charge |
| We will keep adding new charge types | If the system meets a type it does not recognise, it says so in plain Thai and refuses rather than quietly splitting the money wrongly |
| A parent with two children sends one slip | The old approach guessed silently. Now a staff member decides, and every child on that account is shown |
| A teacher holds cash that has not reached finance yet | The system ages that cash and warns staff internally — never the parent |
The Results
| Before | After |
|---|---|
| Slips posted to a group of 800-900, everyone seeing everyone | A private chat — nobody sees anybody else's |
| Payment notified through a form many could not complete | Send the slip image in chat, done in one step |
| "Paid" = a deleted row, no history | Every movement recorded permanently, no edits, no deletes |
| Nobody knew who owed what without going through a file | A receivables ledger of 1,027,634 baht across 82 students, visible immediately |
| Cash and slips could both be recorded for the same payment | Cross-channel duplicate detection, plus ageing on cash a teacher is holding |
| Wrong settlements discovered afterwards | The system refuses approval unless the amounts match exactly |
| Nobody knew who was exempt from chasing | 293 families identified, each with its reason |
1. 293 of 873 families were sitting under a do-not-chase flag, and 238 of them had no tuition figure recorded at all
Before the project, the school had marked certain families as "do not chase". Nobody had ever added up how many.
Checking the real data found 293 families:
| Group | Count | Value |
|---|---|---|
| Chaseable | 28 | 413,915 baht |
| On a payment arrangement | 43 | 564,963 baht |
| Staff families | 11 | 48,756 baht |
And 238 of the 293 had no tuition figure recorded at all.
A do-not-chase flag with no instalment schedule attached to it is not leniency. It is a write-off nobody decided to make.
2. Messages sent to real parents across the whole project, up to handover: zero
The chasing system was finished, passed its joint testing, and was ready to run. The send switch stayed off the entire time.
| Switch | State | What it means |
|---|---|---|
| Safe mode | On | No real parent received anything |
| Master send switch | Off | The exit door is locked |
| Batch send switch | Off | The send step refuses to run |
| Batch build switch | On | Batches can be built so the wording can be reviewed |
The count of messages sent to real parents is zero, because the director had not yet approved the final wording.
There is an allow-list for testing — named accounts do receive real messages while every parent stays blocked — and blocked messages are still written to the log anyway, so it can be proven that the message would have been correct had it gone out.
For a system that talks to parents about money and about their children, the fact that it can genuinely hold still, exactly as designed, matters more than the fact that it is fast.
3. Four joint test rounds with the school caught defects that 19 automated suites had all passed
The project had 19 automated test suites, all green.
The first round sitting with the finance teacher and the director found 6 defects, not one of which any automated suite had caught.
| Round | Result |
|---|---|
| 1 | 24 of 24 items passed — but 6 defects surfaced during testing, all fixed the same day |
| 2 | 2 items failed, including the most dangerous case of all: money entering the system without reaching the child's account |
| 3 | Fixed and proven, plus the alerting system passing 6 of 6 |
| Final | 14 of 15 passed. The remaining item was a case that does not exist in reality |
Two Bugs With the Same Face: the System Looked Fine and Had Never Seen Real Data
Two bugs found during internal testing had precisely the same shape, and both are worth remembering:
- •The cash-versus-slip duplicate detector passed every offline test, and could never have worked in real life, because it was only ever fed one row at a time, so it never saw a duplicate pair together
- •The staff review card was being re-sent every 30 minutes for as long as nobody had reviewed it — fixed and then proven against a real timer, not just in a test
The same lesson both times: a test suite fed with data the real system would never feed it will pass every time, and die in the field.
The Blanks Left Deliberately Empty
Right up to handover, some decisions stayed with the school rather than with us — the final wording of the reminder messages, how many days a teacher may hold cash before a warning, whether general announcements and money messages share one opt-out, the settlement order for new charge types, and the instalment terms.
Every one of those was left blank in the system rather than guessed.
A number you invent becomes a rule the school never agreed to.
What the System Found the Moment It Opened: Real Money With No Owner
As soon as the channel opened, real things started arriving — 4 real accounts, 3 real transfers totalling 20,542 baht sitting at the status "we do not know which parent this is", plus 3 images that could not be read.
The system was configured to receive and queue them without replying — nothing went out to any of them — but real money that cannot be matched is a problem the school has to handle now. It surfaced because, for the first time, something could see it.
A Report That Admitted Its Own Previous Report Was Wrong
The second-phase report told the client, in writing:
"Let me say it plainly: the report of 26 August stated that all 24 items passed, which was true as far as that day's testing went. But after testing with harder cases in the second round, two items turned out not to be genuinely finished."
The client read it and approved that phase as normal.
Voices From the Project
"May I add a little to the proposal, so that it supports long-term use... If it can be designed to support this approach, I think it would suit the school's long-term use very well."
— The school director. This request is why the system was split into three programmes from day one
"I think this method suits the school better than SMS one-time codes, because the steps are not complicated, there is no extra cost, and it should be convenient for most parents."
— The school director, choosing how parents would verify their identity
"Whenever the two disagree, the school's registry system is right — that is rule number one."
— The responsibility boundary, written jointly with the other vendor
Lessons Learned
- •A message about money is the one thing you cannot take back, so the exit has to be a single guarded door. Building, approving and sending were separated into three distinct events, because the gap between approval and sending is exactly when a parent pays.
- •A test suite fed with data the real system never produces will pass forever and fail in production. The duplicate detector was green on every offline run and could never have fired live, because it was only ever shown one row at a time. Fixtures have to be built from the real upstream output.
- •Whoever grants permissions must not be able to approve money. The director asked to be view-only on her own system, and that separation is what makes the audit trail mean anything.
- •Absent data is a design input, not a migration detail. The old process expressed "paid" by deleting the row, so there was no history to move — which is why every movement in the new system is permanent and cannot be edited.
- •Never design against a list that the client can extend. The charge types were thought to be 11, turned out to be around 20, and the finance teacher can add more at will — so the system refuses an unrecognised type in plain language instead of splitting the money wrongly and quietly.
- •Leave the blanks blank. Wording, cash-holding limits and instalment terms were all left empty rather than filled with a plausible guess, because a number you invent becomes a rule the client never agreed to.
- •Correct your own earlier report before the client finds it. Telling them that a previous "24 of 24 passed" did not survive harder testing cost nothing — the phase was approved as normal.
Lots of Individual Debtors, and Afraid of Chasing the Wrong One?
If any of these describes your organisation, the same shape of system applies:
- •Many individual debtors, and nobody can see the whole picture of who owes what
- •Customers send payment slips through several channels, and somebody has to read them one at a time
- •You have had cases of a payment recorded twice, or recorded against the wrong person
- •You want the system to help you chase, but you do not dare let it send on its own
- •You need evidence of who approved what, and when
Separating "write the message" from "send the message" gives you the speed without putting the relationship at risk.
Project Information
More Like This
AI ChatbotAI Concierge Across a Regional Hotel Group — 370 Leads, 92-96.8% Self-Service, Second Property Live in Half the Time
96% MatchAn AI concierge live across Facebook Messenger, LINE, and the brand website for a regional hotel group — 370 cumulative booking leads with no down week, 92-96.8% of conversations handled without a human, and a second property live in 7 days against the first one's 14.
AI ChatbotFive Months After Handover — 96.5% Handled Without a Human, Worth 2.4 Times Its Upkeep, and Leads Recovered from 6 to 23
96% MatchA LINE AI assistant for an occupational safety training institute, built in 7 days and then measured for five months. It handles 96.5% of its conversations without a human and returns 2.4 times what its upkeep costs — and the maintenance habit behind those numbers found 15 of 16 leads quietly going missing, staff alerts dying halfway through every month, and a customer who sent 15 messages without a reply. None of it ever raised an error.
AI ChatbotA 245-Item Catalogue Bot That Would Rather Say Nothing Than Guess a Price — a 156,000 Baht Error Caught Before Go-Live
96% MatchA price-quoting bot on LINE and Facebook for a building-materials distributor with 245 products whose model codes overlap. Every price it is about to say is checked against the catalogue first — if it does not match, the bot stays silent and alerts a human instead. That guard caught a pricing error worth 156,000 baht on a single 1,000 sqm job, two days after the build had already passed 10 out of 10 acceptance tests.