shopify_draft_proxy/proxy/discounts

Discount-domain read and mutation staging.

This module ports the discount owner-node surface with a deliberately flexible normalized record: the store tracks id/type/status/code fields for local lifecycle behavior and keeps a captured/projectable owner-node payload for Shopify-like field projection.

Types

pub type DiscountsError {
  ParseFailed(root_field.RootFieldError)
}

Constructors

pub type MutationOutcome {
  MutationOutcome(
    data: json.Json,
    store: store.Store,
    identity: synthetic_identity.SyntheticIdentityRegistry,
    staged_resource_ids: List(String),
    log_drafts: List(mutation_helpers.LogDraft),
  )
}

Constructors

Values

pub fn handle_discount_query(
  store: store.Store,
  document: String,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> Result(json.Json, DiscountsError)
pub fn handle_query_request(
  proxy: proxy_state.DraftProxy,
  request: proxy_state.Request,
  parsed: parse_operation.ParsedOperation,
  primary_root_field: String,
  document: String,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> #(proxy_state.Response, proxy_state.DraftProxy)

Domain entrypoint for the discount query path. The dispatcher always lands here for discount-domain reads regardless of read_mode; the handler itself decides whether to compute the answer from local state or to forward to upstream verbatim via passthrough.passthrough_sync (when in LiveHybrid mode and the operation is one we know we can’t satisfy locally — see should_passthrough_in_live_hybrid).

pub fn is_discount_mutation_root(name: String) -> Bool
pub fn is_discount_query_root(name: String) -> Bool
pub fn local_has_discount_id(
  proxy: proxy_state.DraftProxy,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> Bool

True iff any string-typed variable value in the request resolves to a discount that’s already in local state, or is a proxy-synthetic gid. The dispatcher uses this to skip LiveHybrid passthrough so that read-after-create reads of a synthetic id stay local (and so that read-after-delete reads of a synthetic id correctly return null instead of forwarding a synthetic gid upstream where it would 404).

We scan every string variable value rather than keying on "id" because GraphQL operations frequently rebind the argument under a different variable name (e.g. discountNode(id: $codeId)).

pub fn local_has_staged_discounts(
  proxy: proxy_state.DraftProxy,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> Bool

True iff the local store has any staged discount records, or any variable carries a proxy-synthetic gid. The dispatcher uses this to keep aggregate / connection / by-code reads on the local handler once a lifecycle scenario has staged or deleted discounts — passthrough would otherwise forward synthetic gids upstream (404) or skip the empty/null answer the lifecycle test expects after a delete.

pub fn process(
  store: store.Store,
  document: String,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> Result(json.Json, DiscountsError)
pub fn process_mutation(
  store: store.Store,
  identity: synthetic_identity.SyntheticIdentityRegistry,
  request_path: String,
  document: String,
  variables: dict.Dict(String, root_field.ResolvedValue),
) -> Result(MutationOutcome, DiscountsError)
pub fn process_mutation_with_upstream(
  store: store.Store,
  identity: synthetic_identity.SyntheticIdentityRegistry,
  request_path: String,
  document: String,
  variables: dict.Dict(String, root_field.ResolvedValue),
  upstream: upstream_query.UpstreamContext,
) -> Result(MutationOutcome, DiscountsError)

Variant of process_mutation that threads an UpstreamContext into the per-handler logic. Used by the dispatcher when the proxy has an upstream_transport installed (parity cassette in tests, live HTTP in production), so that handlers like discountCodeBasicCreate can consult upstream for cross-discount uniqueness checks before staging.

Search Document