console: a thread that shows what the customer actually received
The order was right — the audit rows are in sequence and the panel rendered them in sequence. Two other things were wrong. A MESSAGE THE CUSTOMER GOT WAS NOT IN THE THREAD. After "Okay I confirm the policy go ahead" the panel showed nothing from us until their next question, so it read as though we had ignored somebody agreeing to buy. We had not — the confirmation went out immediately — but it was composed inside a trigger node and never written to a field, and the console can only show what the workflow records. 90 stores it in customer_answer, so it appears here and in the trail. An operator reviewing an acceptance no human took needs to see exactly what the customer was told at the moment they said yes. ORDERING IS NOW (timestamp, id). One submission writes three rows in the same second — the trigger commit, its repeat, the settle — so a timestamp alone left their order to the sort's stability, and a reply could print before the message it answered whenever the two landed in the same second. It had not happened yet; it was waiting to. DE-DUPLICATION ONLY COLLAPSES AN IMMEDIATE REPEAT, not any repeat anywhere in the thread. A customer who asks the same thing twice because the first went unanswered has said it twice, and a thread that silently showed it once would hide exactly the impatience an operator needs to see. Only a same-side, same-words turn directly after its twin is the platform talking to itself. The footer says which sends are still absent and why: the quote (a registered template, not text we compose) and the read receipt (which would sit between every question and its answer). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f4c67310cb
commit
5d146e9ffb
@ -11,18 +11,31 @@ import './Conversation.css'
|
||||
* right.
|
||||
*
|
||||
* WHAT IT CAN AND CANNOT SHOW, said plainly at the foot of the panel rather
|
||||
* than left for someone to discover. Every message the workflow RECORDS is
|
||||
* here: the customer's replies (customer_reply) and the replies written back
|
||||
* (customer_answer). The three automatic sends are not. The quote goes out as
|
||||
* a registered WhatsApp template, and the acknowledgement and the acceptance
|
||||
* confirmation are composed inside trigger nodes and never written to a field.
|
||||
* A thread that quietly omitted them would be worse than one that says which
|
||||
* parts it holds.
|
||||
* than left for someone to discover. The console can only show what the
|
||||
* workflow RECORDS, so anything sent from inside a trigger node and never
|
||||
* written to a field is invisible here however certainly the customer received
|
||||
* it. The acceptance confirmation used to be exactly that — the panel showed
|
||||
* nothing after "I confirm", which read as though we had ignored somebody
|
||||
* agreeing to buy — so 90 writes it into customer_answer and it appears.
|
||||
*
|
||||
* Two sends remain absent by choice: the quote, which is a registered WhatsApp
|
||||
* template rather than text we compose, and the "I have your message" receipt,
|
||||
* which would put a line between every question and its answer.
|
||||
*
|
||||
* A thread that quietly omitted any of this would be worse than one that says
|
||||
* which parts it holds.
|
||||
*/
|
||||
function turnsFrom(rows) {
|
||||
if (!Array.isArray(rows)) return []
|
||||
const out = []
|
||||
const ordered = [...rows].sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)))
|
||||
// Sorted on (timestamp, id). One submission writes three rows in the same
|
||||
// second — the trigger commit, its repeat, and the settle — so a timestamp
|
||||
// alone leaves their order to the sort's stability and puts a reply before
|
||||
// the message it answers whenever the two land in the same second.
|
||||
const ordered = [...rows].sort((a, b) => {
|
||||
const t = String(a.created_at).localeCompare(String(b.created_at))
|
||||
return t !== 0 ? t : (Number(a.id) || 0) - (Number(b.id) || 0)
|
||||
})
|
||||
for (const r of ordered) {
|
||||
const fields = Array.isArray(r.fields) && r.fields.length
|
||||
? r.fields
|
||||
@ -35,15 +48,17 @@ function turnsFrom(rows) {
|
||||
if (base === 'customer_answer') out.push({ side: 'us', text: v, at: r.created_at, key: r.id + '-out' })
|
||||
}
|
||||
}
|
||||
// One submission can be recorded more than once (the trigger commit and the
|
||||
// settle both carry the payload), so the same sentence would print twice.
|
||||
// De-duped on side + text rather than on the row id for that reason.
|
||||
const seen = new Set()
|
||||
return out.filter((t) => {
|
||||
const k = t.side + ' ' + t.text
|
||||
if (seen.has(k)) return false
|
||||
seen.add(k)
|
||||
return true
|
||||
// One submission is recorded three times — the trigger commit, its repeat,
|
||||
// and the settle — so the same sentence would print three times.
|
||||
//
|
||||
// De-duped against the PREVIOUS turn only, not against the whole thread. A
|
||||
// customer who asks the same thing twice because the first went unanswered
|
||||
// has said it twice, and a thread that silently showed it once would hide
|
||||
// exactly the impatience an operator needs to see. Only an immediate repeat
|
||||
// of the same side and the same words is the platform talking to itself.
|
||||
return out.filter((t, i) => {
|
||||
const prev = out[i - 1]
|
||||
return !(prev && prev.side === t.side && prev.text === t.text)
|
||||
})
|
||||
}
|
||||
|
||||
@ -105,9 +120,11 @@ export default function Conversation({ rows, name, onClose }) {
|
||||
</div>
|
||||
|
||||
<p className="conv__note">
|
||||
Shows the customer's messages and the replies written back. The quote
|
||||
itself, the read receipt and the acceptance confirmation are sent
|
||||
automatically and are not recorded as text, so they do not appear here.
|
||||
Shows the customer's messages and everything written back to them,
|
||||
including the acceptance confirmation. Two automatic sends are not here:
|
||||
the quote, which goes out as a registered WhatsApp template rather than
|
||||
text we compose, and the “I have your message” receipt sent
|
||||
before anything has read it.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user