Canvas (archive de conception)Tools Shopify à wrapper (knowledge layer @Atlas)

Outils Shopify à encapsuler (couche de connaissance @Atlas)

Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.

Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.

← retour au README


6. Outils Shopify à encapsuler (couche de connaissance @Atlas)

Cible : @Atlas ne dit jamais « je ne sais pas ». Utiliser exclusivement la GraphQL Admin API 2025-10.

Philosophie de permissions : non-négociable

Aucune limite interne côté BoostEcom. La frontière d'@Atlas = les scopes accordés par l'utilisateur via sa custom app Shopify, et rien d'autre.

Concrètement :

  • BoostEcom n'ajoute aucun filtrage au-dessus de Shopify. Si l'utilisateur a accordé read_customers, @Atlas lit les clients. Si l'utilisateur a accordé les 68+ scopes d'une custom app, @Atlas exploite les 68+.
  • Pas de feature flag interne « agents.canReadOrders = false » : la réponse à « puis-je faire X ? » est toujours « oui, si Shopify accepte le token ».
  • Côté outils : chaque outil doit tenter l'appel GraphQL et propager l'erreur Shopify telle quelle si le scope est insuffisant (ses userErrors, ou un 403 : il n'existe pas de type d'erreur maison). L'erreur sert de signal à @Atlas, qui peut alors guider l'utilisateur vers le skill shopify-app-custom pour étendre les scopes : pas un blocage silencieux.
  • Pour les boutiques connectées par OAuth via une app publique (≠ custom app), le même principe s'applique avec les scopes négociés à l'installation ; si un scope manque, @Atlas propose d'élargir, ne ferme jamais la porte.

Référence interne : skill shopify-app-custom (catalogue exhaustif des scopes et reproduction de l'accès admin/partner). La couche de connaissance d'@Atlas est un relais transparent vers ce que la custom app permet.

Implémentation :

  • Pas d'encapsulation conditionnelle if (hasScope(...)) { ... } dans nos outils : on appelle Shopify, on gère l'erreur dans le repli.
  • Schémas zod des outils = stricts sur les entrées/sorties, jamais sur les permissions.
  • Documentation : chaque outil note les scopes Shopify nécessaires comme information (pour le débogage), pas comme barrière.

Lot d'encapsulation (Lot 1 du plan d'exécution)

DomaineEndpoints GraphQLScope
Catalogueproducts, product(id), productVariants, inventoryLevels, collections, collection(id)read_products, read_inventory
Pages de contenupages, page(id)read_content
Blogs / Articlesblogs, blog(id), articles, article(id)read_content
Navigationmenus, menu(id) (linkLists via REST s'il manque)read_content
Thèmethemes, theme(id), themeFiles(themeId), mutations CRUDread_themes, write_themes
AppscurrentAppInstallation, abonnements d'appscope automatique
Réglagesshop, shopLocales, shopBillingPreferences, shippingZonesread_locales, read_shipping
Clients (soumis à scope)customers, customer(id), customerSegmentsread_customers
Commandes (soumis à scope)orders, order(id), draftOrdersread_orders, read_draft_orders
MarketingdiscountCodes, priceRules, marketingActivities, abandonedCheckoutsread_discounts, read_marketing_events
Analytics (limité)shopifyAnalytics (basique) : préférer la Storefront API ou un rapport Shopify CLIread_reports
Storefrontpixels de tracking, données structurées, robots, sitemap (lecture du HTML via fetch)aucun (public)

Pattern d'encapsulation

server.tool(
  "shopify_list_pages",
  "List all CMS pages of the store, with title, handle, body summary.",
  { first: z.number().min(1).max(50).optional() },
  async ({ first = 50 }, ctx) => {
    const data = await ctx.shopify.graphql(LIST_PAGES_QUERY, { first })
    return text(formatPagesList(data.pages))
  },
)

→ ~30 nouveaux outils à encapsuler. Bloc 1 = 1 lot dédié.


Suivant : execution-plan.md