Skip to content

feat(merchant): orders inbox rebuild, home dashboard, and first-class order flows - #175

Merged
ericfj2140 merged 45 commits into
mainfrom
feat/merchant-orders-status
Jul 13, 2026
Merged

ericfj2140 merged 45 commits into
mainfrom
feat/merchant-orders-status

Conversation

@d3vv3

@d3vv3 d3vv3 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Preview Settings

  • Show commit-level mainnet preview links (Cloudflare creates deployments automatically)

Summary

Rebuilds the Merchant orders inbox and dashboard around one shared order-state model, keeps buyer and merchant order roles separated, and makes prepaid and invoice-first flows explicit.

This iteration also finishes the merchant fulfillment path:

  • buyer payment reports/proofs go to verification rather than silently becoming paid
  • merchant-confirmed payment implies acceptance and moves directly to fulfillment
  • paid orders no longer offer ordinary invoices
  • physical and mixed orders require a tracking code plus carrier before one shipment action advances the lifecycle to shipped
  • digital-only orders skip shipment and proceed to delivery confirmation only after every item resolves to a merchant-authored digital listing
  • shipped orders expose a contextual completion action
  • progress rows use state-aware wording: completed rows describe what happened, the active row names the task and prompts the next step, and waiting rows explain the next gate
  • Merchant actions put the recommended next step first and move cancellation into a destructive Other actions section
  • terminal cancellation/refund states stop the progress timeline instead of leaving phantom fulfillment steps
  • evidence-bearing cancellations warn about possible settlement, destructive confirmations preserve decline/cancel intent, and order publications share a concurrency lock
  • accepted guest orders can request payment out of band and explicitly record verified settlement to the merchant self-copy
  • unknown partial reads remain distinct from explicit guests and cannot use the guest-only manual payment shortcut
  • guest operations use out-of-band contact plus encrypted merchant self-copy records, never a fictional guest inbox

The Open Markets kind 16/17 collision is intentionally not changed here. The future migration is tracked in CND-191 and gated on OpenMarketsFoundation/specification#12.

Tracking

  • Tracker: CND-191 for the future private-commerce kind migration
  • Workstream: P3 — Commerce Completeness
  • Planning context checked: yes

Contract Changes

  • Source contracts:
    • docs/specs/order-lifecycle.md
    • docs/specs/merchant.md
  • Contract delta:
    • settlement, decision, fulfillment, and communication are distinct operational axes
    • confirmed payment implies accepted; reported/proof payment remains verify-first
    • paid orders choose fulfill or cancel/manual refund, not another ordinary invoice
    • shipment requires non-empty tracking-code and carrier values; URL and notes remain optional
    • checkout snapshots each item's physical/digital format for durable buyer history
    • timeline copy is state-aware and merchant-directed; active labels cannot reuse completed wording
    • actions present the recommended next step before destructive alternatives
    • cancelled/refund-requested timelines stop at the terminal row
    • non-replyable accepted orders can record verified out-of-band payment before fulfillment
    • orderless partial reads preserve unknown communication state until buyer identity is recovered
    • Merchant skips shipment only when the order snapshot and fully resolved merchant-authored listings both say every item is digital; either source may preserve a physical requirement
    • guest fulfillment is recorded by merchant self-copy
    • useful work queues are Paid—fulfill, Payment reported—verify, Unpaid—review, Shipped, Closed
  • Workflow policy:
    • required contract changes may land with implementation in the same PR
    • reviewers block missing/mismatched contracts, not the absence of a pre-merged spec branch
    • separate decision/docs-only PRs remain appropriate for broad architecture or external consensus
  • External source:
    • GammaMarkets market spec product type format and digital-products-skip-shipping behavior
  • External decision:
    • Open Markets private structured commerce kind proposal remains separate and is not implemented in this PR

Implementation Changes

Merchant orders

  • Rebuilt the inbox on the Market orders layout with desktop rail, mobile scroller/sheet, item-aware search, prepared status pills, and contextual actions.
  • Replaced coarse phase filters with operational work queues.
  • Removed the raw invoice/status/shipping manual console.
  • Suppresses invoice controls after payment evidence/confirmation and enforces the same capability inside mutations.
  • Confirmed payment goes straight to fulfillment; shipping_update itself projects to shipped.
  • Requires tracking code and carrier through native form constraints and the publish mutation; tracking URL and additional notes stay optional.
  • Requires agreement between the order snapshot and authenticated merchant's signed product listings before allowing the digital-only shortcut; either physical signal preserves shipment.
  • Adds contextual completion after shipment, direct delivery confirmation for verified digital-only orders, and sticky terminal-state projection.
  • Rewrites progress labels and hints for completed, active, and waiting states, including Shipping in progress with a tracking-details prompt.
  • Replaces the generic Respond group with a Next step section and moves cancellation to a red Other actions section after the primary workflow.
  • Adds payment-risk cancellation copy, intent-specific decline/cancel confirmations, shared mutation locking, and accessible alertdialog semantics.
  • Gives accepted guest orders an out-of-band request-payment prompt plus a confirmation-gated self-copy settlement action.
  • Shows guest/unknown order history read-only while hiding the reply composer.
  • Sanitizes inbound tracking links to HTTP(S) before rendering.

Shared order behavior

  • Added discriminated merchant domain actions for accept, confirm payment, record shipment, complete, and cancel.
  • Added explicit external-payment-report and shipment projection signals.
  • Preserves item fulfillment format through checkout pricing, order payload parsing, lifecycle persistence, summaries, and buyer timelines.
  • Centralized merchant NIP-17 publication in @conduit/core.
  • Delivery mode is required: signed-in orders publish buyer + self; guest/unknown operations publish critical merchant self-copy only while preserving the order-linked inner p tag.
  • Preserves current legacy kind 16 encoding and reads in this iteration.

Existing PR scope retained

  • Merchant dashboard analytics and latest buyer activity.
  • Buyer/merchant conversation role separation.
  • Market order view-model and floating order messaging.
  • Shared order cards, timeline, message widget, and status presentation.
  • Snapshot-aware fixed-shipping cart readiness.

PR Checks

  • Conventional Commit PR title
  • Contract changes are included in this PR and match the implementation
  • External signer-only auth and non-custodial payment boundaries preserved
  • NIP-17/NIP-59 and NIP-44 v2 behavior preserved
  • Protocol construction moved behind @conduit/core
  • Diagnostics and telemetry remain content-free

Validation

  • bun run typecheck
  • bun run lint
  • bun test — 847 pass, 1 skip
  • bun run build
  • bun run telemetry:check
  • Focused fulfillment suite covers required shipping values, physical/digital snapshots, merchant-authored digital verification, mixed/unresolved fallback, digital timeline omission, proof vs external report, paid-implies-accepted, queue precedence, shipment/completion, sticky terminal states, guest self-copy recipients, and unsafe tracking URLs
  • Timeline and Merchant behavior tests cover active/completed/waiting/terminal copy, action prioritization, refund-risk copy, decline intent, guest settlement, and concurrent publication rejection
  • React Doctor scoped to 60b3686 versus 3ae9dd1 reports no new warnings
  • Remote CI and Sudden Agent review for 60b3686

Runtime / Visual Evidence

  • Production builds complete for Core, UI, Market, Merchant, and Store Builder.
  • Earlier signed-in Merchant preview validation confirmed the work queues, guest verify-first state, self-copy-only guest copy, read-only guest history, shipment projection, and invoice suppression.
  • Merchant and Market previews deployed successfully for 60b3686; the prior signed-in e240819 preview confirmed the paid physical hierarchy and copy, while the later commits harden edge states and confirmation behavior.
  • Existing third-party bundle warnings remain: tseep direct eval and large Market/Merchant chunks.
  • The broader PR React Doctor scan retains pre-existing Merchant route maintainability warnings; the exact latest-commit scope adds none.

Risks and Follow-ups

  • Do not merge until human review.
  • Refund payment remains manual/out-of-band; cancellation records status but does not move funds.
  • Guest contact remains out of band; merchant self-copy proves only the recorded operation, not buyer notification.
  • Buyer-supplied fulfillment snapshots do not authorize Merchant to skip shipment, but a physical snapshot does preserve the historical shipping gate; unresolved merchant listings conservatively keep the shipping path.
  • Product format is resolved from the current merchant-authored listing because the existing order reference does not pin a historical product event revision.
  • The Open Markets kind migration requires dual-read/deduplication rollout and is separately tracked in CND-191.
  • Merchant/Market order route size and duplicated buyer-side publish paths remain refactor candidates outside this fulfillment slice.

Contract Review

Reviewer decision:

  • Contract updated in this PR and matches implementation
  • No contract change needed
  • Separate decision/docs-only PR required

Review Focus

  • Merchant-authored digital fulfillment gate in apps/merchant/src/lib/order-phase.ts and apps/merchant/src/routes/orders.tsx
  • Required shipping payload preparation in apps/merchant/src/lib/shipping-update.ts
  • Domain actions and paid-implies-accepted behavior in packages/core/src/protocol/order-status.ts
  • Item format snapshot propagation through checkout, schema, lifecycle, summary, and buyer view-model
  • Required delivery policy in packages/core/src/protocol/merchant-order-publish.ts
  • Guest read-only history and contextual actions in apps/merchant/src/routes/orders.tsx
  • State-aware progress copy in packages/core/src/protocol/order-status.ts
  • Primary-first and destructive-last action hierarchy in apps/merchant/src/routes/orders.tsx
  • Same-PR contract gate wording in repo instructions and PR review guidance

d3vv3 added 24 commits July 8, 2026 21:26
…pers

Reframe the merchant orders page around order status, matching Market /orders:
- Left panel labelled Orders (was Conversations).
- Selected order uses a subtle orange tint from the shared secondary token
  (bg-secondary-500/10 + border-secondary-500/40).
- Each row shows a StatusPill; the selected order detail shows a StatusStepper of
  the order lifecycle -- the same shared UI the Market uses. Steps carry
  subtitles so the stepper's connector line renders (it is a flex-1 bar that
  needs row height, which title-only rows collapsed).

Shared logic: new @conduit/core order-status module (getOrderStatusDisplay,
buildOrderStatusTimeline) maps an order status string to pill tone + stepper
rows for both apps. Market's buildOrderTimeline/deriveOrderHeaderStatus stay
app-local -- they need the buyer-side OrderViewModel the merchant lacks -- so
only the status-keyed presentation is shared. Core exposes structurally
StatusStepperRow-compatible types to avoid a @conduit/ui dependency. Unit-tested.
…ges)

Selected order card layout:
- StatusStepper is a fixed header, always visible regardless of the active tab.
- Details/Actions use the market's segmented pill selector (restyled Radix
  TabsList/TabsTrigger: rounded-full, self-start so it sizes to its options
  rather than stretching the flex column), matching the /products source control.
- Messages is a bottom-right icon button that sets the controlled active tab.

Order-row status: pill is shrink-0 and the order id is min-w-0/break-all so the
StatusPill no longer clips when the id is long.
…ut shift

Add smart action buttons right of the Details/Actions selector, driven by a
shared core helper getMerchantOrderActions(status):
- pending/paid: Decline order (destructive, left) + Accept order (primary)
- accepted:     Cancel order (destructive, left) + Mark as shipped (primary)
- shipped/delivered/terminal: none (buyer confirms delivery)
Each publishes the mapped status via a param-based advanceStatusMutation and
refetches; the clicked button shows a sending state.

Also remove the standalone 'Checking latest order messages…' block: it inserted/
removed a flow element on every poll, displacing the list below it. Refresh state
is already conveyed by the refresh button (Refreshing…/Updated).

Core helper unit-tested.
Order items rendered the raw product id (30402:pubkey:d) with no image. Resolve
each item against the merchant's own listings (getMerchantStorefront, keyed by
address/id) to fill name + thumbnail, and show a 40px image, name, quantity, and
unit price per line plus the subtotal. OrderDetailCard gains an optional imageUrl
and drops the product-id hash line (falls back to 'Product' if a title is
missing). Order messages carry no image, so the merchant catalog is the source.
- port market orders layout: hero, two-column grid, order-progress
  stepper, items/shipping/order-details cards, and list-card styling
- add order search box, market-parity list spacing, and mobile
  horizontal scroller + search sheet
- resolve order-item name/image via a single batched product read
  (getProductsByIds) instead of per-item fanouts
- share the order message bubble via @conduit/ui OrderConversationMessage
  (used by market messages + merchant), drop app-local copies
- merge actions/messages under a segmented toggle; centered inline
  reply input with paper-plane send
- link buyer to their market storefront; fix order date (ms) rendering
- move buyer info to a bottom-right card (Message button only); move
  the smart status actions into the Actions card
- Actions: dropdown-selected single form (invoice/status/shipping),
  grouped under Respond + Manual action, drop nested form cards
- extract floating chat to @conduit/ui OrderMessagesWidget (shareable);
  full-screen on mobile, anchored card on desktop
- compact order-item bubbles (thumbnail + qty + price, no address hash)
  via resolveItem; drop verbose product-id line
- let the detail panel flow with the page (sticky list rail) instead of
  an independent scroll pane
Model payment and acceptance as two independent gates instead of a
linear status, so the zap-out (pay-first) and order-first (invoice)
flows are both first-class:

- order-status: add MerchantOrderState + deriveOrderFlow; timeline
  orders payment↔acceptance by flow; shipping is gated on payment;
  unify status vocabulary (invoiced/processing/complete) with
  forward-compat; string args still accepted
- merchant: derive {status, paid, invoiceSent} from the order summary
  and drive actions + timeline from it; warn that cancelling a paid
  order needs a manual (non-custodial) Lightning refund
- spec: document the two flows, the paid⟂accepted gates, and the
  refund-as-recorded-payout convention in order-lifecycle.md
- tests: flow ordering, payment-gated shipping, deriveOrderFlow
…ilter

- order-status: add orderFlowFromCheckoutMode (authoritative flow from
  the buyer's checkout mode) alongside deriveOrderFlow
- market order-view: expose `flow` on OrderViewModel and relabel the
  invoice timeline row as direct payment for prepaid (zap-out) orders
- merchant: add All/Pending/In Progress/Completed phase pills (map order
  status → phase; cancelled shows only under All) under the search box,
  in both the desktop list rail and the mobile search sheet
Order gift wraps are self-copied into the sender's inbox, so a pubkey
that both buys and sells received both sides. Gate each conversation
list by the `order` message direction (buyer = sender, merchant =
recipient):

- merchant list drops orders the principal placed as a buyer
- buyer list drops orders the principal received as the merchant
- also derive buyer/merchant pubkey from the order message

Plus item search over product name/description/tags via one batched
listing read across recent orders.
Reuse the shared OrderMessagesWidget on the buyer orders page so
messaging the merchant happens in a floating window (full-screen on
mobile) without navigating away. The reply publishes an order `message`
gift-wrapped to merchant + buyer self-copy and refreshes the buyer
conversation queries. Message-merchant and shipping "Edit" links now
open the widget.
…lter

Buyer phase tabs used vm.phase, which marks any *sent* order as
in_progress, so "waiting for invoice" never showed under Pending.
Add getOrderFilterPhase (unpaid → pending, paid/fulfilling →
in_progress) and filter on it. Show the phase pills under the search
box on the desktop rail too, and drop the now-obsolete desktop
tab-collapse.
- drop the bordered card around the mobile nav user menu (keep the
  network badge above it)
- match the market header: user-menu trigger uses bg-primary-500 /
  white text / hover:bg-primary-600 (applies to the sidebar too)
…st item

- extract BuyerAvatar + OrderListItem to components/OrderListItem and
  reuse in the orders route
- home page now lists recent orders from the merchant conversation list
  (buyer avatar, name, preview, total, status pill) with buyer profile
  hydration, instead of a plain text row — role-filtered and status-aware
Add four order-analytics charts derived from the merchant conversation
list (role-filtered), rendered as self-contained inline SVG using theme
tokens:

- Orders over time (hero): 30-day daily bar chart of order volume
- Order status: donut of pending/in-progress/completed/cancelled
- Revenue (paid): 30-day bars, amounts normalized to sats via btc/usd
- Top products: horizontal bars by ordered quantity

Extract a shared order-phase helper (used by orders + charts) and a pure
buildDashboardChartData aggregator with unit tests.
…oduct card

- add shared @conduit/ui DoubleSideStatusPill (primary-filled left half +
  faint primary-tint bordered right half)
- product card title-aside now shows the Active status pill and a
  DoubleSideStatusPill for the zap policy (e.g. "Public zap" / "generic")
- drop the separate safety row for active listings (info moved into card;
  the warning row stays for non-active listings)
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying conduit-market with  Cloudflare Pages  Cloudflare Pages

Latest commit: a7ccbf4
Status: ✅  Deploy successful!
Preview URL: https://bf066643.conduit-market-coo.pages.dev
Branch Preview URL: https://feat-merchant-orders-status.conduit-market-coo.pages.dev

View logs

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying conduit-merchant with  Cloudflare Pages  Cloudflare Pages

Latest commit: a7ccbf4
Status: ✅  Deploy successful!
Preview URL: https://9608d4a1.conduit-merchant-33n.pages.dev
Branch Preview URL: https://feat-merchant-orders-status.conduit-merchant-33n.pages.dev

View logs

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Preview Deploys

Mainnet Branch URLs

App URL
Market https://feat-merchant-orders-status.conduit-market-coo.pages.dev
Merchant https://feat-merchant-orders-status.conduit-merchant-33n.pages.dev

Commit-level preview links are hidden by PR setting (- [ ] Show commit-level mainnet preview links (Cloudflare creates deployments automatically)).

Mainnet preview links for latest commit a7ccbf4

@conduit-sudden-agent conduit-sudden-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 [packages/core/src/protocol/commerce.ts:2269, 2342]: the new role gate still lets a bucket through when the initial order message is missing. Both the live inbox read and the cached helpers are explicitly partial/limited, so older order wraps can fall out while later status/proof messages remain. In that case a dual-role pubkey will see the conversation in both buyer and merchant views again, which reintroduces the mixup this PR is trying to eliminate.

P1 [apps/market/src/lib/order-view.ts:276]: Merchant can now emit accepted, but Market still drops that status before it reaches the buyer view-model. For invoice-first orders, acceptance regresses to merchantStatus = null, so the buyer header/timeline/filtering never reflect the acceptance gate.

P2 [packages/ui/package.json:18]: @conduit/ui now depends on @conduit/core, which conflicts with the documented shared-package boundary in AGENTS.md and docs/ARCHITECTURE.md. If this inversion is intentional, the repo contract should be updated first; otherwise the protocol helpers/types need to stay out of @conduit/ui.

Comment thread packages/core/src/protocol/commerce.ts Outdated
Comment thread packages/core/src/protocol/commerce.ts Outdated
Comment thread apps/market/src/lib/order-view.ts Outdated
Comment thread packages/ui/package.json
Comment thread apps/merchant/src/routes/orders.tsx Outdated
Comment thread apps/merchant/src/lib/order-phase.ts Outdated
Comment thread apps/merchant/src/routes/orders.tsx Outdated
Comment thread apps/market/src/lib/order-view.ts Outdated
Comment thread apps/market/src/lib/order-view.ts Outdated
Comment thread apps/merchant/src/routes/orders.tsx Outdated
Eric FJ added 2 commits July 12, 2026 13:20
Require non-empty tracking and carrier values at the form and publish boundary. Preserve item fulfillment format, skip shipment only for merchant-verified digital-only orders, and keep unresolved or mixed orders on the physical fulfillment path.\n\nValidated with typecheck, lint, telemetry policy, 838 passing tests, and production builds.
Comment thread apps/merchant/src/lib/order-phase.ts
Eric FJ added 3 commits July 12, 2026 14:51
Require both the order snapshot and current merchant listing to be digital before skipping shipment. A physical snapshot remains authoritative for preserving fulfillment on historical orders.\n\nValidated with focused fulfillment tests, full test suite, typecheck, lint, and telemetry policy.
Make fulfillment timeline copy reflect completed, active, and waiting states. Present the recommended next action before destructive alternatives and cover the hierarchy with regression tests.

Validation: bun run typecheck; bun run lint; bun run telemetry:check; bun test; bun run build
Keep terminal and payment-evidence timelines aligned with available actions, guard concurrent order publications, and preserve guest out-of-band payment confirmation. Add accessible confirmation semantics and behavior-level state coverage.

Validation: bun run typecheck; bun run lint; bun run telemetry:check; bun test; bun run build; React Doctor exact delta
Comment thread apps/merchant/src/routes/orders.tsx Outdated
Eric FJ added 2 commits July 12, 2026 16:08
Keep orderless partial reads distinct from known out-of-band guests so only explicit guest orders can record manual payment confirmation.

Validation: focused order/action/phase tests; typecheck; lint; telemetry policy

@ericfj2140 ericfj2140 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the hardening work from 110a4b6 through the current PR head, a7ccbf4. This is now in a merge-ready state from my side.

The biggest change is that order handling no longer treats payment, acceptance, fulfillment, and communication as one unreliable linear status. Buyer payment reports and proofs remain evidence that the merchant must verify; merchant-confirmed settlement implies acceptance and moves the order directly into fulfillment. This removes the redundant accept step for paid orders, suppresses ordinary invoice actions after payment, and gives the Merchant inbox operational queues for paid fulfillment, payment verification, unpaid review, shipped, and closed orders.

Partial relay/cache histories were hardened throughout the stack. Buyer and merchant roles are recovered from fixed message direction when enough evidence survives, while ambiguous histories remain conservative. Participant hints now preserve payment evidence and merchant state consistently across the list, selected-order pane, dashboard charts, status pills, filters, and buyer timeline. Buyer-side paid projection also remains consistent when only a merchant status survives a partial read, without incorrectly inferring a prepaid flow.

Fulfillment was completed as a real workflow rather than a manual status console. Physical shipments require both a non-empty tracking code and carrier at the form and mutation boundaries; tracking URL and notes remain optional, and rendered tracking links are restricted to HTTP(S). One shipping update advances the order to shipped, and shipped orders expose delivery completion. Digital-only orders skip shipment only when both the durable order snapshot and resolved merchant-authored listings agree every item is digital. Physical, mixed, unresolved, deleted, and legacy listings conservatively retain the shipping gate, and historical shipping events backfill the earlier paid/accepted gates.

Guest handling now matches the actual communication boundary. Explicit guests use phone/email out of band while Merchant records decisions, settlement confirmation, shipping, and completion as encrypted self-copies. Their order history is readable without presenting a fictional reply composer. Orderless partial histories remain a distinct unknown state and cannot use the guest-only manual payment shortcut. Legacy signed-in orders without the newer identity marker still retain buyer-and-self delivery.

The Merchant progress and action UI was reorganized around the next decision. Completed, active, and waiting timeline rows now use state-appropriate language; active shipping reads “Shipping in progress” and explains how to advance it. Cancelled and refund-requested timelines stop at the terminal state. The recommended next step appears first, with cancellation moved into a destructive “Other actions” section and explicit paid/payment-evidence refund warnings. Destructive actions use confirmation dialogs with alert-dialog semantics, publication actions share an exclusive lock, and success/error feedback uses live status/alert semantics. The horizontally scrolling queue pills were also replaced with the shared accessible dropdown in both the desktop rail and mobile orders sheet.

Protocol construction for Merchant order actions was moved behind @conduit/core. The shared publisher makes buyer-and-self versus self-only delivery explicit while preserving the order-linked inner p tag, NIP-17/NIP-59 wrapping, and the current kind-16 encoding. The known kind collision is intentionally not partially migrated here; that remains tracked behind OpenMarketsFoundation/specification#12 and CND-191.

The repo contracts were updated in the same PR to match the implemented settlement, decision, fulfillment, communication, shipment, digital-order, and guest-order behavior. The contribution/review workflow now allows required contract updates to land with implementation and reserves separate decision PRs for broad architecture or external consensus.

The review feedback was handled comprehensively: partial role separation, accepted-status propagation, the documented UI-to-Core package edge, snapshot-aware shipping readiness, proof-only queue/dashboard consistency, selected-pane participant hints, buyer paid projection, conservative flow inference, legacy buyer delivery, historical physical fulfillment, and the guest/unknown communication distinction are all covered. All 13 Sudden Agent threads are resolved, and the latest Agent review is green.

Validation is green at the current head: 847 tests pass with 1 skip, and CI passes format, lint, typecheck, telemetry and color policies, E2E smoke, mainnet build, dependency/security scans, both preview deployments, and Agent review. The final dropdown commit has green CI and deployed previews but did not receive a fresh signed-in visual pass; because both layouts use the same shared accessible control and the earlier signed-in preview covered the surrounding fulfillment hierarchy, I consider that a low-risk visual spot-check item rather than a merge blocker.

Remaining limitations are understood and are not blockers for this PR: refunds are still manual/out of band; guest self-copies record Merchant intent but do not prove buyer notification; product revisions are not historically pinned; the private-commerce kind migration remains separate; and the large Merchant/Market order routes remain future refactor candidates.

Approved.

@ericfj2140
ericfj2140 merged commit 0fa2248 into main Jul 13, 2026
17 checks passed
@ericfj2140
ericfj2140 deleted the feat/merchant-orders-status branch July 13, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants