UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

195 lines (149 loc) • 4.96 kB
--- name: decide-app-specific-overrides-vs-shared-platform description: > Load this skill when deciding whether storefront-specific wrappers, DTOs, address adapters, or backend behavior should stay in the app or move into @techsio/storefront-data. Use it for thin wrapper rules, customer-specific read models, and deciding when repeated backend logic becomes shared platform behavior. type: composition library: "@techsio/storefront-data" library_version: "0.1.0" sources: - "TechsioCZ/new-engine:libs/storefront-data/README.md" - "TechsioCZ/new-engine:libs/storefront-data/AGENTS.md" - "TechsioCZ/new-engine:libs/storefront-data/src/shared/address.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/checkout/address.ts" - "TechsioCZ/new-engine:libs/storefront-data/src/auth/hooks.ts" --- # Decide app-specific overrides vs shared platform ## Setup Default to the shared preset surface. Add a local wrapper only when the app contributes real policy or UX behavior. ```ts // src/lib/auth-hooks.ts import { storefront } from "@/src/lib/storefront" import { toast } from "sonner" export function useLoginWithToast() { return storefront.hooks.auth.useLogin({ onSuccess: () => { toast.success("Logged in") }, }) } ``` ## Core Patterns ### Keep customer-specific DTOs and read models in the app ```ts // apps/n1/src/lib/customer-models.ts export type N1ProfileCard = { email: string loyaltyTier: string } ``` The shared package should own reusable backend-facing contracts. A storefront-local view model stays local until another storefront needs the same shape. ### Keep address customization behind the shared contract ```ts // apps/n1/src/lib/address-adapter.ts import type { CheckoutCartAddressAdapter } from "@techsio/storefront-data/shared/address" export const checkoutCartAddressAdapter: CheckoutCartAddressAdapter<FormValues> = { toCreateInput(values) { return { first_name: values.firstName, last_name: values.lastName, address_1: values.street, city: values.city, country_code: values.countryCode, postal_code: values.postalCode, } }, toPatchInput(values) { return { first_name: values.firstName, last_name: values.lastName, address_1: values.street, city: values.city, country_code: values.countryCode, postal_code: values.postalCode, } }, } ``` ### Promote repeated backend behavior into the shared package ```ts // apps/n1/src/lib/checkout.ts export function useCheckoutWithSharedPaymentRule(cartId: string, regionId: string) { return storefront.flows.checkout.useCompleteCheckout({ cartId, regionId, }) } ``` If another storefront needs the same backend-facing rule, move that rule into `libs/storefront-data` so the next bugfix lands once. ## Common Mistakes ### HIGH Wrappers with no added behavior Wrong: ```ts export const useProducts = (params: ProductParams) => storefront.hooks.products.useProducts(params) ``` Correct: ```ts export const useProducts = storefront.hooks.products.useProducts ``` A wrapper that adds no policy, translation, or side effect only obscures the preset surface. Source: maintainer interview ### HIGH Customer-specific read models inside the shared package Wrong: ```ts // libs/storefront-data/src/customers/types.ts export type N1ProfileCard = { loyaltyTier: string } ``` Correct: ```ts // apps/n1/src/lib/customer-models.ts export type N1ProfileCard = { loyaltyTier: string } ``` The shared package owns reusable backend-facing contracts. A storefront-local read model belongs to the storefront until reuse is proven. Source: `libs/storefront-data/README.md`, maintainer interview ### HIGH Repeated backend behavior left inside one app Wrong: ```ts // apps/n1/src/lib/cart-hooks.ts export function useSharedCartSemantics() { return useMutation({ mutationFn: customCartMutation }) } ``` Correct: ```ts // libs/storefront-data/src/... shared seam consumed from the preset export const storefront = createMedusaStorefrontPreset({ sdk }) ``` If checkout, cart, or product backend behavior is shared by most storefronts, it belongs in the library so bugfixes propagate once. Source: maintainer interview, `libs/storefront-data/AGENTS.md`, `libs/storefront-data/README.md` ### HIGH UI dependencies leaked into shared platform code Wrong: ```ts createMedusaStorefrontPreset({ sdk, auth: { hooks: { onSuccess: () => toast.success("Logged in"), }, }, }) ``` Correct: ```ts function useLoginWithToast() { return storefront.hooks.auth.useLogin({ onSuccess: () => toast.success("Logged in"), }) } ``` Storefront-specific UI dependencies belong in the app layer, even when the backend flow itself stays shared. Source: `libs/storefront-data/src/auth/hooks.ts`, maintainer interview See also: `extend-storefront-data-for-new-backend-use-cases` when the behavior is no longer truly storefront-specific.