create-ailk 0.4.0 → 0.6.0
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 +12248 -0
- package/component-catalog.md +193 -68
- package/dist/cli.js +29 -1
- package/dist/derive-architecture.js +5 -2
- 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 +50 -2
- package/dist/lib/extract-module-bundle.js +223 -15
- package/dist/lib/fetch-guard.d.ts +28 -0
- package/dist/lib/fetch-guard.js +101 -0
- package/dist/lib/fetch-module.js +4 -0
- package/dist/lib/fetch-template.js +4 -0
- package/dist/lib/import-graph.d.ts +29 -0
- package/dist/lib/import-graph.js +140 -0
- package/dist/module-architecture.d.ts +60 -8
- package/dist/module-architecture.js +587 -242
- package/dist/parse-args.js +6 -2
- package/dist/programmatic.d.ts +10 -0
- package/dist/programmatic.js +134 -19
- package/dist/site-chrome.d.ts +80 -0
- package/dist/site-chrome.js +135 -0
- package/dist/surfaces.d.ts +21 -6
- package/dist/surfaces.js +209 -36
- package/dist/template-manifest.d.ts +88 -3
- package/dist/template-manifest.js +281 -29
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +2 -0
- package/package.json +10 -2
- package/site-templates/_base/ailk-template.json +6 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +351 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +400 -0
- package/site-templates/marketing-site/ailk-template.json +11 -0
- package/site-templates/marketing-site/content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx +36 -0
- package/site-templates/marketing-site/provenance.json +4 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +288 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +286 -0
- package/site-templates/marketing-site-free/ailk-template.json +2 -1
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +279 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +336 -0
- package/site-templates/minimalism-site/ailk-template.json +22 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-1.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-2.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-3.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-4.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-5.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-6.svg +7 -0
- package/site-templates/minimalism-site/assets/hero-backdrop.svg +17 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-1.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-2.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-3.svg +6 -0
- package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
- package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +110 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +68 -0
- package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +57 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +244 -0
- package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +77 -0
- package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +73 -0
- package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +52 -0
- package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +73 -0
- package/site-templates/minimalism-site/flows/referral.flow.json +71 -0
- package/site-templates/minimalism-site/provenance.json +4 -0
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +61 -0
- package/site-templates/saas-product/ailk-template.json +16 -0
- package/site-templates/saas-product/provenance.json +10 -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/.claude/skills/README.md +16 -25
- package/templates/.env.example +102 -12
- package/templates/.github/workflows/ci.yml +48 -0
- package/templates/README.md +3 -1
- 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 +29 -2
- package/templates/apps/api/eslint.config.mjs +69 -0
- package/templates/apps/api/jest.config.cjs +3 -0
- package/templates/apps/api/package.json +7 -2
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +89 -9
- package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +167 -0
- 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 +10 -1
- 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 +241 -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 +521 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +150 -0
- package/templates/apps/api/src/middleware/default-tenant.ts +136 -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/__tests__/list.test.ts +171 -0
- package/templates/apps/api/src/routes/leads/index.ts +100 -13
- package/templates/apps/api/src/routes/leads/list.ts +104 -0
- 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 +521 -55
- 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-promotion.test.ts +408 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +160 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +329 -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 +300 -0
- 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 +160 -0
- package/templates/apps/api/src/services/lead-routing.ts +161 -2
- package/templates/apps/api/src/services/leads-inbox.ts +284 -0
- package/templates/apps/api/src/services/listing-config.ts +27 -9
- package/templates/apps/api/src/services/owner-workspaces.ts +132 -0
- 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 +58 -25
- 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 +12 -9
- 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/{scaffold.test.ts → create_project.test.ts} +23 -23
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +300 -123
- package/templates/apps/mcp/eslint.config.mjs +69 -0
- package/templates/apps/mcp/jest.config.cjs +13 -0
- package/templates/apps/mcp/package.json +8 -2
- 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 +61 -37
- package/templates/apps/mcp/src/tools/audit.ts +26 -2
- package/templates/apps/mcp/src/tools/{scaffold.ts → create_project.ts} +3 -3
- 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 +9 -7
- 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 +74 -8
- package/templates/apps/web/CLAUDE.md +46 -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 +67 -14
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +19 -2
- package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +181 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/components/LeadsTable.tsx +137 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +111 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +1 -1
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +111 -0
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +65 -0
- package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +6 -5
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +1 -1
- package/templates/apps/web/app/[locale]/layout.tsx +308 -65
- 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/components/google-analytics.tsx +18 -1
- package/templates/apps/web/eslint.config.mjs +69 -0
- package/templates/apps/web/jest.config.cjs +15 -19
- 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__/structured-data.test.tsx +50 -6
- 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/nav-config.ts +27 -7
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/lib/site-chrome.ts +29 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +50 -0
- package/templates/apps/web/messages/en.json +216 -2
- package/templates/apps/web/next.config.mjs +20 -0
- package/templates/apps/web/package.json +8 -3
- package/templates/apps/web/sentry.client.config.ts +131 -0
- package/templates/apps/web/sentry.edge.config.ts +72 -0
- package/templates/apps/web/sentry.server.config.ts +72 -0
- package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
- package/templates/apps/web/src/lib/commerce-sections.ts +61 -0
- package/templates/apps/web/src/lib/routes.ts +13 -18
- package/templates/brand_assets/README.md +24 -0
- package/templates/content/en/AboutPage/about.mdx +160 -15
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -0
- package/templates/content/en/ContactPage/contact.mdx +90 -13
- package/templates/content/en/FAQPage/faq.mdx +62 -22
- package/templates/content/en/HomePage/home.mdx +244 -20
- package/templates/content/en/LandingPage/blog.mdx +83 -0
- package/templates/content/en/LandingPage/features.mdx +103 -0
- package/templates/content/en/LandingPage/how-it-works.mdx +143 -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__/seed.test.ts +1 -1
- 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/eslint.config.mjs +69 -0
- 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 +7 -3
- package/templates/database/seed.ts +1 -1
- package/templates/database/tenancy.ts +86 -1
- package/templates/database/tsconfig.json +1 -0
- package/templates/package.json +1 -14
- package/versions.json +52 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -103
- 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/site-templates/{marketing-site-free → _base}/content/en/PrivacyPage/privacy.mdx +0 -0
- /package/site-templates/{marketing-site-free → _base}/content/en/TermsPage/terms.mdx +0 -0
- /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
- /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
|
@@ -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,61 @@
|
|
|
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
|
+
export function ensureCommerceSectionsRegistered(): Promise<boolean> {
|
|
47
|
+
if (!registration) {
|
|
48
|
+
registration = (async () => {
|
|
49
|
+
try {
|
|
50
|
+
const mod = await import(
|
|
51
|
+
/* webpackIgnore: true */ "@working-theory/ui-commerce"
|
|
52
|
+
);
|
|
53
|
+
mod.registerCommerceSections();
|
|
54
|
+
return true;
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
})();
|
|
59
|
+
}
|
|
60
|
+
return registration;
|
|
61
|
+
}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* handlers to avoid copy-paste duplication.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { routeFor } from "@working-theory/templates/routes";
|
|
9
|
+
|
|
8
10
|
import { SITE_BASE_URL } from "../../lib/site-brand";
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -29,22 +31,15 @@ export function resolveBaseUrl(): string {
|
|
|
29
31
|
/**
|
|
30
32
|
* Maps a content-adapter page type + slug to a site-relative path.
|
|
31
33
|
* Drives both /llms.txt and /sitemap.xml URL generation.
|
|
34
|
+
*
|
|
35
|
+
* A lookup over the routes map (#5572 U2, spec § D4 row 1) — `routeFor` is
|
|
36
|
+
* byte-identical to the switch this replaced for its six `case` literals and
|
|
37
|
+
* the `` `/${slug}` `` default (proven by
|
|
38
|
+
* `packages/templates/src/__tests__/routes-map.test.ts`'s table test and
|
|
39
|
+
* `apps/web/__tests__/routes/routes-map-identity.test.ts`'s differential
|
|
40
|
+
* test over the live content tree). The signature is annotated explicitly so
|
|
41
|
+
* this stays the exact `(type: string, slug: string) => string` contract the
|
|
42
|
+
* three call sites (`sitemap.xml`, `llms.txt`, `docs-blog/llms-route.ts`)
|
|
43
|
+
* depend on, even though `routeFor`'s own `slug` parameter is optional.
|
|
32
44
|
*/
|
|
33
|
-
export
|
|
34
|
-
switch (type) {
|
|
35
|
-
case "HomePage":
|
|
36
|
-
return "/";
|
|
37
|
-
case "BlogPosting":
|
|
38
|
-
return `/blog/${slug}`;
|
|
39
|
-
case "Product":
|
|
40
|
-
return `/products/${slug}`;
|
|
41
|
-
case "Service":
|
|
42
|
-
return `/services/${slug}`;
|
|
43
|
-
case "AboutPage":
|
|
44
|
-
return "/about";
|
|
45
|
-
case "ContactPage":
|
|
46
|
-
return "/contact";
|
|
47
|
-
default:
|
|
48
|
-
return `/${slug}`;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
45
|
+
export const slugToPath: (type: string, slug: string) => string = routeFor;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# brand_assets/
|
|
2
|
+
|
|
3
|
+
This folder is where you put your project's real brand material. It ships
|
|
4
|
+
empty — nothing here is required to run `pnpm dev` — but populating it is
|
|
5
|
+
what lets Claude Code (and anyone else building this site) use your actual
|
|
6
|
+
brand instead of inventing placeholder colors and copy.
|
|
7
|
+
|
|
8
|
+
`apps/web/CLAUDE.md` reads from this folder before designing a page. If a
|
|
9
|
+
file below is present, it's used; if it's absent, generic defaults are used
|
|
10
|
+
instead.
|
|
11
|
+
|
|
12
|
+
## What goes here
|
|
13
|
+
|
|
14
|
+
| File / folder | Contents |
|
|
15
|
+
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
16
|
+
| `logo.svg` (or `.png`) | Your logo, ideally an SVG. Add light/dark variants if your mark needs them (e.g. `logo-dark.svg`). |
|
|
17
|
+
| `brand-guide.md` | The global theme — brand colors, type direction, tone of voice, do's and don'ts — used when choosing layout and components for a page. |
|
|
18
|
+
| `brand-brief.md` | Positioning, messaging, and the target citation phrases a page's content should work toward. |
|
|
19
|
+
| `favicon.ico` / `favicon-*.png` | Favicon assets for `apps/web/app/favicon.ico` and any additional sizes your deploy target wants. |
|
|
20
|
+
| `photos/` | Real photography — team, product, office — to use instead of stock or placeholder images. |
|
|
21
|
+
| `reference/` | Mockups, screenshots, or other visual references to match when building or reviewing a page's design. |
|
|
22
|
+
|
|
23
|
+
None of these are mandatory. Add what you have; the rest can stay
|
|
24
|
+
placeholder until you're ready.
|
|
@@ -1,29 +1,174 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: "AboutPage"
|
|
3
3
|
slug: "about"
|
|
4
|
-
title: "
|
|
5
|
-
description: "
|
|
4
|
+
title: "We want you to {ability they couldn't do before}"
|
|
5
|
+
description: "We want you to {ability they couldn't do before}"
|
|
6
6
|
sections:
|
|
7
7
|
[
|
|
8
8
|
{
|
|
9
|
-
"id": "
|
|
10
|
-
"type": "
|
|
11
|
-
"data":
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
"id": "manifesto",
|
|
10
|
+
"type": "content-block",
|
|
11
|
+
"data": {
|
|
12
|
+
"variant": "media-right",
|
|
13
|
+
"eyebrow": "Manifesto",
|
|
14
|
+
"headline": "We want you to {ability they couldn't do before}",
|
|
15
|
+
"body": "Hey, I’m {your name}, the founder of {your company}.\n\nWrite a few sentences introducing the problems you solve. You can even ask a rhetorical question to get people thinking about their own personal experiences with a problem they might have encountered.\n\nThis is your chance to tell the backstory of why your product exists and explain the gap your product fills. Don’t be afraid to take a stance and plant your flag.\n\nWe believe that {you should be able to X without Y}.\n\nWe’ll help you:\n\nSolve this problem\n\nSolve another problem\n\nSolve this other problem\n\nIf that resonates with you, you're in the right place.\n\n- (your name)",
|
|
16
|
+
"cta": {
|
|
17
|
+
"label": "Sign Up",
|
|
18
|
+
"href": "/sign-in"
|
|
15
19
|
},
|
|
20
|
+
"secondaryCta": {
|
|
21
|
+
"label": "More about us",
|
|
22
|
+
"href": "/about",
|
|
23
|
+
"variant": "outline"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
},
|
|
17
27
|
{
|
|
18
|
-
"id": "
|
|
19
|
-
"type": "
|
|
20
|
-
"data":
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
"id": "team",
|
|
29
|
+
"type": "team",
|
|
30
|
+
"data": {
|
|
31
|
+
"headline": "Our team",
|
|
32
|
+
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
|
33
|
+
"members": [
|
|
34
|
+
{
|
|
35
|
+
"name": "Anya Lind",
|
|
36
|
+
"role": "Head of Growth",
|
|
37
|
+
"bio": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "Narciso Gerlach",
|
|
41
|
+
"role": "Head of Sales",
|
|
42
|
+
"bio": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "Edythe Sanford",
|
|
46
|
+
"role": "Head of Content",
|
|
47
|
+
"bio": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "Angeline Watsica",
|
|
51
|
+
"role": "Head of Conversion",
|
|
52
|
+
"bio": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "Gerardo Ullrich",
|
|
56
|
+
"role": "Head of Marketing",
|
|
57
|
+
"bio": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique."
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "logo-cloud",
|
|
64
|
+
"type": "logoCloud",
|
|
65
|
+
"data": {
|
|
66
|
+
"headline": "Don’t just take our word for it",
|
|
67
|
+
"logos": [
|
|
68
|
+
{
|
|
69
|
+
"name": "Placeholder logo",
|
|
70
|
+
"src": "/logomark.svg"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "Placeholder logo",
|
|
74
|
+
"src": "/logomark.svg"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "Placeholder logo",
|
|
78
|
+
"src": "/logomark.svg"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "Placeholder logo",
|
|
82
|
+
"src": "/logomark.svg"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "Placeholder logo",
|
|
86
|
+
"src": "/logomark.svg"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "Placeholder logo",
|
|
90
|
+
"src": "/logomark.svg"
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"layout": "inline",
|
|
94
|
+
"treatment": "monochrome"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "testimonial",
|
|
99
|
+
"type": "testimonials",
|
|
100
|
+
"data": {
|
|
101
|
+
"variant": "featured",
|
|
102
|
+
"items": [
|
|
103
|
+
{
|
|
104
|
+
"quote": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat.",
|
|
105
|
+
"author": "John Smith",
|
|
106
|
+
"role": "CEO, Google"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "switch",
|
|
113
|
+
"type": "cta",
|
|
114
|
+
"data": {
|
|
115
|
+
"variant": "box",
|
|
116
|
+
"headline": "Switch to {your product} in {time amount} or less",
|
|
117
|
+
"description": "You shouldn't have to {experience a painful problem}. With {your product}, you can finally {achieve a value outcome or get a big improvement}.",
|
|
118
|
+
"chips": [
|
|
119
|
+
"No credit card required",
|
|
120
|
+
"Cancel any time",
|
|
121
|
+
"Live chat support"
|
|
122
|
+
],
|
|
123
|
+
"primaryCta": {
|
|
124
|
+
"label": "{Primary CTA}",
|
|
125
|
+
"href": "/contact"
|
|
126
|
+
},
|
|
127
|
+
"secondaryCta": {
|
|
128
|
+
"label": "{Secondary CTA}",
|
|
129
|
+
"href": "/pricing",
|
|
130
|
+
"variant": "outline"
|
|
24
131
|
},
|
|
132
|
+
"closingLine": "{Social Proof goes here}"
|
|
133
|
+
}
|
|
25
134
|
},
|
|
135
|
+
{
|
|
136
|
+
"id": "faq",
|
|
137
|
+
"type": "faq",
|
|
138
|
+
"data": {
|
|
139
|
+
"headline": "FAQs",
|
|
140
|
+
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
|
|
141
|
+
"supportLink": {
|
|
142
|
+
"label": "Contact",
|
|
143
|
+
"href": "/contact"
|
|
144
|
+
},
|
|
145
|
+
"presentation": "accordion",
|
|
146
|
+
"initialOpen": "first",
|
|
147
|
+
"items": [
|
|
148
|
+
{
|
|
149
|
+
"question": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa?",
|
|
150
|
+
"answer": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"question": "Dolorem consectetur quia maxime sunt ut sint. Fuga optio dolorem animi voluptatem laudantium error. Quis accusamus deleniti rer?",
|
|
154
|
+
"answer": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"question": "Totam nihil esse. Itaque optio temporibus adipisci. Rerum nisi aperiam aliquid doloremque aliquam?",
|
|
158
|
+
"answer": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa."
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"question": "Delectus minus officiis et. Perspiciatis illum nisi vitae. Sed consequuntur animi corrupti distinctio ipsam accusamus?",
|
|
162
|
+
"answer": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa."
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"question": "Aperiam perferendis voluptatem est sit enim sed eaque perspiciatis enim. Est explicabo ea explicabo et et dignissimos aliquid?",
|
|
166
|
+
"answer": "Vel odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa odio odit voluptatum ut veritatis. Ex rerum aspernatur voluptas unde officia. Dolorem officiis laboriosa."
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
26
171
|
]
|
|
27
172
|
---
|
|
28
173
|
|
|
29
|
-
{/* Rendered from frontmatter `sections[]`.
|
|
174
|
+
{/* Rendered from frontmatter `sections[]`. Placeholder copy, verbatim from the reference — replace the manifesto and the team before you launch. */}
|
|
@@ -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. */}
|
|
@@ -2,27 +2,104 @@
|
|
|
2
2
|
type: "ContactPage"
|
|
3
3
|
slug: "contact"
|
|
4
4
|
title: "Contact {{COMPANY_NAME}}"
|
|
5
|
-
description: "
|
|
5
|
+
description: "Find out if {your product} is a good fit for you in just {time amount}."
|
|
6
6
|
sections:
|
|
7
7
|
[
|
|
8
8
|
{
|
|
9
9
|
"id": "hero",
|
|
10
10
|
"type": "hero",
|
|
11
|
-
"data":
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
11
|
+
"data": {
|
|
12
|
+
"variant": "split",
|
|
13
|
+
"eyebrow": "Book a Demo",
|
|
14
|
+
"headline": "Ready to {achieve a valuable outcome}?",
|
|
15
|
+
"subheadline": "Find out if {your product} is a good fit for you in just {time amount}.",
|
|
16
|
+
"checklist": [
|
|
17
|
+
"Use these bullet points to describe what to expect on the call",
|
|
18
|
+
"Alleviate any fears or hesitations visitors might have before scheduling",
|
|
19
|
+
"Frame the meeting around what they get out of it instead of what you get out of it"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
16
22
|
},
|
|
17
23
|
{
|
|
18
|
-
"id": "
|
|
19
|
-
"type": "
|
|
20
|
-
"data":
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
"id": "contact-form",
|
|
25
|
+
"type": "contact-form",
|
|
26
|
+
"data": {
|
|
27
|
+
"variant": "card",
|
|
28
|
+
"fields": [
|
|
29
|
+
{
|
|
30
|
+
"name": "name",
|
|
31
|
+
"label": "Name",
|
|
32
|
+
"type": "text",
|
|
33
|
+
"required": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "email",
|
|
37
|
+
"label": "Email",
|
|
38
|
+
"type": "email",
|
|
39
|
+
"required": true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "message",
|
|
43
|
+
"label": "Message",
|
|
44
|
+
"type": "textarea",
|
|
45
|
+
"required": true
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"consentText": "I accept the Terms",
|
|
49
|
+
"successMessage": "Thank you! Your submission has been received!",
|
|
50
|
+
"action": "/v1/leads/submit"
|
|
51
|
+
}
|
|
24
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"id": "logo-cloud",
|
|
55
|
+
"type": "logoCloud",
|
|
56
|
+
"data": {
|
|
57
|
+
"headline": "Don’t just take our word for it",
|
|
58
|
+
"logos": [
|
|
59
|
+
{
|
|
60
|
+
"name": "Placeholder logo",
|
|
61
|
+
"src": "/logomark.svg"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "Placeholder logo",
|
|
65
|
+
"src": "/logomark.svg"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "Placeholder logo",
|
|
69
|
+
"src": "/logomark.svg"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "Placeholder logo",
|
|
73
|
+
"src": "/logomark.svg"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "Placeholder logo",
|
|
77
|
+
"src": "/logomark.svg"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "Placeholder logo",
|
|
81
|
+
"src": "/logomark.svg"
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
"layout": "inline",
|
|
85
|
+
"treatment": "monochrome"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "testimonial",
|
|
90
|
+
"type": "testimonials",
|
|
91
|
+
"data": {
|
|
92
|
+
"variant": "featured",
|
|
93
|
+
"items": [
|
|
94
|
+
{
|
|
95
|
+
"quote": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat.",
|
|
96
|
+
"author": "John Smith",
|
|
97
|
+
"role": "CEO, Google"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
25
102
|
]
|
|
26
103
|
---
|
|
27
104
|
|
|
28
|
-
{/* Rendered from frontmatter `sections[]`.
|
|
105
|
+
{/* Rendered from frontmatter `sections[]`. The form posts to the site's own API (`/v1/leads/submit`) and confirms inline. Placeholder copy — replace before you launch. */}
|