order details: hide the review surface for spine-bridged retail rows
ci / lint-test (push) Successful in 58s

Verdicts are the meal lane's feedback loop (loved/never steers the next
restaurant order and the nudge card warns on re-order). Bridge rows
(source='order-bridge': Amazon, eBay, Officeworks...) have no such loop,
so ItemVerdictToggle and OrderVerdict stay hidden there. The order API
now returns 'source'; OrderReceipt.platform widened to string — the
bridge writes real platform slugs beyond the meal trio.
This commit is contained in:
2026-08-10 18:02:51 +10:00
parent 502e3f563c
commit 7f8e363b5b
3 changed files with 28 additions and 15 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ export async function GET(
}
const row = await queryRow(
`SELECT platform, order_reference, line_items, route, subtotal, amount,
`SELECT source, platform, order_reference, line_items, route, subtotal, amount,
currency, card_last4, flags, source_email_subject, transaction_date
FROM expense_metadata
-- A card-settled order creates no transaction of its own (I5): the
+11
View File
@@ -81,6 +81,13 @@ export function OrderDetails({
const mine = review?.reviews.find((r) => r.participant_id === reviewer);
// Verdicts are the MEAL lane's feedback loop — "loved / never again" exists
// to steer the next restaurant order, and the nudge card warns on re-order.
// Spine-bridged retail (Amazon boxes, eBay, Officeworks) has no such loop:
// rating a roller-shade motor "order again?" is noise, so the whole review
// surface stays hidden for bridge rows.
const rateable = receipt.source !== "order-bridge";
return (
<div className={bare ? "" : "border-t border-zinc-800 pt-4"}>
<div className="flex items-baseline justify-between mb-2">
@@ -106,6 +113,7 @@ export function OrderDetails({
<span className="block text-zinc-600">{it.options.join(" · ")}</span>
)}
</span>
{rateable && (
<ItemVerdictToggle
transactionId={transactionId}
reviewer={reviewer}
@@ -114,6 +122,7 @@ export function OrderDetails({
rating={mine?.rating ?? null}
note={mine?.note ?? null}
/>
)}
{/* Spine-bridged receipts (Amazon shipment notices, eBay) often
name the goods without per-item prices — a null here is "the
mail didn't say", and printing $0.00 would assert it did. */}
@@ -152,11 +161,13 @@ export function OrderDetails({
</p>
)}
{rateable && (
<OrderVerdict
transactionId={transactionId}
reviewer={reviewer}
onReviewerChange={setReviewer}
/>
)}
</div>
);
}
+3 -1
View File
@@ -257,7 +257,9 @@ export function useTransactionSplits(transactionId: number) {
}
export interface OrderReceipt {
platform: "doordash" | "ubereats" | "uber" | null;
/** 'email' | 'receipt-scan' | 'order-bridge' | ... — which lane wrote the row. */
source: string | null;
platform: string | null;
order_reference: string | null;
line_items: { qty: number; description: string; amount: number; options?: string[] }[];
route: { label: string; time: string | null; address: string }[];