create-ailk 0.5.0 → 0.6.1
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 +55 -8
- package/component-catalog.json +336 -27
- package/component-catalog.md +25 -12
- package/dist/cli.js +54 -5
- package/dist/copy.d.ts +14 -0
- package/dist/copy.js +38 -1
- package/dist/lib/api-boot-assertion.d.ts +46 -0
- package/dist/lib/api-boot-assertion.js +70 -0
- package/dist/lib/extract-module-bundle.d.ts +20 -1
- package/dist/lib/extract-module-bundle.js +64 -5
- package/dist/lib/import-graph.d.ts +29 -0
- package/dist/lib/import-graph.js +140 -0
- package/dist/lib/module-license-gate.d.ts +6 -1
- package/dist/lib/module-license-gate.js +6 -1
- package/dist/lib/pro-callout.js +1 -1
- package/dist/module-architecture.d.ts +1 -0
- package/dist/module-architecture.js +253 -127
- package/dist/modules/commerce/0.6.0.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.0.tar.gz +0 -0
- package/dist/programmatic.js +14 -10
- package/dist/surfaces.js +105 -7
- package/dist/template-manifest.d.ts +33 -0
- package/dist/template-manifest.js +99 -16
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +1 -0
- package/package.json +3 -2
- package/site-templates/marketing-site/DESIGN.md +148 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +22 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +9 -2
- package/site-templates/marketing-site/ailk-template.json +1 -1
- package/site-templates/marketing-site-free/DESIGN.md +148 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +2 -2
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +1 -0
- package/site-templates/minimalism-site/DESIGN.md +148 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +10 -2
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +47 -35
- package/site-templates/minimalism-site/ailk-template.json +2 -1
- package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +49 -19
- package/site-templates/saas-product/DESIGN.md +148 -0
- package/site-templates/simple-service/DESIGN.md +148 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +240 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +278 -0
- package/site-templates/simple-service/ailk-template.json +10 -0
- package/site-templates/simple-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +67 -0
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +56 -0
- package/site-templates/simple-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +40 -0
- package/site-templates/simple-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/simple-service/provenance.json +4 -0
- package/templates/.env.example +72 -7
- package/templates/CLAUDE.md +2 -3
- package/templates/DESIGN.md +155 -0
- package/templates/README.md +42 -8
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +8 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +12 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +12 -0
- package/templates/apps/api/.env.example +13 -0
- package/templates/apps/api/CLAUDE.md +26 -2
- package/templates/apps/api/jest.config.cjs +3 -0
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +83 -7
- package/templates/apps/api/src/__tests__/server.test.ts +471 -0
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +45 -0
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +2 -0
- package/templates/apps/api/src/config/index.ts +62 -0
- package/templates/apps/api/src/config/modules.ts +7 -3
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +238 -2
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +143 -0
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +23 -0
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +125 -0
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +20 -0
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +317 -0
- package/templates/apps/api/src/lib/__tests__/site.test.ts +238 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +75 -0
- package/templates/apps/api/src/lib/auth-email-budget.ts +160 -0
- package/templates/apps/api/src/lib/content-adapter.ts +57 -31
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +76 -0
- package/templates/apps/api/src/lib/error-serializer.ts +23 -3
- package/templates/apps/api/src/lib/outbound-http.ts +7 -2
- package/templates/apps/api/src/lib/require-commerce-claim.ts +250 -0
- package/templates/apps/api/src/lib/site.ts +208 -9
- package/templates/apps/api/src/lib/stripe.ts +66 -0
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +182 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +42 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +7 -1
- package/templates/apps/api/src/openapi/spec.ts +543 -2
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +48 -0
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +309 -0
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +123 -0
- package/templates/apps/api/src/routes/auth/transactional-email.ts +273 -0
- package/templates/apps/api/src/routes/auth/user.ts +61 -0
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +434 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +888 -0
- package/templates/apps/api/src/routes/checkout/index.ts +34 -0
- package/templates/apps/api/src/routes/checkout/session.ts +139 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +197 -0
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +554 -0
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +108 -0
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +450 -0
- package/templates/apps/api/src/routes/content/get-page.ts +94 -12
- package/templates/apps/api/src/routes/content/index.ts +13 -73
- package/templates/apps/api/src/routes/content/list-pages.ts +15 -3
- package/templates/apps/api/src/routes/content/rate-limit.ts +15 -6
- package/templates/apps/api/src/routes/content/search.ts +129 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +447 -31
- package/templates/apps/api/src/routes/leads/index.ts +100 -13
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +351 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +5 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +4 -1
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +58 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +107 -6
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +87 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/start.ts +5 -1
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +686 -0
- package/templates/apps/api/src/routes/requests/confirm.ts +601 -0
- package/templates/apps/api/src/routes/requests/index.ts +54 -0
- package/templates/apps/api/src/routes/webhooks/README.md +265 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +749 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +330 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +262 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +285 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +213 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +301 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +648 -0
- package/templates/apps/api/src/routes/webhooks/index.ts +89 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +1399 -0
- package/templates/apps/api/src/server.ts +439 -49
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +39 -0
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +217 -40
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +620 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +2 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +300 -5
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +20 -0
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +368 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +160 -0
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +166 -0
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +154 -0
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +137 -0
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +444 -0
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +238 -0
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +78 -0
- package/templates/apps/api/src/services/abandon-email.ts +8 -2
- package/templates/apps/api/src/services/aeo-score.ts +49 -12
- package/templates/apps/api/src/services/audit-log.ts +668 -0
- package/templates/apps/api/src/services/consent.ts +18 -0
- package/templates/apps/api/src/services/default-tenant.ts +70 -31
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +141 -13
- package/templates/apps/api/src/services/dunning-policy.ts +294 -0
- package/templates/apps/api/src/services/entitlements.ts +80 -0
- package/templates/apps/api/src/services/lead-promotion.ts +13 -14
- package/templates/apps/api/src/services/lead-routing.ts +161 -2
- package/templates/apps/api/src/services/leads-inbox.ts +23 -2
- package/templates/apps/api/src/services/listing-config.ts +27 -9
- package/templates/apps/api/src/services/project-listings.ts +201 -6
- package/templates/apps/api/src/services/public-site-resolver.ts +106 -0
- package/templates/apps/api/src/services/request-confirm.ts +646 -0
- package/templates/apps/api/src/services/revalidation.ts +173 -0
- package/templates/apps/api/src/services/verified-email.ts +71 -0
- package/templates/apps/api/src/vercel-handler.ts +75 -35
- package/templates/apps/mcp/.env.example +17 -0
- package/templates/apps/mcp/CLAUDE.md +57 -24
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +6 -0
- package/templates/apps/mcp/__tests__/audit.test.ts +137 -8
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +79 -36
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +111 -2
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +82 -2
- package/templates/apps/mcp/__tests__/http-transport.test.ts +541 -2
- package/templates/apps/mcp/__tests__/index.test.ts +39 -0
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +143 -0
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +111 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +65 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +188 -0
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +165 -0
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +124 -0
- package/templates/apps/mcp/__tests__/list_pages.test.ts +116 -0
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +7 -1
- package/templates/apps/mcp/__tests__/parity.test.ts +10 -7
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +89 -22
- package/templates/apps/mcp/__tests__/read_content.test.ts +322 -1
- package/templates/apps/mcp/__tests__/search_content.test.ts +105 -2
- package/templates/apps/mcp/__tests__/server.test.ts +67 -14
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +252 -0
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +300 -123
- package/templates/apps/mcp/jest.config.cjs +13 -0
- package/templates/apps/mcp/package.json +2 -0
- package/templates/apps/mcp/src/abuse/index.ts +159 -24
- package/templates/apps/mcp/src/config/modules.ts +10 -5
- package/templates/apps/mcp/src/http-transport.ts +102 -29
- package/templates/apps/mcp/src/index.ts +73 -11
- package/templates/apps/mcp/src/lib/audit-single-page.ts +90 -3
- package/templates/apps/mcp/src/lib/commerce-claim.ts +94 -0
- package/templates/apps/mcp/src/lib/content-adapter.ts +113 -0
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +139 -0
- package/templates/apps/mcp/src/lib/prisma.ts +39 -0
- package/templates/apps/mcp/src/lib/public-workspace.ts +133 -0
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +59 -0
- package/templates/apps/mcp/src/server.ts +59 -35
- package/templates/apps/mcp/src/tools/audit.ts +26 -2
- package/templates/apps/mcp/src/tools/get_business_hours.ts +4 -3
- package/templates/apps/mcp/src/tools/get_faq.ts +4 -3
- package/templates/apps/mcp/src/tools/get_locations.ts +5 -3
- package/templates/apps/mcp/src/tools/get_offerings.ts +16 -4
- package/templates/apps/mcp/src/tools/get_pricing.ts +25 -6
- package/templates/apps/mcp/src/tools/get_site_info.ts +4 -3
- package/templates/apps/mcp/src/tools/index.ts +6 -4
- package/templates/apps/mcp/src/tools/list_pages.ts +4 -3
- package/templates/apps/mcp/src/tools/purchase.ts +128 -45
- package/templates/apps/mcp/src/tools/read_content.ts +20 -6
- package/templates/apps/mcp/src/tools/search_content.ts +11 -4
- package/templates/apps/web/.env.example +71 -5
- package/templates/apps/web/CLAUDE.md +44 -0
- package/templates/apps/web/PRODUCT.md +86 -0
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +18 -2
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +11 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +282 -0
- package/templates/apps/web/app/[locale]/(auth)/__tests__/password-reset.test.tsx +515 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +89 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +109 -0
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +92 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +135 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +109 -0
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/page.test.tsx +48 -2
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/page.tsx +20 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +125 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +96 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +101 -0
- package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +102 -0
- package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +87 -0
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +20 -10
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +84 -0
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +58 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +63 -8
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +18 -1
- package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/layout.tsx +133 -87
- package/templates/apps/web/app/[locale]/purchase/__tests__/cancel.test.tsx +162 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/module-scope.test.ts +68 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/success.test.tsx +361 -0
- package/templates/apps/web/app/[locale]/purchase/cancel/page.tsx +115 -0
- package/templates/apps/web/app/[locale]/purchase/success/page.tsx +307 -0
- package/templates/apps/web/app/[locale]/returns/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/shipping/page.tsx +44 -0
- package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +670 -0
- package/templates/apps/web/app/api/revalidate/route.ts +194 -0
- package/templates/apps/web/auth.ts +407 -8
- package/templates/apps/web/jest.config.cjs +8 -4
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +214 -0
- package/templates/apps/web/lib/__tests__/auth-routes.test.ts +74 -0
- package/templates/apps/web/lib/__tests__/meeting-slugs.test.ts +72 -0
- package/templates/apps/web/lib/__tests__/site-theme.test.ts +135 -20
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +18 -1
- package/templates/apps/web/lib/auth-email.ts +318 -0
- package/templates/apps/web/lib/auth-env.ts +85 -0
- package/templates/apps/web/lib/auth-routes.ts +55 -0
- package/templates/apps/web/lib/meeting-slugs.ts +53 -0
- package/templates/apps/web/lib/site-brand.tsx +4 -8
- package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
- package/templates/apps/web/messages/en.json +187 -0
- package/templates/apps/web/middleware.ts +1 -1
- package/templates/apps/web/package.json +2 -1
- package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
- package/templates/apps/web/src/lib/commerce-sections.ts +93 -0
- package/templates/content/_site.mdx +18 -3
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -0
- package/templates/content/en/ReturnsPolicyPage/returns.mdx +108 -0
- package/templates/content/en/ShippingPolicyPage/shipping.mdx +108 -0
- package/templates/database/CHANGELOG.md +149 -0
- package/templates/database/README.md +10 -3
- package/templates/database/__tests__/appointment.db.test.ts +106 -0
- package/templates/database/__tests__/artifact-content-store.db.test.ts +316 -0
- package/templates/database/__tests__/composite-fence.db.test.ts +206 -0
- package/templates/database/__tests__/fence-fan-out.db.test.ts +711 -0
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +79 -0
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +100 -0
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +263 -0
- package/templates/database/__tests__/prefixed-ids.db.test.ts +85 -9
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +111 -0
- package/templates/database/__tests__/tenancy.test.ts +141 -0
- package/templates/database/config/schema.prisma +79 -2
- package/templates/database/content/schema.prisma +87 -11
- package/templates/database/inbox/schema.prisma +452 -9
- package/templates/database/jest.config.cjs +5 -3
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +15 -0
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +158 -0
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +40 -0
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +67 -0
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +70 -0
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +181 -0
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +172 -0
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +41 -0
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +185 -0
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +70 -0
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +57 -0
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +68 -0
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +1067 -0
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +210 -0
- package/templates/database/package.json +3 -2
- package/templates/database/tenancy.ts +86 -1
- package/templates/database/tsconfig.json +1 -0
- package/versions.json +34 -34
- package/templates/apps/api/src/routes/content/__tests__/create.test.ts +0 -253
- package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +0 -215
- package/templates/apps/api/src/routes/content/__tests__/update.test.ts +0 -266
- package/templates/apps/api/src/routes/content/create.ts +0 -115
- package/templates/apps/api/src/routes/content/delete.ts +0 -82
- package/templates/apps/api/src/routes/content/update.ts +0 -112
- package/templates/apps/mcp/__tests__/create_page.test.ts +0 -202
- package/templates/apps/mcp/__tests__/delete_page.test.ts +0 -177
- package/templates/apps/mcp/__tests__/update_page.test.ts +0 -196
- package/templates/apps/mcp/src/tools/create_page.ts +0 -96
- package/templates/apps/mcp/src/tools/delete_page.ts +0 -74
- package/templates/apps/mcp/src/tools/update_page.ts +0 -92
- package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +0 -123
- package/templates/apps/web/public/logo-dark.svg +0 -21
- package/templates/apps/web/public/logo-light.svg +0 -21
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/next-path.test.ts +0 -0
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/next-path.ts +0 -0
|
@@ -49,6 +49,10 @@
|
|
|
49
49
|
"emptyState": "No documentation yet. Add MDX files to",
|
|
50
50
|
"emptyStateTrailing": "to populate this list."
|
|
51
51
|
},
|
|
52
|
+
"cancellation": {
|
|
53
|
+
"heading": "Cancellation Policy",
|
|
54
|
+
"emptyState": "Cancellation policy content coming soon."
|
|
55
|
+
},
|
|
52
56
|
"careers": {
|
|
53
57
|
"heading": "Careers",
|
|
54
58
|
"emptyState": "Career listings coming soon."
|
|
@@ -214,10 +218,39 @@
|
|
|
214
218
|
"heading": "Projects",
|
|
215
219
|
"emptyState": "Projects listing coming soon."
|
|
216
220
|
},
|
|
221
|
+
"purchase": {
|
|
222
|
+
"success": {
|
|
223
|
+
"title": "Payment successful",
|
|
224
|
+
"message": "Thanks for your order — here's what you bought.",
|
|
225
|
+
"statusLabel": "Paid",
|
|
226
|
+
"sessionIdLabel": "Order",
|
|
227
|
+
"lineItem": "Qty {quantity} · {amount}",
|
|
228
|
+
"continueLabel": "Back to services",
|
|
229
|
+
"pendingHeadline": "We have your order",
|
|
230
|
+
"pendingBody": "Payment is still settling. This page will not update on its own — check your email for the receipt, or come back in a few minutes.",
|
|
231
|
+
"unknownHeadline": "We can't look up this order from here",
|
|
232
|
+
"unknownBody": "Check your email for the receipt from checkout — it has everything about your order.",
|
|
233
|
+
"ctaHeadline": "Keep going",
|
|
234
|
+
"ctaDescription": "Have a look at what else we offer.",
|
|
235
|
+
"ctaLabel": "Browse services"
|
|
236
|
+
},
|
|
237
|
+
"cancel": {
|
|
238
|
+
"title": "Checkout canceled",
|
|
239
|
+
"message": "Nothing was charged. Your card was not billed.",
|
|
240
|
+
"statusLabel": "Canceled",
|
|
241
|
+
"ctaHeadline": "Still interested?",
|
|
242
|
+
"ctaDescription": "Head back to the service menu whenever you're ready.",
|
|
243
|
+
"ctaLabel": "Back to services"
|
|
244
|
+
}
|
|
245
|
+
},
|
|
217
246
|
"resources": {
|
|
218
247
|
"heading": "Resources",
|
|
219
248
|
"emptyState": "Resources listing coming soon."
|
|
220
249
|
},
|
|
250
|
+
"returns": {
|
|
251
|
+
"heading": "Returns & Refunds",
|
|
252
|
+
"emptyState": "Returns and refunds content coming soon."
|
|
253
|
+
},
|
|
221
254
|
"schedule": {
|
|
222
255
|
"title": "Book a call",
|
|
223
256
|
"description": "Pick a time that works for you.",
|
|
@@ -240,6 +273,10 @@
|
|
|
240
273
|
"heading": "Services",
|
|
241
274
|
"emptyState": "Services listing coming soon."
|
|
242
275
|
},
|
|
276
|
+
"shipping": {
|
|
277
|
+
"heading": "Shipping Policy",
|
|
278
|
+
"emptyState": "Shipping policy content coming soon."
|
|
279
|
+
},
|
|
243
280
|
"software": {
|
|
244
281
|
"heading": "Software",
|
|
245
282
|
"description": "The @working-theory/* packages \u2014 typed tools for building AX-first products.",
|
|
@@ -396,6 +433,64 @@
|
|
|
396
433
|
"signInFailed": "We couldn't sign you in. Check your details and try again.",
|
|
397
434
|
"providerFailed": "We couldn't start sign-in with that provider. Try again."
|
|
398
435
|
},
|
|
436
|
+
"auth": {
|
|
437
|
+
"signUpTitle": "Create an account",
|
|
438
|
+
"signUpDescription": "Create an account on this site.",
|
|
439
|
+
"forgotTitle": "Reset your password",
|
|
440
|
+
"forgotDescription": "Request a password reset link.",
|
|
441
|
+
"resetTitle": "Choose a new password",
|
|
442
|
+
"resetDescription": "Set a new password for your account.",
|
|
443
|
+
"verifyEmailTitle": "Check your email",
|
|
444
|
+
"verifyEmailDescription": "Follow the link we sent to continue.",
|
|
445
|
+
"email": "Email address",
|
|
446
|
+
"password": "Password",
|
|
447
|
+
"confirmPassword": "Confirm password",
|
|
448
|
+
"newPassword": "New password",
|
|
449
|
+
"orContinue": "Or continue with",
|
|
450
|
+
"ssoPrefix": "Continue with",
|
|
451
|
+
"google": "Google",
|
|
452
|
+
"github": "GitHub",
|
|
453
|
+
"backToSignIn": "Back to sign in",
|
|
454
|
+
"signUpHeading": "Create your account",
|
|
455
|
+
"signUpSubhead": "Enter your details to get started.",
|
|
456
|
+
"signUpSubmit": "Create account",
|
|
457
|
+
"signUpFooterPrompt": "Already have an account?",
|
|
458
|
+
"signUpFooterLink": "Sign in",
|
|
459
|
+
"signUpNotConfiguredSubhead": "Sign-up is not configured for this site yet. Set a provider's environment variables to enable it.",
|
|
460
|
+
"signUpFailed": "We couldn't create your account. Check your details and try again.",
|
|
461
|
+
"providerFailed": "We couldn't start sign-up with that provider. Try again.",
|
|
462
|
+
"invitationHeading": "Accounts are by invitation",
|
|
463
|
+
"invitationSubhead": "This site does not offer public sign-up.",
|
|
464
|
+
"invitationBody": "If you were invited, open the link in your invitation email to create your account.",
|
|
465
|
+
"forgotHeading": "Reset your password",
|
|
466
|
+
"forgotSubhead": "Enter your email and we will send a reset link.",
|
|
467
|
+
"forgotSubmit": "Send reset link",
|
|
468
|
+
"resetHeading": "Choose a new password",
|
|
469
|
+
"resetSubhead": "Choose a new password for your account.",
|
|
470
|
+
"resetSubmit": "Set new password",
|
|
471
|
+
"forgotUnavailableHeading": "Password reset isn't available",
|
|
472
|
+
"forgotUnavailableSubhead": "This site does not offer password reset.",
|
|
473
|
+
"forgotUnavailableBody": "Sign in with one of the providers on the sign-in page, or ask the site owner for help getting back in.",
|
|
474
|
+
"resetUnavailableHeading": "Password reset isn't available",
|
|
475
|
+
"resetUnavailableSubhead": "This reset link cannot be used on this site.",
|
|
476
|
+
"resetUnavailableBody": "Password reset is not enabled here. Sign in with one of the providers on the sign-in page instead.",
|
|
477
|
+
"sentToPrefix": "We sent it to",
|
|
478
|
+
"resetRequestFailed": "We couldn't send a reset link just now. Try again in a few minutes.",
|
|
479
|
+
"resetFailed": "We couldn't set that password. The link may have expired \u2014 request a new one.",
|
|
480
|
+
"passwordMismatch": "Both passwords must match.",
|
|
481
|
+
"resetExpiredHeading": "This reset link has expired",
|
|
482
|
+
"resetExpiredSubhead": "Reset links are single-use and last one hour.",
|
|
483
|
+
"resetExpiredBody": "Request a new link from the sign-in page and follow the most recent email.",
|
|
484
|
+
"verifyExpiredHeading": "This confirmation link has expired",
|
|
485
|
+
"verifyExpiredSubhead": "Confirmation links last 24 hours.",
|
|
486
|
+
"verifyExpiredBody": "Sign in again and we'll send you a fresh confirmation email.",
|
|
487
|
+
"sentHeading": "Check your email",
|
|
488
|
+
"sentSubhead": "Follow the link we just sent to continue.",
|
|
489
|
+
"sentBody": "Check your inbox and follow the link to continue. You can close this tab once you're done.",
|
|
490
|
+
"footerPrivacy": "Privacy",
|
|
491
|
+
"footerTerms": "Terms",
|
|
492
|
+
"footerHelp": "Help"
|
|
493
|
+
},
|
|
399
494
|
"account": {
|
|
400
495
|
"title": "Your account",
|
|
401
496
|
"description": "Your profile, results, and purchases.",
|
|
@@ -433,6 +528,12 @@
|
|
|
433
528
|
"date": "Date",
|
|
434
529
|
"emptyHeadline": "No purchases yet",
|
|
435
530
|
"emptyDescription": "Purchases you complete will appear here."
|
|
531
|
+
},
|
|
532
|
+
"subscription": {
|
|
533
|
+
"headline": "Your payment didn't go through",
|
|
534
|
+
"descriptionPastDue": "Update your card to keep your subscription active.",
|
|
535
|
+
"descriptionCanceled": "Your subscription was canceled. Update your card by {date} to keep your access.",
|
|
536
|
+
"action": "Update payment method"
|
|
436
537
|
}
|
|
437
538
|
},
|
|
438
539
|
"admin": {
|
|
@@ -480,5 +581,91 @@
|
|
|
480
581
|
"emptyHeadline": "No members yet",
|
|
481
582
|
"emptyDescription": "People with access to this workspace will appear here."
|
|
482
583
|
}
|
|
584
|
+
},
|
|
585
|
+
"edit": {
|
|
586
|
+
"title": "Pages",
|
|
587
|
+
"description": "Edit your site's pages and publish changes without a deploy.",
|
|
588
|
+
"listHeading": "Pages",
|
|
589
|
+
"listDescription": "Every page on this site. Choose one to edit its content and publish your changes.",
|
|
590
|
+
"listEmptyHeadline": "No pages yet",
|
|
591
|
+
"listEmptyDescription": "Pages you create appear here, ready to edit and publish.",
|
|
592
|
+
"statusDraft": "Draft",
|
|
593
|
+
"statusPublished": "Published",
|
|
594
|
+
"statusPublishedWithDraft": "Published, with unpublished changes",
|
|
595
|
+
"licenceRequiredHeadline": "Content editing is a Pro feature",
|
|
596
|
+
"licenceRequiredDescription": "Editing pages without a deploy is part of Pro. Add a Pro licence to this site to turn it on.",
|
|
597
|
+
"notFoundHeadline": "Page not found",
|
|
598
|
+
"notFoundDescription": "There is no page at this address. It may have been renamed or removed.",
|
|
599
|
+
"editor": {
|
|
600
|
+
"tabForm": "Details",
|
|
601
|
+
"tabBody": "Body",
|
|
602
|
+
"tabPreview": "Preview",
|
|
603
|
+
"tabCode": "Code",
|
|
604
|
+
"statusDraft": "Draft",
|
|
605
|
+
"statusNotYetLive": "Not yet live",
|
|
606
|
+
"statusPublished": "Published",
|
|
607
|
+
"frontmatterHeading": "Page details",
|
|
608
|
+
"frontmatterTitle": "Title",
|
|
609
|
+
"frontmatterSlug": "Slug",
|
|
610
|
+
"frontmatterDescription": "Description",
|
|
611
|
+
"issuesHeading": "Fix these before publishing",
|
|
612
|
+
"saveButton": "Save draft",
|
|
613
|
+
"saving": "Saving\u2026",
|
|
614
|
+
"saved": "Saved",
|
|
615
|
+
"saveError": "Could not save. Try again.",
|
|
616
|
+
"publishButton": "Publish",
|
|
617
|
+
"publishing": "Publishing\u2026",
|
|
618
|
+
"published": "Published",
|
|
619
|
+
"publishError": "Could not publish. Try again.",
|
|
620
|
+
"unpublishButton": "Unpublish",
|
|
621
|
+
"unpublishing": "Unpublishing\u2026",
|
|
622
|
+
"unpublished": "Unpublished",
|
|
623
|
+
"unpublishError": "Could not unpublish. Try again.",
|
|
624
|
+
"conflictHeading": "Someone else saved this page",
|
|
625
|
+
"conflictMessage": "This page changed since you opened it. Reload to take their version, or overwrite it with yours.",
|
|
626
|
+
"conflictReload": "Reload their version",
|
|
627
|
+
"conflictOverwrite": "Overwrite with mine",
|
|
628
|
+
"imageInsertLabel": "Insert an image",
|
|
629
|
+
"imageInsertHint": "The image is uploaded and its markdown inserted at the cursor.",
|
|
630
|
+
"imageAlt": "Image",
|
|
631
|
+
"imageInsertError": "Could not upload that image. Try again.",
|
|
632
|
+
"codeHeading": "Composed MDX",
|
|
633
|
+
"diffLegendAdded": "Added",
|
|
634
|
+
"diffLegendRemoved": "Removed",
|
|
635
|
+
"diffLegendUnchanged": "Unchanged"
|
|
636
|
+
},
|
|
637
|
+
"sections": {
|
|
638
|
+
"heading": "Sections",
|
|
639
|
+
"arrayAdd": "Add",
|
|
640
|
+
"arrayRemove": "Remove",
|
|
641
|
+
"unsupportedField": "This field is edited as raw JSON",
|
|
642
|
+
"sectionLevelErrors": "Other problems with this section"
|
|
643
|
+
},
|
|
644
|
+
"body": {
|
|
645
|
+
"label": "Body",
|
|
646
|
+
"hint": "Markdown. Headings, links, lists and images all work.",
|
|
647
|
+
"machinePreambleNotice": "This page starts with imports or components. They are preserved and are not editable here."
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
"appointments": {
|
|
651
|
+
"title": "Appointments",
|
|
652
|
+
"description": "Your site's upcoming bookings, soonest first.",
|
|
653
|
+
"forbiddenHeadline": "You don't have access",
|
|
654
|
+
"forbiddenDescription": "Sign in with the account that owns this site to see its bookings.",
|
|
655
|
+
"table": {
|
|
656
|
+
"caption": "Upcoming bookings for your site",
|
|
657
|
+
"columnWhen": "When",
|
|
658
|
+
"columnWho": "Who",
|
|
659
|
+
"columnStatus": "Status",
|
|
660
|
+
"columnPaid": "Paid",
|
|
661
|
+
"statusPending": "Pending",
|
|
662
|
+
"statusConfirmed": "Confirmed",
|
|
663
|
+
"statusCancelled": "Cancelled",
|
|
664
|
+
"paidYes": "Paid",
|
|
665
|
+
"paidNo": "Unpaid",
|
|
666
|
+
"next": "Next page",
|
|
667
|
+
"emptyHeadline": "No upcoming bookings",
|
|
668
|
+
"emptyDescription": "When someone books a time with you, the appointment appears here automatically."
|
|
669
|
+
}
|
|
483
670
|
}
|
|
484
671
|
}
|
|
@@ -79,7 +79,7 @@ export function middleware(request: NextRequest): NextResponse {
|
|
|
79
79
|
// The trailing `.*\\..*` alternative excludes any path whose last segment
|
|
80
80
|
// contains a dot, i.e. every file with an extension. Without it the negative
|
|
81
81
|
// lookahead named only favicon.ico, so next-intl's locale rewrite swallowed
|
|
82
|
-
// every OTHER public/ asset —
|
|
82
|
+
// every OTHER public/ asset — logomark.svg, wordmark.svg, site.webmanifest,
|
|
83
83
|
// og-default.png — and each 404'd (#4090 item 4). robots.txt and sitemap.xml are
|
|
84
84
|
// route handlers rather than public/ files, but they carry extensions too and
|
|
85
85
|
// are equally not locale-scoped, so the same rule covers them.
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"@working-theory/api-client": "workspace:*",
|
|
22
22
|
"@working-theory/content-adapters": "workspace:*",
|
|
23
23
|
"@working-theory/database": "workspace:*",
|
|
24
|
+
"@working-theory/ids": "workspace:*",
|
|
24
25
|
"@working-theory/jsonld": "workspace:*",
|
|
26
|
+
"@working-theory/license": "workspace:*",
|
|
25
27
|
"@working-theory/metadata": "workspace:*",
|
|
26
28
|
"@working-theory/page-renderer": "workspace:*",
|
|
27
29
|
"@working-theory/schema": "workspace:*",
|
|
@@ -64,7 +66,6 @@
|
|
|
64
66
|
"@eslint/js": "^10.0.1",
|
|
65
67
|
"globals": "^17.7.0",
|
|
66
68
|
"typescript-eslint": "^8.62.1",
|
|
67
|
-
"@working-theory/license": "workspace:*",
|
|
68
69
|
"@working-theory/sections-registry": "workspace:*"
|
|
69
70
|
}
|
|
70
71
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deployment's `commerce` add-on claim, resolved PER REQUEST (#6084 D12).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `app/.well-known/mcp.json/route.ts`'s own inline
|
|
5
|
+
* `resolveCommerceClaim()` (#5971) — that route's behaviour is unchanged;
|
|
6
|
+
* only its import line moves. `/purchase/success` and `/purchase/cancel`
|
|
7
|
+
* need the identical check (D12's shape-2 gate: the pages ship BASE TREE
|
|
8
|
+
* and gate at REQUEST time on this claim, exactly as the checkout
|
|
9
|
+
* primitives do — `apps/api/src/lib/require-commerce-claim.ts`), so this is
|
|
10
|
+
* extracted ONCE and imported three times rather than copied a third time.
|
|
11
|
+
*
|
|
12
|
+
* Fail-closed (NFR-3 mirror): anything short of a positively-held,
|
|
13
|
+
* unrevoked claim reads as absent, and a licence read that throws never
|
|
14
|
+
* takes the caller down with it. Called PER REQUEST rather than memoised —
|
|
15
|
+
* unlike `apps/mcp/src/lib/commerce-claim.ts`'s boot-time memoisation — so a
|
|
16
|
+
* site that buys commerce after its last deploy starts serving immediately
|
|
17
|
+
* rather than waiting on a redeploy.
|
|
18
|
+
*/
|
|
19
|
+
import { checkLicense } from "@working-theory/license";
|
|
20
|
+
|
|
21
|
+
/** The licence `features[]` claim that turns the commerce add-on on. */
|
|
22
|
+
const COMMERCE_FEATURE = "commerce";
|
|
23
|
+
|
|
24
|
+
export async function resolveCommerceClaim(): Promise<boolean> {
|
|
25
|
+
try {
|
|
26
|
+
const result = await checkLicense();
|
|
27
|
+
return (
|
|
28
|
+
result.revoked !== true && result.features.includes(COMMERCE_FEATURE)
|
|
29
|
+
);
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazily registers the paid `@working-theory/ui-commerce` slice's sections
|
|
3
|
+
* (`payment-receipt`) — never a static top-level import (#6084, code-review
|
|
4
|
+
* finding on this issue's PR).
|
|
5
|
+
*
|
|
6
|
+
* `/purchase/success` and `/purchase/cancel` ship in the BASE TREE
|
|
7
|
+
* (`surfaces.ts` `CORE_ROUTE_DIRS`, D12) so a site that buys the `commerce`
|
|
8
|
+
* add-on after its last deploy gets working return pages without a
|
|
9
|
+
* redeploy. But a KEYLESS scaffold carries NO `ui-commerce` dependency by
|
|
10
|
+
* design — `packages/create-ailk/scripts/build-templates.mjs`'s
|
|
11
|
+
* `transformPaidUiPackages()` strips it from a keyless `apps/web/package.json`,
|
|
12
|
+
* and `__tests__/paid-module-honest-states.test.ts`'s "#5581 U6" suite
|
|
13
|
+
* asserts a keyless scaffold declares NONE of the four paid `ui-*` packages
|
|
14
|
+
* as a dependency. A plain top-level, STATIC named-import of that package's
|
|
15
|
+
* `registerCommerceSections` export would leave every keyless customer's
|
|
16
|
+
* build failing with `ERR_MODULE_NOT_FOUND` — webpack resolves a static
|
|
17
|
+
* import at BUILD time regardless of whether the code path importing it
|
|
18
|
+
* ever executes at runtime, so gating the CALL at request time (as
|
|
19
|
+
* `resolveCommerceClaim()` already does) is not enough on its own.
|
|
20
|
+
*
|
|
21
|
+
* The `webpackIgnore` magic comment tells webpack to leave this `import()`
|
|
22
|
+
* unresolved at build time; Node's own ESM loader then attempts it at
|
|
23
|
+
* RUNTIME, where a keyless deployment's absent package throws a genuine
|
|
24
|
+
* (caught) resolution error instead of a build failure. This repo's `dev`
|
|
25
|
+
* and `build` scripts both force `--webpack` (never Turbopack, which does
|
|
26
|
+
* not honor this comment), so the magic comment is reliably honored here.
|
|
27
|
+
*
|
|
28
|
+
* On success, the real `payment-receipt` renderer is registered and the
|
|
29
|
+
* caller may build a `payment-receipt` section as usual. On failure (the
|
|
30
|
+
* package genuinely is not installed), the caller MUST NOT construct a bare
|
|
31
|
+
* `payment-receipt` section anyway — `SectionRenderer`'s dispatch table
|
|
32
|
+
* falls back to `ModuleAbsent`, which renders `null` in production
|
|
33
|
+
* (`packages/ui/src/sections/ModuleAbsent.tsx`) — silently dropping the
|
|
34
|
+
* title/message/status that is this page's entire point. The caller must
|
|
35
|
+
* build an OSS `content-block` fallback carrying the same copy instead.
|
|
36
|
+
*
|
|
37
|
+
* Registered (or found absent) once per process — memoised, so a concurrent
|
|
38
|
+
* request never double-registers or double-attempts a failed resolution.
|
|
39
|
+
* This is a build-presence fact, not the license claim itself (which
|
|
40
|
+
* `resolveCommerceClaim()` deliberately re-checks every request); a
|
|
41
|
+
* process only changes which packages are on disk via a fresh deploy, which
|
|
42
|
+
* is a fresh process.
|
|
43
|
+
*/
|
|
44
|
+
let registration: Promise<boolean> | undefined;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The paid package's specifier, held in a CONST rather than written inline at
|
|
48
|
+
* the `import()` call (#6440 AC2).
|
|
49
|
+
*
|
|
50
|
+
* `webpackIgnore` defers only WEBPACK's resolution; `tsc` resolves a dynamic
|
|
51
|
+
* `import()` whose argument is a string LITERAL exactly as eagerly as a static
|
|
52
|
+
* one, so the literal form failed a keyless scaffold's type-check with TS2307
|
|
53
|
+
* "Cannot find module '@working-theory/ui-commerce'" — the build error #6440
|
|
54
|
+
* was filed for. This monorepo never saw it: `packages-paid/ui-commerce` is on
|
|
55
|
+
* disk here and `apps/web/package.json` declares it `workspace:*`, so the
|
|
56
|
+
* specifier resolves and the defect is reachable only from a scaffold.
|
|
57
|
+
*
|
|
58
|
+
* A non-literal specifier is the whole fix. `tsc` does not attempt module
|
|
59
|
+
* resolution on an `import()` it cannot constant-fold, so the paid package's
|
|
60
|
+
* ABSENCE stops being a type error — while webpack still honours the magic
|
|
61
|
+
* comment beside it and Node still performs the real resolution at runtime,
|
|
62
|
+
* leaving the `catch` below as the one and only thing that observes whether
|
|
63
|
+
* the package is installed. The behaviour is unchanged in both directions:
|
|
64
|
+
* a licensed deployment registers the sections; a keyless one returns false.
|
|
65
|
+
*
|
|
66
|
+
* The file deliberately stays in the BASE TREE rather than moving into the
|
|
67
|
+
* commerce slice: `/purchase/success` and `/purchase/cancel` import it
|
|
68
|
+
* statically, so slicing it out would take the return pages with it and
|
|
69
|
+
* regress #6084 D12 (disposed again on #6440, 2026-09-22).
|
|
70
|
+
*/
|
|
71
|
+
const COMMERCE_UI_PACKAGE = "@working-theory/ui-commerce";
|
|
72
|
+
|
|
73
|
+
/** The one export this module needs from the paid package. */
|
|
74
|
+
interface CommerceSectionsModule {
|
|
75
|
+
registerCommerceSections: () => void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function ensureCommerceSectionsRegistered(): Promise<boolean> {
|
|
79
|
+
if (!registration) {
|
|
80
|
+
registration = (async () => {
|
|
81
|
+
try {
|
|
82
|
+
const mod = (await import(
|
|
83
|
+
/* webpackIgnore: true */ COMMERCE_UI_PACKAGE
|
|
84
|
+
)) as CommerceSectionsModule;
|
|
85
|
+
mod.registerCommerceSections();
|
|
86
|
+
return true;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
})();
|
|
91
|
+
}
|
|
92
|
+
return registration;
|
|
93
|
+
}
|
|
@@ -17,10 +17,25 @@ analytics:
|
|
|
17
17
|
theme:
|
|
18
18
|
colors:
|
|
19
19
|
light:
|
|
20
|
-
bg: "#
|
|
21
|
-
|
|
20
|
+
bg: "#ffffff"
|
|
21
|
+
bgMuted: "#ffffff"
|
|
22
|
+
surface: "#ffffff"
|
|
23
|
+
border: "#000000"
|
|
24
|
+
text: "#000000"
|
|
25
|
+
textMuted: "#333333"
|
|
26
|
+
primary: "#000000"
|
|
27
|
+
primaryFg: "#ffffff"
|
|
28
|
+
accent: "#000000"
|
|
22
29
|
dark:
|
|
23
|
-
bg: "#
|
|
30
|
+
bg: "#000000"
|
|
31
|
+
bgMuted: "#000000"
|
|
32
|
+
surface: "#000000"
|
|
33
|
+
border: "#ffffff"
|
|
34
|
+
text: "#ffffff"
|
|
35
|
+
textMuted: "#cccccc"
|
|
36
|
+
primary: "#ffffff"
|
|
37
|
+
primaryFg: "#000000"
|
|
38
|
+
accent: "#ffffff"
|
|
24
39
|
---
|
|
25
40
|
|
|
26
41
|
<!--
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "CancellationPolicyPage"
|
|
3
|
+
slug: "cancellation"
|
|
4
|
+
title: "Cancellation Policy"
|
|
5
|
+
description: "How to cancel or reschedule a booking on this site, the notice required, and what a late cancellation or no-show costs."
|
|
6
|
+
updatedAt: "2026-09-17"
|
|
7
|
+
sections:
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"id": "cancellation-document",
|
|
11
|
+
"type": "document-chassis",
|
|
12
|
+
"data":
|
|
13
|
+
{
|
|
14
|
+
"headline": "Cancellation Policy",
|
|
15
|
+
"backHref": "/",
|
|
16
|
+
"backLabel": "Back home",
|
|
17
|
+
"navGroupLabel": "Contents",
|
|
18
|
+
"stats":
|
|
19
|
+
[
|
|
20
|
+
{ "label": "Last updated", "sublabel": "17 September 2026" },
|
|
21
|
+
{ "label": "Applies to", "sublabel": "Bookings made on this site" },
|
|
22
|
+
],
|
|
23
|
+
"sections":
|
|
24
|
+
[
|
|
25
|
+
{
|
|
26
|
+
"id": "intro",
|
|
27
|
+
"heading": "Cancellation Policy",
|
|
28
|
+
"blocks":
|
|
29
|
+
[
|
|
30
|
+
{
|
|
31
|
+
"kind": "paragraph",
|
|
32
|
+
"text": "This page explains how cancellations and reschedules work for bookings made on this site. Replace the starter copy below with the policy you actually operate — the headings are the ones a customer and an agent both look for, so keep them and fill in your own terms.",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "notice",
|
|
38
|
+
"heading": "How much notice is required",
|
|
39
|
+
"blocks":
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
"kind": "paragraph",
|
|
43
|
+
"text": "State the notice period in hours before the appointment, and say how it is measured. A customer reading at midnight should be able to work out, without arithmetic you have not shown them, whether they are still inside it.",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "how-to-cancel",
|
|
49
|
+
"heading": "How to cancel or reschedule",
|
|
50
|
+
"blocks":
|
|
51
|
+
[
|
|
52
|
+
{
|
|
53
|
+
"kind": "paragraph",
|
|
54
|
+
"text": "Give one route to cancel and one to reschedule, and say whether a reschedule inside the notice period counts as a cancellation. If a booking confirmation carries a self-service link, name it here.",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "fees",
|
|
60
|
+
"heading": "Late cancellations and no-shows",
|
|
61
|
+
"blocks":
|
|
62
|
+
[
|
|
63
|
+
{
|
|
64
|
+
"kind": "paragraph",
|
|
65
|
+
"text": "Say what a late cancellation costs and what a no-show costs, as a figure or a share of the booking, and when each is charged. If you hold a deposit, say what happens to it in each case.",
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "our-cancellations",
|
|
71
|
+
"heading": "If we cancel",
|
|
72
|
+
"blocks":
|
|
73
|
+
[
|
|
74
|
+
{
|
|
75
|
+
"kind": "paragraph",
|
|
76
|
+
"text": "Set out what a customer gets if you cancel or move an appointment — a full refund, a rebooking, or both — and how quickly you tell them. A policy that only binds one side reads as one.",
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "exceptions",
|
|
82
|
+
"heading": "Exceptions",
|
|
83
|
+
"blocks":
|
|
84
|
+
[
|
|
85
|
+
{
|
|
86
|
+
"kind": "paragraph",
|
|
87
|
+
"text": "Name the circumstances in which you waive a fee — illness, bereavement, severe weather — and say what you need from the customer to apply the waiver. Vague discretion is worse for you than a short written list.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "contact",
|
|
93
|
+
"heading": "Questions about a booking",
|
|
94
|
+
"blocks":
|
|
95
|
+
[
|
|
96
|
+
{
|
|
97
|
+
"kind": "paragraph",
|
|
98
|
+
"text": "Point to the one place a customer should write, and say roughly how quickly you answer.",
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
]
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
{/* Rendered from frontmatter `sections[]`; the MDX body is not read by the section-catalog renderer. schema.org has no cancellation-policy type, so this page emits a plain WebPage (#5947, D2) — a real policy field reaches the JSON-LD through the `schema:` escape hatch, never a coined @type. */}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "ReturnsPolicyPage"
|
|
3
|
+
slug: "returns"
|
|
4
|
+
title: "Returns & Refunds"
|
|
5
|
+
description: "How to return an order from this site, how long you have, and how refunds are issued."
|
|
6
|
+
updatedAt: "2026-09-17"
|
|
7
|
+
sections:
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"id": "returns-document",
|
|
11
|
+
"type": "document-chassis",
|
|
12
|
+
"data":
|
|
13
|
+
{
|
|
14
|
+
"headline": "Returns & Refunds",
|
|
15
|
+
"backHref": "/",
|
|
16
|
+
"backLabel": "Back home",
|
|
17
|
+
"navGroupLabel": "Contents",
|
|
18
|
+
"stats":
|
|
19
|
+
[
|
|
20
|
+
{ "label": "Last updated", "sublabel": "17 September 2026" },
|
|
21
|
+
{ "label": "Applies to", "sublabel": "Orders placed on this site" },
|
|
22
|
+
],
|
|
23
|
+
"sections":
|
|
24
|
+
[
|
|
25
|
+
{
|
|
26
|
+
"id": "intro",
|
|
27
|
+
"heading": "Returns & Refunds",
|
|
28
|
+
"blocks":
|
|
29
|
+
[
|
|
30
|
+
{
|
|
31
|
+
"kind": "paragraph",
|
|
32
|
+
"text": "This page explains how returns and refunds work on this site. Replace the starter copy below with the policy you actually operate — the headings are the ones a customer and an agent both look for, so keep them and fill in your own terms.",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "return-window",
|
|
38
|
+
"heading": "How long you have",
|
|
39
|
+
"blocks":
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
"kind": "paragraph",
|
|
43
|
+
"text": "State the return window in days, counted from a date a customer can verify — delivery, not dispatch. If different products carry different windows, say which, and say plainly which items cannot be returned at all.",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "condition",
|
|
49
|
+
"heading": "What condition an item must be in",
|
|
50
|
+
"blocks":
|
|
51
|
+
[
|
|
52
|
+
{
|
|
53
|
+
"kind": "paragraph",
|
|
54
|
+
"text": "Describe the condition an item must come back in — unused, original packaging, tags attached, or whatever your standard is. Name anything that voids a return, such as a removed seal on a digital product or a personalised item.",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "how-to-return",
|
|
60
|
+
"heading": "How to start a return",
|
|
61
|
+
"blocks":
|
|
62
|
+
[
|
|
63
|
+
{
|
|
64
|
+
"kind": "paragraph",
|
|
65
|
+
"text": "Give the customer one route to start a return and the information they need to hand: an order number, the item, and the reason. If you issue a return label, say who pays for it; if you do not, say that too.",
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "refunds",
|
|
71
|
+
"heading": "How refunds are issued",
|
|
72
|
+
"blocks":
|
|
73
|
+
[
|
|
74
|
+
{
|
|
75
|
+
"kind": "paragraph",
|
|
76
|
+
"text": "Say what a customer gets back — the item price, the original shipping, or both — and how long the refund takes to reach the payment method it came from. If you offer store credit or an exchange instead, describe when each applies.",
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "exchanges",
|
|
82
|
+
"heading": "Exchanges and faulty items",
|
|
83
|
+
"blocks":
|
|
84
|
+
[
|
|
85
|
+
{
|
|
86
|
+
"kind": "paragraph",
|
|
87
|
+
"text": "A faulty or incorrectly shipped item is usually not an ordinary return. Set out how those are handled, and say whether the return window above applies to them.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "contact",
|
|
93
|
+
"heading": "Questions about a return",
|
|
94
|
+
"blocks":
|
|
95
|
+
[
|
|
96
|
+
{
|
|
97
|
+
"kind": "paragraph",
|
|
98
|
+
"text": "Point to the one place a customer should write, and say roughly how quickly you answer. A returns policy nobody can ask a question about is a policy that generates disputes.",
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
]
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
{/* Rendered from frontmatter `sections[]`; the MDX body is not read by the section-catalog renderer. The JSON-LD for this page — a WebPage wrapping a MerchantReturnPolicy — is emitted by `buildReturnsPolicyPage` (#5947), not hand-rolled here. */}
|