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( 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 currency, card_last4, flags, source_email_subject, transaction_date
FROM expense_metadata FROM expense_metadata
-- A card-settled order creates no transaction of its own (I5): the -- A card-settled order creates no transaction of its own (I5): the
+24 -13
View File
@@ -81,6 +81,13 @@ export function OrderDetails({
const mine = review?.reviews.find((r) => r.participant_id === reviewer); 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 ( return (
<div className={bare ? "" : "border-t border-zinc-800 pt-4"}> <div className={bare ? "" : "border-t border-zinc-800 pt-4"}>
<div className="flex items-baseline justify-between mb-2"> <div className="flex items-baseline justify-between mb-2">
@@ -106,14 +113,16 @@ export function OrderDetails({
<span className="block text-zinc-600">{it.options.join(" · ")}</span> <span className="block text-zinc-600">{it.options.join(" · ")}</span>
)} )}
</span> </span>
<ItemVerdictToggle {rateable && (
transactionId={transactionId} <ItemVerdictToggle
reviewer={reviewer} transactionId={transactionId}
item={it.description} reviewer={reviewer}
current={mine?.item_verdicts ?? []} item={it.description}
rating={mine?.rating ?? null} current={mine?.item_verdicts ?? []}
note={mine?.note ?? null} rating={mine?.rating ?? null}
/> note={mine?.note ?? null}
/>
)}
{/* Spine-bridged receipts (Amazon shipment notices, eBay) often {/* Spine-bridged receipts (Amazon shipment notices, eBay) often
name the goods without per-item prices — a null here is "the name the goods without per-item prices — a null here is "the
mail didn't say", and printing $0.00 would assert it did. */} mail didn't say", and printing $0.00 would assert it did. */}
@@ -152,11 +161,13 @@ export function OrderDetails({
</p> </p>
)} )}
<OrderVerdict {rateable && (
transactionId={transactionId} <OrderVerdict
reviewer={reviewer} transactionId={transactionId}
onReviewerChange={setReviewer} reviewer={reviewer}
/> onReviewerChange={setReviewer}
/>
)}
</div> </div>
); );
} }
+3 -1
View File
@@ -257,7 +257,9 @@ export function useTransactionSplits(transactionId: number) {
} }
export interface OrderReceipt { 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; order_reference: string | null;
line_items: { qty: number; description: string; amount: number; options?: string[] }[]; line_items: { qty: number; description: string; amount: number; options?: string[] }[];
route: { label: string; time: string | null; address: string }[]; route: { label: string; time: string | null; address: string }[];