---
id: ADR-COM-ORD-016
title: One route set serves portal and console; the caller decides authority
product_area: commerce
module: orders
revision: 1
status: proposed
design_intent: proposed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
decision: >-
  Share portal-capable operations with console callers, checking linked-contact authority in services and
  reserving administrative interventions for console access.
constrains:
  - SVC-COM-ORD-checkout
  - SVC-COM-ORD-orders
  - SVC-COM-ORD-entitlements
  - DOM-COM-ORD-001
  - DOM-COM-ORD-002
  - DOM-COM-ORD-004
  - RESP-COM
origin: >-
  services-commerce:docs/milestones/plans/COMM-M2-plan.md#9. Acceptance scenarios (permissions and isolation);
  COMM-M2 M2-S2 (Rhythm support identity)
alternatives:
  - option: Duplicate purchase APIs by caller surface
    why_not: Separate copies of the same purchase operation create avoidable behavioral drift.
consequences:
  - >-
    Requests require service context and operation authority, with workspace isolation preventing
    cross-customer reads.
  - Support activity retains its own actor attribution.
  - Portal selling is held while backend authority remains testable.
supersedes: []
evidence:
  - >-
    services-commerce at c8b66a98: route declarations; modules/checkout/services/checkout/checkout-actor.ts;
    tests/e2e/checkout-security.e2e.spec.js.
---

# One route set serves portal and console; the caller decides authority

## Context

Staff and buyers use many of the same purchase actions with different authority.

## Decision

Retain shared portal-capable routes, with service-level party restrictions for buyers and console-only intervention boundaries.

## Alternatives Considered

Duplicating route sets creates another place for equivalent purchase logic to drift.

## Consequences

Service tests must prove party authority and workspace isolation for each operation. Portal storefront scope is held even though backend routes exist.
