Skip to main content

GraphQL schema

Defined in etc/schema.graphqls. All resolvers go through Byte8\StockRadar\Model\SubscriptionService — the same Service layer the Luma controller uses, so validation and side-effects stay in one place.

Schema

type Mutation {
byte8StockRadarSubscribe(input: Byte8StockRadarSubscribeInput!): Byte8StockRadarSubscribeOutput
byte8StockRadarUnsubscribe(token: String!): Byte8StockRadarUnsubscribeOutput
}

type Query {
byte8StockRadarMySubscriptions: Byte8StockRadarSubscriptionList
}

input Byte8StockRadarSubscribeInput {
sku: String!
email: String!
}

type Byte8StockRadarSubscribeOutput {
success: Boolean!
created: Boolean!
message: String!
}

type Byte8StockRadarUnsubscribeOutput {
success: Boolean!
message: String!
}

type Byte8StockRadarSubscriptionList {
items: [Byte8StockRadarSubscription!]!
total_count: Int!
}

type Byte8StockRadarSubscription {
sku: String!
product_name: String
product_url: String
status: String!
created_at: String!
notified_at: String
unsubscribe_token: String!
}

byte8StockRadarSubscribe

ArgumentTypeNotes
input.skuString!For configurables, pass the simple variant SKU. Subscribing to a parent SKU is allowed; the bridge resolves which simples to associate.
input.emailString!Validated server-side via Magento\Framework\Validator\EmailAddress.

Returns:

FieldNotes
successAlways true on a non-error response
createdtrue for first subscribe; false if the email already had a pending subscription for this product+store (idempotent)
messageHuman-readable confirmation, suitable for direct UI display

Errors:

ConditionError
Empty SKU or emailGraphQlInputException — "SKU and email are required."
Invalid email formatGraphQlInputException — "Please provide a valid email address."
Stock Radar disabled for the storeGraphQlInputException — "Stock notifications are not enabled for this store."
Simple product currently in stockGraphQlInputException — "This product is currently in stock."

byte8StockRadarUnsubscribe

ArgumentTypeNotes
tokenString!The 48-character unsubscribe token from the email link or the customer-account list

Returns:

FieldNotes
successAlways true — the response is identical whether the token matched or not. This is intentional: any difference in response would let an attacker enumerate which tokens (and thereby which subscriptions) exist.
messageAlways "You have been unsubscribed."

byte8StockRadarMySubscriptions

Requires customer authentication (Authorization: Bearer <token>).

Returns:

FieldNotes
items[].skuSubscribed product's SKU (simple SKU for variants)
items[].product_nameStorefront-display product name; null if product was deleted
items[].product_urlFull storefront URL; null if product was deleted
items[].statusOne of pending, notified, cancelled, bounced
items[].created_atISO 8601 timestamp
items[].notified_atISO 8601 timestamp; null if not yet sent
items[].unsubscribe_tokenFor use with byte8StockRadarUnsubscribe

Filtered to status IN ('pending', 'notified') — cancelled and bounced are not exposed (no value to the customer).

Errors:

ConditionError
Anonymous requestGraphQlAuthorizationException — "Customer authentication required."

Future extensions (non-breaking)

FieldStatus
byte8StockRadarMySubscriptions(filter: ...) — paging + status filterConsidered, deferred until customer ask
Byte8StockRadarSubscription.product { ... } — full Product object via existing GraphQL typeConsidered, deferred — current product_name + product_url covers 90% of UI needs
byte8StockRadarUnsubscribeAll — admin-only mutation for GDPR delete by emailPlanned