@thorprovider/storefront 0.3.1 → 0.4.0-mvp.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +321 -152
- package/VENDOR.md +69 -0
- package/assets/openspec/config.yaml +38 -0
- package/assets/templates/AGENTS.md +76 -0
- package/assets/templates/app/app/[[...slug]]/page.tsx +54 -2
- package/assets/templates/app/app/[[...slug]]/renderer.tsx +13 -2
- package/assets/templates/app/app/globals.css +5 -8
- package/assets/templates/app/app/layout.tsx +17 -7
- package/assets/templates/app/app/robots.ts +19 -0
- package/assets/templates/app/app/sitemap.ts +71 -0
- package/assets/templates/app/lib/__STOREFRONT__/actions.ts +612 -0
- package/assets/templates/app/lib/__STOREFRONT__/cart-state.ts +66 -0
- package/assets/templates/app/lib/__STOREFRONT__/catalog.ts +50 -57
- package/assets/templates/app/lib/__STOREFRONT__/commerce.ts +679 -0
- package/assets/templates/app/lib/__STOREFRONT__/composition.ts +26 -0
- package/assets/templates/app/lib/__STOREFRONT__/handlers.core.ts +197 -0
- package/assets/templates/app/lib/__STOREFRONT__/handlers.ts +5 -36
- package/assets/templates/app/lib/__STOREFRONT__/icon-map.ts +27 -0
- package/assets/templates/app/lib/__STOREFRONT__/mappers.ts +13 -11
- package/assets/templates/app/lib/__STOREFRONT__/registry.tsx +264 -51
- package/assets/templates/app/lib/__STOREFRONT__/runtime.ts +6 -3
- package/assets/templates/app/lib/__STOREFRONT__/schema.ts +136 -0
- package/assets/templates/app/lib/__STOREFRONT__/section-observation.ts +182 -0
- package/assets/templates/app/lib/__STOREFRONT__/section-sources.ts +130 -0
- package/assets/templates/app/lib/__STOREFRONT__/session.core.ts +470 -0
- package/assets/templates/app/lib/__STOREFRONT__/session.ts +169 -0
- package/assets/templates/app/lib/__STOREFRONT__/shell/content.ts +120 -0
- package/assets/templates/app/lib/__STOREFRONT__/shell/props.ts +38 -0
- package/assets/templates/app/lib/__STOREFRONT__/spec/index.ts +129 -10
- package/assets/templates/app/lib/__STOREFRONT__/spec/page-root.ts +5 -1
- package/assets/templates/app/lib/__STOREFRONT__/spec/seo.ts +191 -0
- package/assets/templates/app/lib/__STOREFRONT__/state.core.ts +257 -0
- package/assets/templates/app/lib/__STOREFRONT__/state.ts +7 -31
- package/assets/templates/app/lib/__STOREFRONT__/store-context.ts +161 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/cta.client.tsx +25 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/cta.tsx +16 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/faq.client.tsx +24 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/faq.tsx +5 -18
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/index.ts +18 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/logoCloud.tsx +26 -14
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/pricing.tsx +36 -18
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.client.tsx +100 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.tsx +19 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.cta.ts +19 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.faq.ts +18 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.products.ts +39 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/statistics.tsx +35 -14
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/testimonials.tsx +31 -13
- package/assets/templates/app/lib/__STOREFRONT__/views/types.ts +5 -3
- package/assets/templates/features/checkout/handlers.ts +159 -0
- package/assets/templates/features/checkout/state.ts +61 -0
- package/assets/templates/features/customer-auth/handlers.ts +59 -0
- package/assets/templates/features/customer-auth/state.ts +45 -0
- package/assets/templates/features/recommendations/state.ts +11 -0
- package/assets/templates/views/account/content.ts +35 -0
- package/assets/templates/views/account/index.tsx +114 -0
- package/assets/templates/views/account/registry.tsx +439 -0
- package/assets/templates/views/account/schema.ts +53 -0
- package/assets/templates/views/cart/content.ts +11 -0
- package/assets/templates/views/cart/data.ts +23 -0
- package/assets/templates/views/cart/index.tsx +53 -0
- package/assets/templates/views/cart/props.ts +12 -0
- package/assets/templates/views/cart/registry.tsx +81 -0
- package/assets/templates/views/cart/schema.ts +52 -0
- package/assets/templates/views/category/assembly/assembly.json +29 -0
- package/assets/templates/views/category/assembly/index.skeleton.tsx +251 -0
- package/assets/templates/views/category/assembly/registry.skeleton.tsx +34 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/binding.json +5 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/catalog.part +4 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/element.part +7 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/registry.part +18 -0
- package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/catalog.part +5 -0
- package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/element.part +34 -0
- package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/registry.part +71 -0
- package/assets/templates/views/category/content.ts +30 -0
- package/assets/templates/views/category/data.ts +12 -0
- package/assets/templates/views/category/index.tsx +299 -0
- package/assets/templates/views/category/props.ts +23 -0
- package/assets/templates/views/category/registry.tsx +122 -0
- package/assets/templates/views/category/schema.ts +91 -0
- package/assets/templates/views/checkout/content.ts +105 -0
- package/assets/templates/views/checkout/data.ts +23 -0
- package/assets/templates/views/checkout/index.tsx +111 -0
- package/assets/templates/views/checkout/props.ts +49 -0
- package/assets/templates/views/checkout/registry.tsx +217 -0
- package/assets/templates/views/checkout/schema.ts +229 -0
- package/assets/templates/views/home/assembly/assembly.json +33 -0
- package/assets/templates/views/home/assembly/index.skeleton.tsx +90 -0
- package/assets/templates/views/home/assembly/registry.skeleton.tsx +25 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature1/binding.json +5 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature1/catalog.part +4 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature1/element.part +4 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature1/registry.part +11 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature2/binding.json +5 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature2/catalog.part +4 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature2/element.part +4 -0
- package/assets/templates/views/home/assembly/slots/benefits/Feature2/registry.part +10 -0
- package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/binding.json +5 -0
- package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/catalog.part +4 -0
- package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/element.part +5 -0
- package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/registry.part +16 -0
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/binding.json +5 -0
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/catalog.part +4 -0
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/element.part +5 -0
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/registry.part +26 -0
- package/assets/templates/views/home/content.ts +70 -0
- package/assets/templates/views/home/data.ts +24 -0
- package/assets/templates/views/home/index.tsx +57 -85
- package/assets/templates/views/home/props.ts +22 -0
- package/assets/templates/views/home/registry.tsx +38 -22
- package/assets/templates/views/home/schema.ts +93 -0
- package/assets/templates/views/product/content.ts +25 -0
- package/assets/templates/views/product/data.ts +50 -0
- package/assets/templates/views/product/index.tsx +148 -0
- package/assets/templates/views/product/props.ts +27 -0
- package/assets/templates/views/product/registry.tsx +103 -0
- package/assets/templates/views/product/schema.ts +121 -0
- package/assets/templates/views/static/content.ts +99 -0
- package/assets/templates/views/static/index.tsx +60 -0
- package/assets/templates/views/static/registry.tsx +66 -0
- package/assets/templates/views/static/schema.ts +45 -0
- package/bin/storefront.js +2424 -148
- package/examples/merchandising/category-led.json +37 -0
- package/examples/merchandising/collection-led.json +37 -0
- package/package.json +15 -9
- package/recipes/archetypes.json +28 -14
- package/recipes/catalog.json +400 -0
- package/recipes/catalog.mjs +128 -0
- package/recipes/catalog.schema.json +64 -0
- package/recipes/feature.schema.json +89 -0
- package/recipes/features.json +162 -0
- package/recipes/manifest.schema.json +69 -0
- package/recipes/operations.schema.json +43 -0
- package/recipes/recipe.schema.json +11 -2
- package/recipes/recipes.json +76 -19
- package/recipes/sections.json +34 -5
- package/recipes/validate.mjs +838 -32
- package/scripts/candidate.mjs +236 -0
- package/scripts/composers.mjs +160 -0
- package/scripts/env-file.mjs +86 -0
- package/scripts/file-classes.mjs +121 -0
- package/scripts/logical-controls.mjs +61 -0
- package/scripts/manifest.mjs +298 -0
- package/scripts/migrate-english-routes.mjs +276 -0
- package/scripts/operation-registry.mjs +256 -0
- package/scripts/operations.mjs +720 -0
- package/scripts/ownership-conflict.mjs +356 -0
- package/scripts/pinning.mjs +573 -0
- package/scripts/plan-apply.mjs +987 -0
- package/scripts/preflight.mjs +51 -0
- package/scripts/reconcile.mjs +549 -0
- package/scripts/render-templates.mjs +338 -68
- package/scripts/schema-validate.mjs +132 -0
- package/scripts/section-compat.mjs +300 -0
- package/scripts/section-config.mjs +253 -0
- package/scripts/section-operations.mjs +508 -0
- package/scripts/starter.mjs +17 -0
- package/scripts/sync-assets.mjs +22 -15
- package/scripts/theme/color.mjs +185 -0
- package/scripts/theme/css-theme.mjs +233 -0
- package/scripts/theme/fonts.mjs +123 -0
- package/scripts/theme/import-export.mjs +125 -0
- package/scripts/theme/preset.mjs +93 -0
- package/scripts/theme/theme-plan.mjs +292 -0
- package/scripts/theme/tokens.mjs +137 -0
- package/scripts/view-assembly.mjs +337 -0
- package/scripts/view-selection.mjs +211 -0
- package/skills/sf-feature/SKILL.md +80 -0
- package/skills/sf-setup/SKILL.md +79 -0
- package/skills/sf-theme-gen/SKILL.md +100 -30
- package/skills/sf-theme-gen/references/shadcn-theming.md +87 -0
- package/skills/{shadcn-theming/references/templates → sf-theme-gen/references}/theme-setup.md +15 -19
- package/skills/{shadcn-theming → sf-theme-gen}/references/theming-guide.md +6 -11
- package/skills/sf-view-gen/SKILL.md +146 -93
- package/skills/sf-view-gen/assets/recipes/archetypes.json +28 -14
- package/skills/sf-view-gen/assets/recipes/catalog.json +400 -0
- package/skills/sf-view-gen/assets/recipes/catalog.schema.json +64 -0
- package/skills/sf-view-gen/assets/recipes/features.json +162 -0
- package/skills/sf-view-gen/assets/recipes/recipes.json +76 -19
- package/skills/sf-view-gen/assets/recipes/sections.json +34 -5
- package/skills/sf-view-gen/assets/templates/views/sections/cta.client.tsx +25 -0
- package/skills/sf-view-gen/assets/templates/views/sections/cta.tsx +16 -0
- package/skills/sf-view-gen/assets/templates/views/sections/faq.client.tsx +13 -9
- package/skills/sf-view-gen/assets/templates/views/sections/faq.tsx +2 -7
- package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.client.tsx +12 -8
- package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.tsx +2 -7
- package/skills/sf-view-gen/assets/templates/views/sections/pricing.client.tsx +14 -10
- package/skills/sf-view-gen/assets/templates/views/sections/pricing.tsx +2 -9
- package/skills/sf-view-gen/assets/templates/views/sections/products.client.tsx +100 -0
- package/skills/sf-view-gen/assets/templates/views/sections/products.tsx +19 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.cta.ts +19 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.faq.ts +18 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.logoCloud.ts +19 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.pricing.ts +26 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.products.ts +39 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.statistics.ts +25 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.testimonials.ts +23 -0
- package/skills/sf-view-gen/assets/templates/views/sections/statistics.client.tsx +16 -8
- package/skills/sf-view-gen/assets/templates/views/sections/statistics.tsx +2 -7
- package/skills/sf-view-gen/assets/templates/views/sections/testimonials.client.tsx +13 -9
- package/skills/sf-view-gen/assets/templates/views/sections/testimonials.tsx +2 -5
- package/skills/{json-render-core/SKILL.md → sf-view-gen/references/json-render-core.md} +4 -27
- package/skills/{json-render-next/SKILL.md → sf-view-gen/references/json-render-next.md} +5 -8
- package/skills/{json-render-react/SKILL.md → sf-view-gen/references/json-render-react.md} +3 -5
- package/skills/{json-render-shadcn/SKILL.md → sf-view-gen/references/json-render-shadcn.md} +3 -5
- package/skills/sf-view-gen/references/views.md +58 -33
- package/skills/sf-view-gen/scripts/catalog.mjs +128 -0
- package/skills/sf-view-gen/scripts/schema-validate.mjs +132 -0
- package/skills/sf-view-gen/scripts/validate.mjs +838 -32
- package/skills/storefront-workflow/SKILL.md +179 -0
- package/skills/{storefront-best-practices/reference/design.md → storefront-workflow/references/design-consistency.md} +13 -29
- package/CHANGELOG.md +0 -61
- package/commands/sf-add-view.md +0 -26
- package/commands/sf-theme.md +0 -20
- package/commands/sf-view.md +0 -25
- package/skills/building-storefronts/SKILL.md +0 -178
- package/skills/building-storefronts/references/frontend-integration.md +0 -229
- package/skills/json-render-remotion/SKILL.md +0 -111
- package/skills/json-render-solid/SKILL.md +0 -204
- package/skills/nextjs-shadcn/SKILL.md +0 -367
- package/skills/nextjs-shadcn/references/architecture.md +0 -499
- package/skills/nextjs-shadcn/references/project-setup.md +0 -162
- package/skills/nextjs-shadcn/references/shadcn-platform.md +0 -261
- package/skills/nextjs-shadcn/references/sidebar.md +0 -274
- package/skills/nextjs-shadcn/references/styling.md +0 -555
- package/skills/sf-view-gen/assets/templates/views/category/index.tsx +0 -86
- package/skills/sf-view-gen/assets/templates/views/category/registry.tsx +0 -48
- package/skills/sf-view-gen/assets/templates/views/checkout/index.tsx +0 -192
- package/skills/sf-view-gen/assets/templates/views/checkout/registry.tsx +0 -45
- package/skills/sf-view-gen/assets/templates/views/product/index.tsx +0 -122
- package/skills/sf-view-gen/assets/templates/views/product/registry.tsx +0 -49
- package/skills/sf-view-gen/assets/templates/views/user-panel/index.tsx +0 -168
- package/skills/sf-view-gen/assets/templates/views/user-panel/registry.tsx +0 -49
- package/skills/shadcn-component-discovery/SKILL.md +0 -273
- package/skills/shadcn-component-discovery/references/registries.md +0 -226
- package/skills/shadcn-theming/SKILL.md +0 -104
- package/skills/storefront-best-practices/SKILL.md +0 -421
- package/skills/storefront-best-practices/reference/components/breadcrumbs.md +0 -123
- package/skills/storefront-best-practices/reference/components/cart-popup.md +0 -189
- package/skills/storefront-best-practices/reference/components/country-selector.md +0 -298
- package/skills/storefront-best-practices/reference/components/footer.md +0 -112
- package/skills/storefront-best-practices/reference/components/hero.md +0 -241
- package/skills/storefront-best-practices/reference/components/megamenu.md +0 -239
- package/skills/storefront-best-practices/reference/components/navbar.md +0 -397
- package/skills/storefront-best-practices/reference/components/popups.md +0 -221
- package/skills/storefront-best-practices/reference/components/product-card.md +0 -125
- package/skills/storefront-best-practices/reference/components/product-reviews.md +0 -217
- package/skills/storefront-best-practices/reference/components/product-slider.md +0 -174
- package/skills/storefront-best-practices/reference/components/search.md +0 -101
- package/skills/storefront-best-practices/reference/connecting-to-backend.md +0 -391
- package/skills/storefront-best-practices/reference/features/promotions.md +0 -307
- package/skills/storefront-best-practices/reference/features/wishlist.md +0 -230
- package/skills/storefront-best-practices/reference/layouts/account.md +0 -380
- package/skills/storefront-best-practices/reference/layouts/cart.md +0 -316
- package/skills/storefront-best-practices/reference/layouts/checkout.md +0 -486
- package/skills/storefront-best-practices/reference/layouts/home-page.md +0 -264
- package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +0 -231
- package/skills/storefront-best-practices/reference/layouts/product-details.md +0 -527
- package/skills/storefront-best-practices/reference/layouts/product-listing.md +0 -520
- package/skills/storefront-best-practices/reference/layouts/static-pages.md +0 -356
- package/skills/storefront-best-practices/reference/medusa.md +0 -307
- /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/mobile-responsiveness.md +0 -0
- /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/seo.md +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: storefront-workflow
|
|
3
|
+
description: The Thor Commerce storefront workflow model — bootstrap, compose, customize, verify — and the CLI/manifest authority. Use when working in a generated storefront, before adding/removing views or features, changing the theme, or editing storefront files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Storefront workflow model
|
|
7
|
+
|
|
8
|
+
A generated storefront is defined by a **manifest** (`storefront.config.json` at
|
|
9
|
+
the project root) and produced by the `storefront` CLI. The manifest is the
|
|
10
|
+
structural source of truth; the CLI is the only writer of derived files; the
|
|
11
|
+
developer (or agent) edits only user-owned files and the bounded surface of the
|
|
12
|
+
two external files.
|
|
13
|
+
|
|
14
|
+
Run every command from inside the project (the CLI resolves the project from the
|
|
15
|
+
current directory). The CLI is installed as a dependency of the project, so
|
|
16
|
+
invoke it with `npx @thorprovider/storefront <command>` or `yarn storefront`.
|
|
17
|
+
|
|
18
|
+
## The four phases
|
|
19
|
+
|
|
20
|
+
**bootstrap → compose → customize → verify**
|
|
21
|
+
|
|
22
|
+
### 1. Bootstrap
|
|
23
|
+
|
|
24
|
+
Create the project. The CLI scaffolds Next.js, installs the pinned candidate
|
|
25
|
+
toolset, writes the initial manifest, and reconciles.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @thorprovider/storefront create <dir> --name <name> --preset <preset> [--starter]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Pass `--starter` to seed the full curated composition — every curated view and
|
|
32
|
+
feature — in the same pass; omit it for the minimal baseline.
|
|
33
|
+
|
|
34
|
+
Authority: **CLI only.** Do not scaffold or copy templates by hand.
|
|
35
|
+
|
|
36
|
+
### 2. Compose
|
|
37
|
+
|
|
38
|
+
Change the structural composition. Each command validates, updates the manifest,
|
|
39
|
+
and reconciles the derived files.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @thorprovider/storefront view add|remove <name> [--intent slot=intent] [--variant slot=Variant]
|
|
43
|
+
npx @thorprovider/storefront feature add|remove <name>
|
|
44
|
+
npx @thorprovider/storefront theme --mode light|dark|system
|
|
45
|
+
npx @thorprovider/storefront plan --operations <file> [--out <file>] [--json]
|
|
46
|
+
npx @thorprovider/storefront apply --plan <file> [--json]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Section composition (`section.add` / `section.remove` / `section.reorder`) goes
|
|
50
|
+
through the same operations envelope (`{ "formatVersion": 1, "operations": [ ... ] }`):
|
|
51
|
+
`plan` is read-only and validates the whole intended state, `apply --plan` is the
|
|
52
|
+
only writer.
|
|
53
|
+
|
|
54
|
+
Authority: **CLI only.** Agents choose *what* to compose by reading the curated
|
|
55
|
+
registry at runtime and then delegate the write to the CLI. The user states the
|
|
56
|
+
change in natural language and never types a command.
|
|
57
|
+
|
|
58
|
+
### 3. Customize
|
|
59
|
+
|
|
60
|
+
Edit the **user-owned** files (content, props, data, local schema, mappers), and —
|
|
61
|
+
within narrow bounds — the two **external** files described below. Reconcile never
|
|
62
|
+
rewrites user-owned files; it regenerates the thin derived wrappers around them,
|
|
63
|
+
and appends CLI-managed markers to the external files idempotently.
|
|
64
|
+
|
|
65
|
+
Authority: **agent/developer.** Hand-edit only user-owned files and the bounded
|
|
66
|
+
external surface.
|
|
67
|
+
|
|
68
|
+
#### Trivial vs non-trivial — and the spec-driven loop
|
|
69
|
+
|
|
70
|
+
Classify the customization before editing:
|
|
71
|
+
|
|
72
|
+
- **Trivial** — the CLI can perform it deterministically and record it in the
|
|
73
|
+
manifest (`storefront theme --mode`, `view add|remove`, `feature add|remove`,
|
|
74
|
+
`setup`). Run the CLI operation; it **does not** require an OpenSpec change —
|
|
75
|
+
`storefront.config.json` is its record.
|
|
76
|
+
- **Non-trivial** — the change needs judgment: content authoring, prop/data
|
|
77
|
+
mapping, composition reshaping, or a cross-file redesign whose acceptance is not
|
|
78
|
+
a CLI assertion. Drive it through the **spec-driven loop** and surface the five
|
|
79
|
+
stages to the user: **explore → plan → build → verify → inform**. Open the change
|
|
80
|
+
through the OpenSpec workflow (`openspec/config.yaml` is seeded with this model),
|
|
81
|
+
carry it to completion, and **never** ask the user to run `openspec`, name an
|
|
82
|
+
artifact, or approve one artifact at a time. Structural edits inside the loop
|
|
83
|
+
still go through the CLI; the loop adds intent and acceptance, not a second
|
|
84
|
+
writer.
|
|
85
|
+
|
|
86
|
+
A non-trivial change is not done until `storefront sync` and `storefront doctor`
|
|
87
|
+
pass and the change's acceptance is met.
|
|
88
|
+
|
|
89
|
+
### 4. Verify
|
|
90
|
+
|
|
91
|
+
Regenerate and check.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx @thorprovider/storefront sync # reconcile derived files to the manifest
|
|
95
|
+
npx @thorprovider/storefront doctor # composition drift + truthful version/BOM
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Authority: **CLI.** A build (`yarn build`) is the final acceptance; `doctor`
|
|
99
|
+
must report no drift.
|
|
100
|
+
|
|
101
|
+
## Read the curated registry through the CLI (never a copied list)
|
|
102
|
+
|
|
103
|
+
The installable set is whatever the registry reports; do not trust a list copied
|
|
104
|
+
into any skill. Read it at runtime, from the project root:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx @thorprovider/storefront views --json # curated views, routes, intents/variants, installed
|
|
108
|
+
npx @thorprovider/storefront features --json # feature bundles, owned views/routes, mounts
|
|
109
|
+
npx @thorprovider/storefront recipes --json # whole curated registry (views + features)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- `views --json` and `recipes --json` include the top-level `sectionTypes` list
|
|
113
|
+
that marks each section type `executable` or `held` (with a reason). That list
|
|
114
|
+
is the authority for which section types may be composed.
|
|
115
|
+
- `npx @thorprovider/storefront sections --json` reports only the currently
|
|
116
|
+
**installed** section instances; use it when the current composition matters,
|
|
117
|
+
never as the set of available types.
|
|
118
|
+
- Publishing a fixed view/feature/section list in a skill is a bug: the registry
|
|
119
|
+
is the single source, so add or remove a unit there, not in this text.
|
|
120
|
+
|
|
121
|
+
A unit the registry does not expose is a **gap to report**, not a reason to
|
|
122
|
+
install another UI framework, hand-edit a derived file, or scaffold structure
|
|
123
|
+
outside the CLI.
|
|
124
|
+
|
|
125
|
+
## File ownership
|
|
126
|
+
|
|
127
|
+
| Class | Examples | Who writes it |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| **Derived** | `views/index.ts`, `views/registry.ts`, `index.tsx`, `registry.tsx`, `catalog.ts`, `runtime.ts`, `spec/index.ts`, `state.ts`, `handlers.ts`, `features/*/adapter.ts` | CLI (reconcile); never hand-edited |
|
|
130
|
+
| **User-owned** | `views/<view>/content.ts`, `props.ts`, `data.ts`, `schema.ts`, `mappers.ts`, `icon-map.ts`, `shell/**` | developer/agent |
|
|
131
|
+
| **External** | `app/globals.css`, `app/layout.tsx` (plus create-next-app/shadcn support files) | developer/agent within the bounded surface below; the CLI only appends idempotent markers |
|
|
132
|
+
|
|
133
|
+
Removing a unit removes its derived wrapper but **preserves** any customized
|
|
134
|
+
user-owned file and reports its location.
|
|
135
|
+
|
|
136
|
+
## Bounded external customization
|
|
137
|
+
|
|
138
|
+
`app/globals.css` and `app/layout.tsx` are `external` files. The supported
|
|
139
|
+
customization surface is deliberately narrow:
|
|
140
|
+
|
|
141
|
+
- **`app/globals.css`** — theme tokens and their foreground pairs, the Tailwind
|
|
142
|
+
`@theme` bridge, font variable wiring.
|
|
143
|
+
- **`app/layout.tsx`** — font loading (`next/font`) and global identity/metadata
|
|
144
|
+
(title, description, Open Graph / Twitter).
|
|
145
|
+
|
|
146
|
+
Everything else in those files is CLI-managed and must survive: the stylesheet
|
|
147
|
+
import, the provider import and its marker, the theme-mode marker, and the block
|
|
148
|
+
token contract. The CLI appends idempotently, so a `sync` must not duplicate a
|
|
149
|
+
marker or drop an edit. Use the `sf-theme-gen` skill for these files; never edit
|
|
150
|
+
the mode wiring by hand. Per-entity SEO still comes from backend entities — global
|
|
151
|
+
customization cannot invent a canonical.
|
|
152
|
+
|
|
153
|
+
## Manifest authority
|
|
154
|
+
|
|
155
|
+
- `storefront.config.json` declares the name, theme, installed views, installed
|
|
156
|
+
features, and per-slot intents. Every structural command edits it and then
|
|
157
|
+
reconciles.
|
|
158
|
+
- `.opencode/storefront.json` is the machine-managed install record (suite
|
|
159
|
+
version, declared compatibility ranges, resolved versions, lockfile hash,
|
|
160
|
+
owned asset BOM). `doctor` validates it against the live project.
|
|
161
|
+
- A **legacy** (pre-manifest) project is detected and refused with a no-write
|
|
162
|
+
diagnostic.
|
|
163
|
+
|
|
164
|
+
## Pinning and prerequisites
|
|
165
|
+
|
|
166
|
+
- Node `>=20.9.0`, Yarn 4, `node-modules` linker. The generated project pins the
|
|
167
|
+
exact candidate toolset; `doctor` reports a linker/version mismatch non-zero.
|
|
168
|
+
- The `checkout` feature ships structural wiring only; the purchase flow is
|
|
169
|
+
owned by the separate `single-tenant-commerce-mvp` change. A generated
|
|
170
|
+
storefront is not a complete commerce implementation on its own.
|
|
171
|
+
|
|
172
|
+
## References
|
|
173
|
+
|
|
174
|
+
Relative to this `SKILL.md`:
|
|
175
|
+
|
|
176
|
+
- `references/design-consistency.md` — keeping UI changes consistent with the
|
|
177
|
+
scaffold's brand and tokens.
|
|
178
|
+
- `references/mobile-responsiveness.md` — mobile-first storefront patterns.
|
|
179
|
+
- `references/seo.md` — ecommerce SEO and structured data.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Design Guidelines
|
|
2
2
|
|
|
3
|
+
Reference material for the `storefront-workflow` skill: guardrails for keeping
|
|
4
|
+
UI changes consistent with an already-scaffolded storefront's brand. The CLI and
|
|
5
|
+
the manifest remain the structural authority; this file only guides visual
|
|
6
|
+
consistency inside the bounded surface (`app/globals.css` tokens, `app/layout.tsx`
|
|
7
|
+
fonts/identity) and `@thorprovider/blocks` usage.
|
|
8
|
+
|
|
3
9
|
## Contents
|
|
4
10
|
|
|
5
11
|
- [Overview](#overview)
|
|
@@ -243,36 +249,14 @@ When starting a new project WITHOUT existing theme:
|
|
|
243
249
|
This helps me understand your aesthetic preferences."
|
|
244
250
|
```
|
|
245
251
|
|
|
246
|
-
###
|
|
247
|
-
|
|
248
|
-
After gathering preferences, configure Tailwind theme:
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
// tailwind.config.ts
|
|
252
|
-
export default {
|
|
253
|
-
theme: {
|
|
254
|
-
extend: {
|
|
255
|
-
colors: {
|
|
256
|
-
primary: '#3B82F6', // User's primary color
|
|
257
|
-
secondary: '#8B5CF6', // User's secondary
|
|
258
|
-
accent: '#F59E0B', // Accent if needed
|
|
259
|
-
// Full scales if sophisticated design
|
|
260
|
-
brand: {
|
|
261
|
-
50: '#eff6ff',
|
|
262
|
-
500: '#3b82f6',
|
|
263
|
-
900: '#1e3a8a',
|
|
264
|
-
}
|
|
265
|
-
},
|
|
266
|
-
fontFamily: {
|
|
267
|
-
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
268
|
-
heading: ['Poppins', 'sans-serif'],
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
}
|
|
273
|
-
```
|
|
252
|
+
### Where tokens live
|
|
274
253
|
|
|
275
|
-
|
|
254
|
+
The scaffold ships its design tokens as CSS variables in `app/globals.css`
|
|
255
|
+
(`:root` + `.dark`) with a Tailwind v4 `@theme` bridge. That file is `external`
|
|
256
|
+
with a bounded surface: change token values and foreground pairs, fonts, and
|
|
257
|
+
global identity only, and keep the CLI-managed imports/markers intact. Use the
|
|
258
|
+
`sf-theme-gen` skill for color, typography, and identity changes; do not
|
|
259
|
+
introduce a separate Tailwind theme configuration.
|
|
276
260
|
|
|
277
261
|
## Decision Tree
|
|
278
262
|
|
package/CHANGELOG.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 0.4.0
|
|
4
|
-
|
|
5
|
-
- **Renamed package**: `@thorprovider/create-storefront` → `@thorprovider/storefront`;
|
|
6
|
-
the `bin` is now `storefront` (`npx @thorprovider/storefront create`).
|
|
7
|
-
- **Single scaffold command**: `storefront create <dir>` scaffolds the storefront and
|
|
8
|
-
installs the OpenCode command suite in the same run. The standalone `install` action
|
|
9
|
-
is gone; `storefront update` refreshes, prunes removed files, and migrates the
|
|
10
|
-
version record.
|
|
11
|
-
- **Interactive wizard**: on a TTY, `create` prompts for name, site name, backend URL,
|
|
12
|
-
and preset (Maia preselected). Brand color is decided via `/sf-theme`, not the wizard.
|
|
13
|
-
Without a TTY, every required input must be passed as a flag or the command fails
|
|
14
|
-
fast before writing anything.
|
|
15
|
-
- **Command surface**: `<dir>` is positional; `--dir` is removed; `--name` is a flag or
|
|
16
|
-
wizard prompt. Commands are `storefront create|update|doctor <dir>`.
|
|
17
|
-
- **Removed `/sf-init`**: the `sf-init` command and `sf-scaffold` skill are gone.
|
|
18
|
-
Scaffolding is fully deterministic inside the binary.
|
|
19
|
-
- **Decoupled templates**: the scaffold templates moved from the `sf-scaffold` skill
|
|
20
|
-
into `assets/templates/` at the package root.
|
|
21
|
-
- **Version record**: `.opencode/storefront.json` (replacing `.create-storefront.json`);
|
|
22
|
-
`update` migrates existing installs.
|
|
23
|
-
|
|
24
|
-
## 0.3.0
|
|
25
|
-
|
|
26
|
-
- **Embedded assets**: each skill now carries the templates, recipes, and scripts it
|
|
27
|
-
uses inside its own directory (`assets/`, `scripts/`, `references/`) and addresses
|
|
28
|
-
them by relative path. No path marker is needed to locate the package.
|
|
29
|
-
- **Versioned install command**: `bin` exposes `create-storefront` with `install`,
|
|
30
|
-
`update`, and `doctor`. Installation is an explicit command; there is no
|
|
31
|
-
`postinstall`. The installer records `{ version, installedAt }` in
|
|
32
|
-
`.opencode/.create-storefront.json` (replacing the `.create-storefront-root` marker).
|
|
33
|
-
- **Single source, generated copies**: `recipes/` stays the single source at the
|
|
34
|
-
package root; `scripts/sync-assets.mjs` generates the per-skill copies and a
|
|
35
|
-
`--check` mode fails on drift. The check runs at build/pretest and before the
|
|
36
|
-
installer copies anything into a target project.
|
|
37
|
-
- **Positive source-of-truth rule**: the skills state that the workflow uses the assets
|
|
38
|
-
inside the skill and that an undecided choice is resolved by asking the user.
|
|
39
|
-
- **Named interfaces**: each skill declares the target-project inputs it reads and the
|
|
40
|
-
outputs it produces.
|
|
41
|
-
- **General self-containment check**: the test fails on any absolute machine path in a
|
|
42
|
-
shipped artifact, independent of any name.
|
|
43
|
-
|
|
44
|
-
## 0.2.0
|
|
45
|
-
|
|
46
|
-
- Per-view templates: every recipe view (`home`, `product`, `category`, `checkout`,
|
|
47
|
-
`user-panel`) ships as a self-contained module under `templates/views/<view>/`.
|
|
48
|
-
- Generated storefronts now compose views through a barrel (`lib/<name>/views/index.ts`);
|
|
49
|
-
shared files (`catalog.ts`, `registry.tsx`, `runtime.ts`, `spec/index.ts`) derive from
|
|
50
|
-
the registered views and are never edited per view.
|
|
51
|
-
- `/sf-add-view` copies a view module and registers one barrel entry, substituting only
|
|
52
|
-
the imported block identifier for the resolved variant. No hand-authored wiring.
|
|
53
|
-
- Optional sections (testimonials, FAQ, statistics, logo cloud, pricing) ship as
|
|
54
|
-
fragments under `views/sections/` and are validated against `recipes/sections.json`.
|
|
55
|
-
- `sf-scaffold` copies `templates/app/` plus `templates/views/home/` and registers
|
|
56
|
-
`home` in the barrel.
|
|
57
|
-
- Templates and skills no longer reference any repository-local application.
|
|
58
|
-
|
|
59
|
-
## 0.1.3
|
|
60
|
-
|
|
61
|
-
- Previous release.
|
package/commands/sf-add-view.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Add a single view to an existing Thor Commerce storefront (product, category, checkout, user-panel)"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Add one view to an existing Thor Commerce storefront, generated from a recipe.
|
|
6
|
-
|
|
7
|
-
**Input**: view name, optionally followed by a description of what the view should contain or emphasize.
|
|
8
|
-
Examples:
|
|
9
|
-
- `/sf-add-view product`
|
|
10
|
-
- `/sf-add-view category specialize in power stations, use a dense grid`
|
|
11
|
-
- `/sf-add-view checkout keep it single-page`
|
|
12
|
-
|
|
13
|
-
**Provided arguments**: $ARGUMENTS
|
|
14
|
-
|
|
15
|
-
Use the `sf-view-gen` skill.
|
|
16
|
-
|
|
17
|
-
The skill generates from the assets inside its own directory (`assets/recipes/`, `assets/templates/views/`); when a choice is not resolved there, it asks you.
|
|
18
|
-
|
|
19
|
-
**Reads (target project):** existence of `package.json`, `lib/<name>/`, `.opencode/`, and the view name + description.
|
|
20
|
-
**Writes (target project):** the view module and one barrel entry, all reported.
|
|
21
|
-
|
|
22
|
-
**Constraints (do not violate without explicit user authorization):**
|
|
23
|
-
- Allowed view names: `home`, `product`, `category`, `checkout`, `user-panel`
|
|
24
|
-
- Block variants and optional sections MUST come from the skill's own `assets/recipes/` (`recipes.json`, `archetypes.json`, `sections.json`)
|
|
25
|
-
- UI components come ONLY from `@thorprovider/blocks`
|
|
26
|
-
- Data access goes ONLY through `@thorprovider/adapters` / `@thorprovider/runtime/commerce`
|
package/commands/sf-theme.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Customize storefront theme: OKLCH colors (light/dark), typography, and identity metadata"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Customize the theme and identity of a Thor Commerce storefront.
|
|
6
|
-
|
|
7
|
-
**Input**: optional — the wizard asks what to customize (colors, typography, identity, SEO, Open Graph).
|
|
8
|
-
**Provided arguments**: $ARGUMENTS
|
|
9
|
-
|
|
10
|
-
Use the `sf-theme-gen` skill.
|
|
11
|
-
|
|
12
|
-
The skill works from its own directory and the vendored `shadcn-theming` skill beside it; when a choice is not resolved there, it asks you.
|
|
13
|
-
|
|
14
|
-
**Reads (target project):** existence of `package.json`, `lib/<name>/`, `.opencode/`, and the wizard answers.
|
|
15
|
-
**Writes (target project):** `app/globals.css` and `app/layout.tsx`, all reported.
|
|
16
|
-
|
|
17
|
-
**Constraints (do not violate without explicit user authorization):**
|
|
18
|
-
- Colors are CSS variables in OKLCH with complete background/foreground pairs (light AND dark)
|
|
19
|
-
- Never use raw Tailwind color utilities for themed colors
|
|
20
|
-
- Typography and metadata follow the skill's own assets
|
package/commands/sf-view.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Modify an existing storefront view's spec while preserving its structure"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Modify an existing view in a Thor Commerce storefront.
|
|
6
|
-
|
|
7
|
-
**Input**: view name followed by the change to make.
|
|
8
|
-
Examples:
|
|
9
|
-
- `/sf-view home add a statistics band after the hero`
|
|
10
|
-
- `/sf-view category switch to a 4-column grid`
|
|
11
|
-
|
|
12
|
-
**Provided arguments**: $ARGUMENTS
|
|
13
|
-
|
|
14
|
-
Use the `sf-view-gen` skill (modification workflow).
|
|
15
|
-
|
|
16
|
-
The skill works from the assets inside its own directory (`assets/recipes/`, `assets/templates/views/`); when a choice is not resolved there, it asks you.
|
|
17
|
-
|
|
18
|
-
**Reads (target project):** existence of `package.json`, `lib/<name>/`, `.opencode/`, the existing view module, and the change requested.
|
|
19
|
-
**Writes (target project):** the edited view module, all reported.
|
|
20
|
-
|
|
21
|
-
**Constraints (do not violate without explicit user authorization):**
|
|
22
|
-
- Allowed view names: `home`, `product`, `category`, `checkout`, `user-panel`
|
|
23
|
-
- Preserve element ids, `type`, untouched `props`, `$state` bindings, and `on` wiring
|
|
24
|
-
- Only add block variants/sections declared in the skill's own `assets/recipes/`
|
|
25
|
-
- UI components come ONLY from `@thorprovider/blocks`
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: building-storefronts
|
|
3
|
-
description: Load automatically when planning, researching, or implementing Medusa storefront features (calling custom API routes, SDK integration, React Query patterns, data fetching). REQUIRED for all storefront development in ALL modes (planning, implementation, exploration). Contains SDK usage patterns, frontend integration, and critical rules for calling Medusa APIs.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Medusa Storefront Development
|
|
7
|
-
|
|
8
|
-
Frontend integration guide for building storefronts with Medusa. Covers SDK usage, React Query patterns, and calling custom API routes.
|
|
9
|
-
|
|
10
|
-
## When to Apply
|
|
11
|
-
|
|
12
|
-
**Load this skill for ANY storefront development task, including:**
|
|
13
|
-
- Calling custom Medusa API routes from the storefront
|
|
14
|
-
- Integrating Medusa SDK in frontend applications
|
|
15
|
-
- Using React Query for data fetching
|
|
16
|
-
- Implementing mutations with optimistic updates
|
|
17
|
-
- Error handling and cache invalidation
|
|
18
|
-
|
|
19
|
-
**Also load building-with-medusa when:** Building the backend API routes that the storefront calls
|
|
20
|
-
|
|
21
|
-
## CRITICAL: Load Reference Files When Needed
|
|
22
|
-
|
|
23
|
-
**The quick reference below is NOT sufficient for implementation.** You MUST load the reference file before writing storefront integration code.
|
|
24
|
-
|
|
25
|
-
**Load this reference when implementing storefront features:**
|
|
26
|
-
|
|
27
|
-
- **Calling API routes?** → MUST load `references/frontend-integration.md` first
|
|
28
|
-
- **Using SDK?** → MUST load `references/frontend-integration.md` first
|
|
29
|
-
- **Implementing React Query?** → MUST load `references/frontend-integration.md` first
|
|
30
|
-
|
|
31
|
-
## Rule Categories by Priority
|
|
32
|
-
|
|
33
|
-
| Priority | Category | Impact | Prefix |
|
|
34
|
-
|----------|----------|--------|--------|
|
|
35
|
-
| 1 | SDK Usage | CRITICAL | `sdk-` |
|
|
36
|
-
| 2 | React Query Patterns | HIGH | `query-` |
|
|
37
|
-
| 3 | Data Display | HIGH (includes CRITICAL price rule) | `display-` |
|
|
38
|
-
| 4 | Error Handling | MEDIUM | `error-` |
|
|
39
|
-
|
|
40
|
-
## Quick Reference
|
|
41
|
-
|
|
42
|
-
### 1. SDK Usage (CRITICAL)
|
|
43
|
-
|
|
44
|
-
- `sdk-always-use` - **ALWAYS use the Medusa JS SDK for ALL API requests** - NEVER use regular fetch()
|
|
45
|
-
- `sdk-existing-methods` - For built-in endpoints, use existing SDK methods (`sdk.store.product.list()`, `sdk.admin.order.retrieve()`)
|
|
46
|
-
- `sdk-client-fetch` - For custom API routes, use `sdk.client.fetch()`
|
|
47
|
-
- `sdk-required-headers` - SDK automatically adds required headers (publishable API key for store, auth for admin) - regular fetch() missing these headers causes errors
|
|
48
|
-
- `sdk-no-json-stringify` - **NEVER use JSON.stringify() on body** - SDK handles serialization automatically
|
|
49
|
-
- `sdk-plain-objects` - Pass plain JavaScript objects to body, not strings
|
|
50
|
-
- `sdk-locate-first` - Always locate where SDK is instantiated in the project before using it
|
|
51
|
-
|
|
52
|
-
### 2. React Query Patterns (HIGH)
|
|
53
|
-
|
|
54
|
-
- `query-use-query` - Use `useQuery` for GET requests (data fetching)
|
|
55
|
-
- `query-use-mutation` - Use `useMutation` for POST/DELETE requests (mutations)
|
|
56
|
-
- `query-invalidate` - Invalidate queries in `onSuccess` to refresh data after mutations
|
|
57
|
-
- `query-keys-hierarchical` - Structure query keys hierarchically for effective cache management
|
|
58
|
-
- `query-loading-states` - Always handle `isLoading`, `isPending`, `isError` states
|
|
59
|
-
|
|
60
|
-
### 3. Data Display (HIGH)
|
|
61
|
-
|
|
62
|
-
- `display-price-format` - **CRITICAL**: Prices from Medusa are stored as-is ($49.99 = 49.99, NOT in cents). Display them directly - NEVER divide by 100
|
|
63
|
-
|
|
64
|
-
### 4. Error Handling (MEDIUM)
|
|
65
|
-
|
|
66
|
-
- `error-on-error` - Implement `onError` callback in mutations to handle failures
|
|
67
|
-
- `error-display` - Show error messages to users when mutations fail
|
|
68
|
-
- `error-rollback` - Use optimistic updates with rollback on error for better UX
|
|
69
|
-
|
|
70
|
-
## Critical SDK Pattern
|
|
71
|
-
|
|
72
|
-
**ALWAYS pass plain objects to the SDK - NEVER use JSON.stringify():**
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// ✅ CORRECT - Plain object
|
|
76
|
-
await sdk.client.fetch("/store/reviews", {
|
|
77
|
-
method: "POST",
|
|
78
|
-
body: {
|
|
79
|
-
product_id: "prod_123",
|
|
80
|
-
rating: 5,
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
// ❌ WRONG - JSON.stringify breaks the request
|
|
85
|
-
await sdk.client.fetch("/store/reviews", {
|
|
86
|
-
method: "POST",
|
|
87
|
-
body: JSON.stringify({ // ❌ DON'T DO THIS!
|
|
88
|
-
product_id: "prod_123",
|
|
89
|
-
rating: 5,
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Why this matters:**
|
|
95
|
-
- The SDK handles JSON serialization automatically
|
|
96
|
-
- Using JSON.stringify() will double-serialize and break the request
|
|
97
|
-
- The server won't be able to parse the body
|
|
98
|
-
|
|
99
|
-
## Common Mistakes Checklist
|
|
100
|
-
|
|
101
|
-
Before implementing, verify you're NOT doing these:
|
|
102
|
-
|
|
103
|
-
**SDK Usage:**
|
|
104
|
-
- [ ] Using regular fetch() instead of the Medusa JS SDK (causes missing header errors)
|
|
105
|
-
- [ ] Not using existing SDK methods for built-in endpoints (e.g., using sdk.client.fetch("/store/products") instead of sdk.store.product.list())
|
|
106
|
-
- [ ] Using JSON.stringify() on the body parameter
|
|
107
|
-
- [ ] Manually setting Content-Type headers (SDK adds them)
|
|
108
|
-
- [ ] Hardcoding SDK import paths (locate in project first)
|
|
109
|
-
- [ ] Not using sdk.client.fetch() for custom routes
|
|
110
|
-
|
|
111
|
-
**React Query:**
|
|
112
|
-
- [ ] Not invalidating queries after mutations
|
|
113
|
-
- [ ] Using flat query keys instead of hierarchical
|
|
114
|
-
- [ ] Not handling loading and error states
|
|
115
|
-
- [ ] Forgetting to disable buttons during mutations (isPending)
|
|
116
|
-
|
|
117
|
-
**Data Display:**
|
|
118
|
-
- [ ] **CRITICAL**: Dividing prices by 100 when displaying (prices are stored as-is: $49.99 = 49.99, NOT in cents)
|
|
119
|
-
|
|
120
|
-
**Error Handling:**
|
|
121
|
-
- [ ] Not implementing onError callbacks
|
|
122
|
-
- [ ] Not showing error messages to users
|
|
123
|
-
- [ ] Not handling network failures gracefully
|
|
124
|
-
|
|
125
|
-
## How to Use
|
|
126
|
-
|
|
127
|
-
**For detailed patterns and examples, load reference file:**
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
references/frontend-integration.md - SDK usage, React Query patterns, API integration
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
The reference file contains:
|
|
134
|
-
- Step-by-step SDK integration patterns
|
|
135
|
-
- Complete React Query examples
|
|
136
|
-
- Correct vs incorrect code examples
|
|
137
|
-
- Query key best practices
|
|
138
|
-
- Optimistic update patterns
|
|
139
|
-
- Error handling strategies
|
|
140
|
-
|
|
141
|
-
## When to Use MedusaDocs MCP Server
|
|
142
|
-
|
|
143
|
-
**Use this skill for (PRIMARY SOURCE):**
|
|
144
|
-
- How to call custom API routes from storefront
|
|
145
|
-
- SDK usage patterns (sdk.client.fetch)
|
|
146
|
-
- React Query integration patterns
|
|
147
|
-
- Common mistakes and anti-patterns
|
|
148
|
-
|
|
149
|
-
**Use MedusaDocs MCP server for (SECONDARY SOURCE):**
|
|
150
|
-
- Built-in SDK methods (sdk.admin.*, sdk.store.*)
|
|
151
|
-
- Official Medusa SDK API reference
|
|
152
|
-
- Framework-specific configuration options
|
|
153
|
-
|
|
154
|
-
**Why skills come first:**
|
|
155
|
-
- Skills contain critical patterns like "don't use JSON.stringify" that MCP doesn't emphasize
|
|
156
|
-
- Skills show correct vs incorrect patterns; MCP shows what's possible
|
|
157
|
-
- Planning requires understanding patterns, not just API reference
|
|
158
|
-
|
|
159
|
-
## Integration with Backend
|
|
160
|
-
|
|
161
|
-
**⚠️ CRITICAL: ALWAYS use the Medusa JS SDK - NEVER use regular fetch()**
|
|
162
|
-
|
|
163
|
-
When building features that span backend and frontend:
|
|
164
|
-
|
|
165
|
-
1. **Backend (building-with-medusa skill):** Module → Workflow → API Route
|
|
166
|
-
2. **Storefront (this skill):** SDK → React Query → UI Components
|
|
167
|
-
3. **Connection:**
|
|
168
|
-
- Built-in endpoints: Use existing SDK methods (`sdk.store.product.list()`)
|
|
169
|
-
- Custom API routes: Use `sdk.client.fetch("/store/my-route")`
|
|
170
|
-
- **NEVER use regular fetch()** - missing publishable API key causes errors
|
|
171
|
-
|
|
172
|
-
**Why the SDK is required:**
|
|
173
|
-
- Store routes need `x-publishable-api-key` header
|
|
174
|
-
- Admin routes need `Authorization` and session headers
|
|
175
|
-
- SDK handles all required headers automatically
|
|
176
|
-
- Regular fetch() without headers → authentication/authorization errors
|
|
177
|
-
|
|
178
|
-
See `building-with-medusa` for backend API route patterns.
|