Skip to content
KummaLabsDescribe your project

Sample diagnostic report

Phone-order flow: what breaks between “that’s everything” and a saved order

This is what you receive at the end of an integration diagnostic. It is a real one. We ran it on our own system, KOTA, on November 12, 2026, and it found defects we hadn’t known about. The only thing missing is the fixed price and delivery time for each fix, which a client report includes.

Findings
5: three high, two medium
Checks that passed
2
How it was tested
Seven targeted tests against the real code, with the database and messaging provider replaced by controlled fakes
Status
Open. KOTA is not deployed, and these are fixed before it is.

Scope

Looked at

The English order path from the caller finishing an order to a stored order record and a confirmation text, plus the two web entry points that path depends on.

Not looked at

  • The Mandarin order path, which has its own code.
  • Two order requests arriving at the same instant.
  • Behaviour under load, and against the real phone and messaging providers.
  • Hosting and deployment settings.

Findings

  1. HighReproduced

    1. A failed save is announced as a confirmed order

    When the database write fails, the save function hides the error and returns nothing. The order step doesn’t check the result, so it marks the order as placed, clears the cart, texts the caller, and says the order is confirmed.

    The caller arrives to collect an order that doesn’t exist. The “#N/A” in the text is the only trace that something went wrong.

    Save function, with the database write forced to fail

    save_order_details on DB error -> None

    What the agent then said

    Perfect, your order at Golden Bowl Noodle House is confirmed for $30.40 and I just texted your order details. Thank you for calling.

    The text it sent

    Golden Bowl Noodle House: your pickup order is confirmed (#N/A). 2x Beef Noodle Soup, 1x Jasmine Tea. Total $30.40. Thank you.

    Proposed fix
    Treat a missing order number as a failure: keep the cart, tell the caller there was a problem, offer the transfer to staff, and raise an alert.
    Done when
    With the database write forced to fail, the agent does not say “confirmed”, no confirmation text is sent, the cart is unchanged, and an alert is logged.
  2. HighReproduced

    2. An order number can be issued for an order that was never stored

    Orders are saved by updating a row created at the start of the call. If that row is missing, the update changes nothing, the database reports zero rows, and the function still returns a new order number.

    The outcome is the same as finding 1, but with a believable reference number, so it is harder to notice. The row it depends on is written by a separate step that can fail on its own.

    The statement

    UPDATE calls SET order_id = $1, metadata = $2 WHERE call_sid

    The database’s answer, and what the function returned anyway

    DB said: UPDATE 0 | function returned: 'ORD-CA_SYNTHETIC-17...'

    Proposed fix
    Store each order as its own record, and return an order number only when exactly one record was written.
    Done when
    With no call row present, placing an order either creates a complete order record or fails as in finding 1. An order number is never returned without a stored record.
  3. HighReproduced

    3. Call transcripts and caller phone numbers are readable without a login

    The routes that list calls and what was said on them have no authentication.

    Anyone who finds the address can read what callers said, along with their phone numbers.

    Request with no credentials (synthetic data)

    GET /api/db/utterances (no credentials) -> 200 {'count': 1, 'data': [{'id': 1, 'call_sid': 'CA_SYNTHETIC_0001', 'speaker': 'caller', 'text': 'two beef noodle soups', 'caller_phone': '+15555550100'}]}

    Proposed fix
    Require authentication on every data route, remove the debug route, and limit each restaurant to its own calls.
    Done when
    Without valid credentials every data route answers 401. With one restaurant’s credentials, another restaurant’s calls are not returned.
  4. MediumReproduced

    4. The call webhook accepts requests that don’t come from the phone provider

    The route the phone provider calls when a call starts does not verify the provider’s signature.

    Anyone can start call flows with made-up caller details, which costs money and pollutes the call log.

    A forged request with no signature

    POST /api/incoming-call (no X-Twilio-Signature) -> 200 application/xml <?xml version="1.0" encoding="UTF-8"?><Response><Say voice="Polly.Joanna-Neural">Welcome to our restaurant.</Say><Gather …

    Proposed fix
    Verify the provider’s signature on every webhook and reject everything else.
    Done when
    An unsigned or wrongly signed request gets 403. A correctly signed one behaves as it does today.
  5. MediumRead from the code, not run

    5. Every restaurant’s “press 0” transfers to the same phone number

    The transfer number is a single setting for the whole system, while menus and prompts are stored per restaurant.

    With more than one restaurant, a caller asking for staff reaches the wrong business.

    Proposed fix
    Store the transfer number per restaurant, and define what happens when one isn’t set.
    Done when
    A call for restaurant A transfers to A’s number. A restaurant with no number set gets a spoken apology, never another restaurant’s staff.

What held up

  • Placing the same order twice in one call

    The second attempt is refused and only one confirmation goes out.

    SECOND place_order -> Your order has already been placed. | confirmations sent: 1

  • A failed text is not reported as sent

    With the messaging provider returning a failure, the agent confirms the order and makes no claim about a text.

    Perfect, your order at Golden Bowl Noodle House is confirmed for $30.40 (reference TEST_1-1). Thank you for calling.

Recommendation

Fix findings 1 and 2 together, since they share one code path and decide whether a confirmed order is real. Then 3, which exposes callers’ data. Then 4 and 5.

Separately, and not a defect: nothing in the system tells the restaurant that an order arrived. That is a new piece of work, scoped on its own.

In a client report, each group of fixes carries a fixed price and a delivery time, and you choose which to go ahead with. If the right answer is to stop, or to use an existing product instead, the report says that.

Want this for your agent or automation?

Tell us what it does today and where it goes wrong.