create-ailk 0.24.0 → 0.26.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 +53 -22
- package/component-catalog.json +3 -3
- package/component-catalog.md +3 -3
- package/dist/add-module.js +4 -2
- package/dist/add-route.d.ts +12 -1
- package/dist/add-route.js +31 -3
- package/dist/cli.js +12 -7
- package/dist/derive-architecture.d.ts +3 -4
- package/dist/derive-architecture.js +65 -29
- package/dist/lib/design-checks.d.ts +9 -4
- package/dist/lib/design-checks.js +13 -7
- package/dist/lib/extract-module-bundle.js +29 -2
- package/dist/lib/fetch-template-snapshot.d.ts +2 -1
- package/dist/lib/fetch-template-snapshot.js +8 -3
- package/dist/lib/import-graph.d.ts +1 -1
- package/dist/lib/import-graph.js +4 -4
- package/dist/lib/module-license-gate.d.ts +12 -1
- package/dist/lib/module-license-gate.js +36 -15
- package/dist/lib/module-tier.d.ts +2 -8
- package/dist/lib/module-tier.js +13 -12
- package/dist/module-architecture.d.ts +20 -3
- package/dist/module-architecture.js +129 -552
- package/dist/paid-sections.d.ts +25 -1
- package/dist/paid-sections.js +88 -3
- package/dist/starter-grid.d.ts +6 -6
- package/dist/starter-grid.js +12 -5
- package/dist/surfaces.js +39 -2
- package/dist/template-record.d.ts +21 -3
- package/dist/template-record.js +38 -7
- package/dist/topology.d.ts +16 -3
- package/dist/topology.js +54 -23
- package/dist/update.d.ts +10 -1
- package/dist/update.js +715 -21
- package/package.json +3 -3
- package/release-scope.json +2 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
- package/site-templates/marketing-site/ailk-template.json +7 -1
- package/site-templates/marketing-site/provenance.json +7 -1
- package/site-templates/saas-product/ailk-template.json +2 -1
- package/site-templates/saas-product/provenance.json +1 -0
- package/templates/.claude/cloudparity-repo-hooks.json +5 -0
- package/templates/.claude/hooks/template-guard.sh +137 -0
- package/templates/.claude/rules/extending.md +106 -0
- package/templates/.claude/rules/loop-contract.md +2 -2
- package/templates/.claude/settings.json +11 -0
- package/templates/.env.example +20 -5
- package/templates/.github/workflows/ci.yml +7 -4
- package/templates/CLAUDE.md +11 -1
- package/templates/CONVENTIONS.md +8 -10
- package/templates/README.md +14 -13
- package/templates/apps/api/.env.example +23 -2
- package/templates/apps/api/CLAUDE.md +119 -83
- package/templates/apps/api/jest.config.cjs +15 -5
- package/templates/apps/api/package.json +16 -20
- package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
- package/templates/apps/api/src/index.ts +1 -1
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +16 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
- package/templates/apps/api/src/modules/commerce.ts +10 -0
- package/templates/apps/api/src/modules/content-write.ts +10 -0
- package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
- package/templates/apps/api/src/modules/scheduling.ts +10 -0
- package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
- package/templates/apps/api/src/modules/workspace.ts +10 -0
- package/templates/apps/api/src/server.ts +117 -1882
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/CLAUDE.md +90 -26
- package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
- package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
- package/templates/apps/mcp/jest.config.cjs +6 -1
- package/templates/apps/mcp/package.json +5 -13
- package/templates/apps/mcp/src/app.ts +8 -7
- package/templates/apps/mcp/src/index.ts +6 -34
- package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
- package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
- package/templates/apps/mcp/src/site.ts +12 -0
- package/templates/apps/web/.env.example +1 -1
- package/templates/apps/web/CLAUDE.md +31 -3
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
- package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +117 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +14 -37
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +108 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +78 -16
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
- package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
- package/templates/apps/web/app/[locale]/layout.tsx +33 -13
- package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
- package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
- package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
- package/templates/apps/web/app/api/revalidate/route.ts +3 -3
- package/templates/apps/web/auth.ts +10 -6
- package/templates/apps/web/i18n/request.ts +49 -1
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
- package/templates/apps/web/lib/auth-email.ts +103 -21
- package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +72 -23
- package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +94 -70
- package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
- package/templates/apps/web/lib/relay.ts +2 -2
- package/templates/apps/web/lib/release-scope.ts +47 -0
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/lib/sign-up-agreements.ts +291 -28
- package/templates/apps/web/lib/site-contributions.ts +18 -0
- package/templates/apps/web/messages/en.json +186 -20
- package/templates/apps/web/messages/site/en.json +1 -0
- package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
- package/templates/customizations.yaml +37 -0
- package/templates/database/prisma.config.ts +10 -14
- package/templates/database/seed-test.ts +2 -2
- package/templates/database/seed.ts +5 -5
- package/templates/package.json +12 -6
- package/templates/pnpm-workspace.yaml +0 -1
- package/templates/project.yaml +16 -8
- package/templates/tools/jest/reporters.cjs +65 -0
- package/templates/tools/lint-architecture.ts +553 -7
- package/templates/tsconfig.json +1 -2
- package/versions.json +49 -36
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
- package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
- package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
- package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
- package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
- package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
- package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
- package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
- package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
- package/templates/apps/api/src/bin/spokes.ts +0 -198
- package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
- package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
- package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
- package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
- package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
- package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
- package/templates/apps/api/src/config/index.ts +0 -596
- package/templates/apps/api/src/config/modules.ts +0 -83
- package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
- package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
- package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
- package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
- package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
- package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
- package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
- package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
- package/templates/apps/api/src/lib/agent-store.ts +0 -613
- package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
- package/templates/apps/api/src/lib/consent-store.ts +0 -363
- package/templates/apps/api/src/lib/content-adapter.ts +0 -112
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
- package/templates/apps/api/src/lib/error-serializer.ts +0 -164
- package/templates/apps/api/src/lib/errors.ts +0 -95
- package/templates/apps/api/src/lib/file-fallback.ts +0 -87
- package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
- package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
- package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
- package/templates/apps/api/src/lib/license-key-store.ts +0 -45
- package/templates/apps/api/src/lib/locales.ts +0 -201
- package/templates/apps/api/src/lib/outbound-http.ts +0 -127
- package/templates/apps/api/src/lib/prisma.ts +0 -21
- package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
- package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
- package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
- package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
- package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
- package/templates/apps/api/src/lib/site.ts +0 -257
- package/templates/apps/api/src/lib/slice-load.ts +0 -90
- package/templates/apps/api/src/lib/spoke-store.ts +0 -180
- package/templates/apps/api/src/lib/stripe.ts +0 -321
- package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
- package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
- package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
- package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
- package/templates/apps/api/src/middleware/auth.ts +0 -864
- package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
- package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
- package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
- package/templates/apps/api/src/openapi/index.ts +0 -18
- package/templates/apps/api/src/openapi/spec.ts +0 -2148
- package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
- package/templates/apps/api/src/routes/aeo/index.ts +0 -107
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
- package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
- package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
- package/templates/apps/api/src/routes/auth/user.ts +0 -305
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
- package/templates/apps/api/src/routes/checkout/index.ts +0 -34
- package/templates/apps/api/src/routes/checkout/session.ts +0 -171
- package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
- package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
- package/templates/apps/api/src/routes/consent/account.ts +0 -268
- package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
- package/templates/apps/api/src/routes/consent/index.ts +0 -26
- package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
- package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
- package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
- package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
- package/templates/apps/api/src/routes/content/get-page.ts +0 -183
- package/templates/apps/api/src/routes/content/index.ts +0 -49
- package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
- package/templates/apps/api/src/routes/content/list-types.ts +0 -19
- package/templates/apps/api/src/routes/content/offerings.ts +0 -184
- package/templates/apps/api/src/routes/content/pricing.ts +0 -176
- package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
- package/templates/apps/api/src/routes/content/search.ts +0 -100
- package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
- package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
- package/templates/apps/api/src/routes/leads/index.ts +0 -639
- package/templates/apps/api/src/routes/leads/list.ts +0 -104
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
- package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
- package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
- package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
- package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
- package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
- package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
- package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
- package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
- package/templates/apps/api/src/routes/requests/index.ts +0 -54
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
- package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
- package/templates/apps/api/src/routes/webhooks/README.md +0 -398
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
- package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
- package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
- package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
- package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
- package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
- package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
- package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
- package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
- package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
- package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
- package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
- package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
- package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
- package/templates/apps/api/src/services/abandon-email.ts +0 -336
- package/templates/apps/api/src/services/aeo-score.ts +0 -325
- package/templates/apps/api/src/services/answer-distributions.ts +0 -138
- package/templates/apps/api/src/services/audit-log.ts +0 -961
- package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
- package/templates/apps/api/src/services/consent.ts +0 -834
- package/templates/apps/api/src/services/default-tenant.ts +0 -416
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
- package/templates/apps/api/src/services/dunning-policy.ts +0 -294
- package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
- package/templates/apps/api/src/services/entitlements.ts +0 -338
- package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
- package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
- package/templates/apps/api/src/services/lead-promotion.ts +0 -160
- package/templates/apps/api/src/services/lead-routing.ts +0 -1372
- package/templates/apps/api/src/services/leads-inbox.ts +0 -312
- package/templates/apps/api/src/services/listing-config.ts +0 -178
- package/templates/apps/api/src/services/magnet-completion.ts +0 -242
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
- package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
- package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
- package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
- package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
- package/templates/apps/api/src/services/offerings/index.ts +0 -614
- package/templates/apps/api/src/services/offerings/source.ts +0 -140
- package/templates/apps/api/src/services/offerings/store.ts +0 -150
- package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
- package/templates/apps/api/src/services/person.ts +0 -1211
- package/templates/apps/api/src/services/plan-offerings.ts +0 -125
- package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
- package/templates/apps/api/src/services/project-listings.ts +0 -2085
- package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
- package/templates/apps/api/src/services/request-confirm.ts +0 -698
- package/templates/apps/api/src/services/revalidation.ts +0 -235
- package/templates/apps/api/src/services/slack-notify.ts +0 -291
- package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
- package/templates/apps/api/src/services/usage-credits.ts +0 -340
- package/templates/apps/api/src/services/verified-email.ts +0 -71
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
- package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
- package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
- package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
- package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
- package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
- package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
- package/templates/apps/mcp/__tests__/index.test.ts +0 -195
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
- package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
- package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
- package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
- package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
- package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
- package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
- package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
- package/templates/apps/mcp/__tests__/server.test.ts +0 -388
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
- package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
- package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
- package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
- package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
- package/templates/apps/mcp/src/abuse/index.ts +0 -349
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
- package/templates/apps/mcp/src/boot.ts +0 -167
- package/templates/apps/mcp/src/config/modules.ts +0 -43
- package/templates/apps/mcp/src/http-transport.ts +0 -564
- package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
- package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
- package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
- package/templates/apps/mcp/src/lib/errors.ts +0 -61
- package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
- package/templates/apps/mcp/src/lib/locales.ts +0 -171
- package/templates/apps/mcp/src/lib/prisma.ts +0 -39
- package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
- package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
- package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
- package/templates/apps/mcp/src/lib/site-config.ts +0 -53
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
- package/templates/apps/mcp/src/request-context.ts +0 -52
- package/templates/apps/mcp/src/server.ts +0 -343
- package/templates/apps/mcp/src/serverless-app.ts +0 -88
- package/templates/apps/mcp/src/tools/audit.ts +0 -127
- package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
- package/templates/apps/mcp/src/tools/create_project.ts +0 -134
- package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
- package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
- package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
- package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
- package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
- package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
- package/templates/apps/mcp/src/tools/index.ts +0 -138
- package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
- package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
- package/templates/apps/mcp/src/tools/proposals.ts +0 -27
- package/templates/apps/mcp/src/tools/purchase.ts +0 -205
- package/templates/apps/mcp/src/tools/read_content.ts +0 -81
- package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
- package/templates/apps/mcp/src/tools/search_content.ts +0 -63
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
- package/templates/apps/mcp/src/workspace-server.ts +0 -224
- package/templates/database/CHANGELOG.md +0 -981
- package/templates/database/LICENSE +0 -202
- package/templates/database/NOTICE +0 -2
- package/templates/database/README.md +0 -243
- package/templates/database/__tests__/agents.db.test.ts +0 -320
- package/templates/database/__tests__/appointment.db.test.ts +0 -106
- package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
- package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
- package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
- package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
- package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
- package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
- package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
- package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
- package/templates/database/__tests__/flows-presets.test.ts +0 -173
- package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
- package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
- package/templates/database/__tests__/member-area.db.test.ts +0 -257
- package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
- package/templates/database/__tests__/member-contract.db.test.ts +0 -413
- package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
- package/templates/database/__tests__/offerings-migration.test.ts +0 -197
- package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
- package/templates/database/__tests__/offerings.db.test.ts +0 -303
- package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
- package/templates/database/__tests__/person-contact.db.test.ts +0 -563
- package/templates/database/__tests__/person-notes.db.test.ts +0 -249
- package/templates/database/__tests__/person.db.test.ts +0 -586
- package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
- package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
- package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
- package/templates/database/__tests__/seed.test.ts +0 -272
- package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
- package/templates/database/__tests__/tenancy.test.ts +0 -141
- package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
- package/templates/database/__tests__/user-cascade.test.ts +0 -140
- package/templates/database/_gitignore +0 -8
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/auth/schema.prisma +0 -641
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/config/schema.prisma +0 -441
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/content/schema.prisma +0 -339
- package/templates/database/eslint.config.mjs +0 -69
- package/templates/database/flows/listing-diagnostic.ts +0 -182
- package/templates/database/flows/presets.ts +0 -315
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +0 -3
- package/templates/database/inbox/__tests__/schema.test.ts +0 -44
- package/templates/database/inbox/schema.prisma +0 -1447
- package/templates/database/jest.config.cjs +0 -36
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
- package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
- package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
- package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
- package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
- package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
- package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
- package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
- package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
- package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
- package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
- package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
- package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
- package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
- package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
- package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
- package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
- package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
- package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
- package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
- package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
- package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
- package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
- package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
- package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
- package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
- package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
- package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
- package/templates/database/migrations/migration_lock.toml +0 -3
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/ops/schema.prisma +0 -43
- package/templates/database/package.json +0 -89
- package/templates/database/schema.prisma +0 -71
- package/templates/database/scripts/db-generate-locked.sh +0 -80
- package/templates/database/scripts/person-backfill.sql +0 -132
- package/templates/database/tenancy.ts +0 -183
- package/templates/database/tsconfig.build.json +0 -16
- package/templates/database/tsconfig.flows.json +0 -15
- package/templates/database/tsconfig.json +0 -16
- package/templates/database/tsconfig.tenancy.json +0 -14
|
@@ -16,13 +16,22 @@
|
|
|
16
16
|
* so the transaction client Better Auth's
|
|
17
17
|
* sign-up transaction runs on is reachable
|
|
18
18
|
* from a database hook.
|
|
19
|
-
* signUpAgreementHooks()
|
|
19
|
+
* signUpAgreementHooks() three database hooks: the user hook decides
|
|
20
20
|
* whether this request's new user carries
|
|
21
21
|
* agreements; the account hook writes one
|
|
22
22
|
* `sign_up` grant per agreement on the
|
|
23
23
|
* captured transaction client, so the User,
|
|
24
24
|
* its Account and the grants commit together
|
|
25
|
-
* or not at all (NFR1)
|
|
25
|
+
* or not at all (NFR1); the session hook does
|
|
26
|
+
* the same for a magic-link sign-up, which
|
|
27
|
+
* has no Account (#9667 D5).
|
|
28
|
+
*
|
|
29
|
+
* THE MAGIC LINK (#9667). A request to `/sign-in/magic-link` whose `metadata`
|
|
30
|
+
* carries the agreements is a sign-up request: the plugin refuses it before
|
|
31
|
+
* the handler, `lib/auth-email.ts`'s callback binds the accepted agreements
|
|
32
|
+
* to the token (a verification row keyed on the token's hash), and the
|
|
33
|
+
* verify creates a user only for a token whose binding still covers the
|
|
34
|
+
* evidence.
|
|
26
35
|
*
|
|
27
36
|
* THE EVIDENCE IS THE API'S. Each grant's statement, hash and version come
|
|
28
37
|
* from `GET /v1/consent/sign-up` — built by the same functions `apps/api`'s
|
|
@@ -56,6 +65,7 @@
|
|
|
56
65
|
*/
|
|
57
66
|
|
|
58
67
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
68
|
+
import { createHash } from "node:crypto";
|
|
59
69
|
|
|
60
70
|
import { consent } from "@working-theory/api-client";
|
|
61
71
|
import {
|
|
@@ -70,6 +80,8 @@ import { isSignUpOpen } from "./auth-env";
|
|
|
70
80
|
|
|
71
81
|
const SIGN_UP_PATH = "/sign-up/email";
|
|
72
82
|
const CALLBACK_PREFIX = "/callback/";
|
|
83
|
+
const MAGIC_LINK_PATH = "/sign-in/magic-link";
|
|
84
|
+
const MAGIC_LINK_VERIFY_PATH = "/magic-link/verify";
|
|
73
85
|
const DEFAULT_LOCALE = "en";
|
|
74
86
|
const FRESH_MS = 60_000;
|
|
75
87
|
const STALE_MS = 10 * 60_000;
|
|
@@ -179,7 +191,7 @@ function coversEvidence(
|
|
|
179
191
|
|
|
180
192
|
async function apiError(
|
|
181
193
|
status: "BAD_REQUEST" | "SERVICE_UNAVAILABLE",
|
|
182
|
-
code: "AGREEMENTS_REQUIRED" | "AGREEMENTS_UNAVAILABLE",
|
|
194
|
+
code: "AGREEMENTS_REQUIRED" | "AGREEMENTS_UNAVAILABLE" | "SIGN_UP_CLOSED",
|
|
183
195
|
message: string,
|
|
184
196
|
): Promise<Error> {
|
|
185
197
|
const { APIError } = await import("better-auth/api");
|
|
@@ -200,6 +212,18 @@ const agreementsUnavailable = (): Promise<Error> =>
|
|
|
200
212
|
"The sign-up agreements could not be read. Try again in a moment.",
|
|
201
213
|
);
|
|
202
214
|
|
|
215
|
+
const warn = (fields: Record<string, unknown>): void =>
|
|
216
|
+
console.warn(
|
|
217
|
+
`[sign-up-agreements] ${JSON.stringify({ kind: "magic-link", ...fields })}`,
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const signUpClosed = (): Promise<Error> =>
|
|
221
|
+
apiError(
|
|
222
|
+
"BAD_REQUEST",
|
|
223
|
+
"SIGN_UP_CLOSED",
|
|
224
|
+
"Public sign-up is not open on this site.",
|
|
225
|
+
);
|
|
226
|
+
|
|
203
227
|
/** A request body, as the hooks see it: never trusted, read by key. */
|
|
204
228
|
function bodyField(body: unknown, key: string): unknown {
|
|
205
229
|
return typeof body === "object" && body !== null
|
|
@@ -207,12 +231,121 @@ function bodyField(body: unknown, key: string): unknown {
|
|
|
207
231
|
: undefined;
|
|
208
232
|
}
|
|
209
233
|
|
|
234
|
+
/**
|
|
235
|
+
* A magic-link request's `metadata` when it is a sign-up request — one that
|
|
236
|
+
* carries the agreements key (#9667 D2) — else `null`. Every `/sign-in`
|
|
237
|
+
* request, and the `(authed)` gate's, sends none.
|
|
238
|
+
*/
|
|
239
|
+
export function signUpMetadata(body: unknown): object | null {
|
|
240
|
+
const metadata = bodyField(body, "metadata");
|
|
241
|
+
return typeof metadata === "object" &&
|
|
242
|
+
metadata !== null &&
|
|
243
|
+
SIGN_UP_AGREEMENTS_FIELD in metadata
|
|
244
|
+
? metadata
|
|
245
|
+
: null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ── #9667 D4 — the magic link's agreements binding ──────────────────────────
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The internal-adapter call the binding makes; Better Auth's satisfies it.
|
|
252
|
+
* Optional, so a sign-in-only double needs none — a binding on one fails.
|
|
253
|
+
*/
|
|
254
|
+
export interface LinkAgreementsStore {
|
|
255
|
+
createVerificationValue?(data: {
|
|
256
|
+
identifier: string;
|
|
257
|
+
value: string;
|
|
258
|
+
expiresAt: Date;
|
|
259
|
+
}): Promise<unknown>;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
interface LinkAgreementsReader {
|
|
263
|
+
findVerificationValue(
|
|
264
|
+
identifier: string,
|
|
265
|
+
): Promise<{ value: string; expiresAt: Date } | null>;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface LinkAgreements {
|
|
269
|
+
agreements: string[];
|
|
270
|
+
locale: string;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* The binding's identifier: SHA-256 of the token, base64url — never the token
|
|
275
|
+
* itself, so reading the table yields no live credential (the property
|
|
276
|
+
* `storeToken: "hashed"` gives the token row).
|
|
277
|
+
*/
|
|
278
|
+
export function linkAgreementsIdentifier(token: string): string {
|
|
279
|
+
return `sign-up-agreements:${createHash("sha256").update(token).digest("base64url")}`;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const isStringArray = (raw: unknown): raw is string[] =>
|
|
283
|
+
Array.isArray(raw) && raw.every((item) => typeof item === "string");
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Binds a sign-up request's agreements to its token, server-side. Called by
|
|
287
|
+
* `sendMagicLink` only after the plugin below accepted the request, so
|
|
288
|
+
* nothing in a URL or a later request can create or change it. It expires
|
|
289
|
+
* with the token. Returns what it wrote, which the sign-up email names
|
|
290
|
+
* (#9720 D6).
|
|
291
|
+
*/
|
|
292
|
+
export async function bindLinkAgreements(
|
|
293
|
+
store: LinkAgreementsStore,
|
|
294
|
+
token: string,
|
|
295
|
+
metadata: object,
|
|
296
|
+
ttlSeconds: number,
|
|
297
|
+
): Promise<LinkAgreements> {
|
|
298
|
+
if (!store.createVerificationValue) throw new Error("no verification store");
|
|
299
|
+
const agreements = bodyField(metadata, SIGN_UP_AGREEMENTS_FIELD);
|
|
300
|
+
const binding: LinkAgreements = {
|
|
301
|
+
agreements: isStringArray(agreements) ? agreements : [],
|
|
302
|
+
locale: normaliseLocale(bodyField(metadata, "locale")),
|
|
303
|
+
};
|
|
304
|
+
await store.createVerificationValue({
|
|
305
|
+
identifier: linkAgreementsIdentifier(token),
|
|
306
|
+
value: JSON.stringify(binding),
|
|
307
|
+
expiresAt: new Date(Date.now() + ttlSeconds * 1000),
|
|
308
|
+
});
|
|
309
|
+
return binding;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* The binding for `token`, or `null` when there is none, it has expired
|
|
314
|
+
* (`findVerificationValue` returns expired rows) or its value is malformed.
|
|
315
|
+
* An empty `agreements` array is a valid binding. A failed store read
|
|
316
|
+
* rejects, so the verify can tell it from a missing binding.
|
|
317
|
+
*/
|
|
318
|
+
async function readLinkAgreements(
|
|
319
|
+
token: unknown,
|
|
320
|
+
store: LinkAgreementsReader,
|
|
321
|
+
): Promise<LinkAgreements | null> {
|
|
322
|
+
if (typeof token !== "string" || token.length === 0) return null;
|
|
323
|
+
const row = await store.findVerificationValue(
|
|
324
|
+
linkAgreementsIdentifier(token),
|
|
325
|
+
);
|
|
326
|
+
if (!row || new Date(row.expiresAt).getTime() <= Date.now()) return null;
|
|
327
|
+
let value: unknown;
|
|
328
|
+
try {
|
|
329
|
+
value = JSON.parse(row.value);
|
|
330
|
+
} catch {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
const agreements = bodyField(value, "agreements");
|
|
334
|
+
const locale = bodyField(value, "locale");
|
|
335
|
+
return isStringArray(agreements) && typeof locale === "string"
|
|
336
|
+
? { agreements, locale }
|
|
337
|
+
: null;
|
|
338
|
+
}
|
|
339
|
+
|
|
210
340
|
// ── D3 — the plugin ─────────────────────────────────────────────────────────
|
|
211
341
|
|
|
212
342
|
/**
|
|
213
343
|
* Refuses `POST /sign-up/email` without the agreements (D3), and warms the
|
|
214
344
|
* evidence cache on the OAuth callback so the user hook below finds it
|
|
215
|
-
* without a network call inside the transaction (SEC-8765-I).
|
|
345
|
+
* without a network call inside the transaction (SEC-8765-I). The same two
|
|
346
|
+
* jobs for the magic link (#9667 D3, D5): a sign-up request to
|
|
347
|
+
* `/sign-in/magic-link` is refused before the handler mints a token or looks
|
|
348
|
+
* the address up, and `/magic-link/verify` warms the cache.
|
|
216
349
|
*/
|
|
217
350
|
export function signUpAgreementsPlugin(): BetterAuthPlugin {
|
|
218
351
|
return {
|
|
@@ -254,6 +387,40 @@ export function signUpAgreementsPlugin(): BetterAuthPlugin {
|
|
|
254
387
|
);
|
|
255
388
|
},
|
|
256
389
|
},
|
|
390
|
+
{
|
|
391
|
+
matcher: (context) => context.path === MAGIC_LINK_PATH,
|
|
392
|
+
// A sign-in request is never refused here. A sign-up request is
|
|
393
|
+
// refused on configuration alone, then on the evidence — all
|
|
394
|
+
// before the handler, so no answer depends on the address.
|
|
395
|
+
handler: async (context) => {
|
|
396
|
+
const metadata = signUpMetadata(context.body);
|
|
397
|
+
if (!metadata) return;
|
|
398
|
+
if (!isSignUpOpen()) throw await signUpClosed();
|
|
399
|
+
const evidence = await readEvidence(
|
|
400
|
+
normaliseLocale(bodyField(metadata, "locale")),
|
|
401
|
+
);
|
|
402
|
+
if (!evidence) throw await agreementsUnavailable();
|
|
403
|
+
if (
|
|
404
|
+
evidence.agreements.length > 0 &&
|
|
405
|
+
!coversEvidence(
|
|
406
|
+
bodyField(metadata, SIGN_UP_AGREEMENTS_FIELD),
|
|
407
|
+
evidence,
|
|
408
|
+
)
|
|
409
|
+
) {
|
|
410
|
+
throw await agreementsRequired();
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
matcher: (context) => context.path === MAGIC_LINK_VERIFY_PATH,
|
|
416
|
+
// Warms only, as the callback hook does. Never refuses.
|
|
417
|
+
handler: async () => {
|
|
418
|
+
if (!isSignUpOpen()) return;
|
|
419
|
+
await Promise.all(
|
|
420
|
+
enabledLocales().map((locale) => readEvidence(locale)),
|
|
421
|
+
);
|
|
422
|
+
},
|
|
423
|
+
},
|
|
257
424
|
],
|
|
258
425
|
},
|
|
259
426
|
};
|
|
@@ -347,6 +514,61 @@ type HookContext = Parameters<
|
|
|
347
514
|
>
|
|
348
515
|
>[1];
|
|
349
516
|
|
|
517
|
+
/**
|
|
518
|
+
* A refused magic-link verify: the redirect the plugin's own
|
|
519
|
+
* `redirectWithError` builds — the request's `errorCallbackURL`, else its
|
|
520
|
+
* `callbackURL`, else `/`, against the base URL, with `error=<code>`. The
|
|
521
|
+
* plugin's origin check has already vetted both URLs.
|
|
522
|
+
*/
|
|
523
|
+
function verifyRefusal(
|
|
524
|
+
context: NonNullable<HookContext>,
|
|
525
|
+
code: string,
|
|
526
|
+
): unknown {
|
|
527
|
+
const raw =
|
|
528
|
+
bodyField(context.query, "errorCallbackURL") ??
|
|
529
|
+
bodyField(context.query, "callbackURL");
|
|
530
|
+
const url = new URL(
|
|
531
|
+
typeof raw === "string" ? decodeURIComponent(raw) : "/",
|
|
532
|
+
context.context.baseURL,
|
|
533
|
+
);
|
|
534
|
+
url.searchParams.set("error", code);
|
|
535
|
+
return context.redirect(url.toString());
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Writes one `sign_up` grant per agreement for `subjectId`, field-for-field
|
|
540
|
+
* from the evidence, on the transaction client captured for this call. No
|
|
541
|
+
* captured client fails closed: the user is not created without its grants.
|
|
542
|
+
*/
|
|
543
|
+
async function writeGrants(
|
|
544
|
+
evidence: ConsentSignUpResponse,
|
|
545
|
+
subjectId: string,
|
|
546
|
+
): Promise<void> {
|
|
547
|
+
const tx = capturedTx.getStore();
|
|
548
|
+
if (!isConsentGrantWriter(tx)) {
|
|
549
|
+
throw new Error(
|
|
550
|
+
"sign-up agreements: no transaction client captured; refusing to create the user without its grants",
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
await tx.consentGrant.createMany({
|
|
554
|
+
data: evidence.agreements.map((agreement) => ({
|
|
555
|
+
siteId: evidence.workspaceId,
|
|
556
|
+
workspaceId: evidence.workspaceId,
|
|
557
|
+
subjectType: "user",
|
|
558
|
+
subjectId,
|
|
559
|
+
personId: null,
|
|
560
|
+
purposeId: agreement.purposeId,
|
|
561
|
+
granted: true,
|
|
562
|
+
source: "sign_up",
|
|
563
|
+
sourceRef: null,
|
|
564
|
+
policyVersion: agreement.policyVersion,
|
|
565
|
+
locale: agreement.locale,
|
|
566
|
+
statement: agreement.statement,
|
|
567
|
+
statementHash: agreement.statementHash,
|
|
568
|
+
})),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
350
572
|
/**
|
|
351
573
|
* The evidence the user being created agreed to, or `null` when none is to be
|
|
352
574
|
* recorded. Reads the cache only — the transaction is already open.
|
|
@@ -377,6 +599,29 @@ async function agreedEvidence(
|
|
|
377
599
|
return evidence;
|
|
378
600
|
}
|
|
379
601
|
|
|
602
|
+
if (path === MAGIC_LINK_VERIFY_PATH) {
|
|
603
|
+
// The plugin creates a user only for an address with none (#9667 D5).
|
|
604
|
+
if (!isSignUpOpen())
|
|
605
|
+
throw verifyRefusal(context, "new_user_signup_disabled");
|
|
606
|
+
const binding = await readLinkAgreements(
|
|
607
|
+
bodyField(context.query, "token"),
|
|
608
|
+
context.context.internalAdapter,
|
|
609
|
+
).catch(() => {
|
|
610
|
+
throw verifyRefusal(context, "AGREEMENTS_UNAVAILABLE");
|
|
611
|
+
});
|
|
612
|
+
const evidence = cachedEvidence(normaliseLocale(binding?.locale));
|
|
613
|
+
if (!evidence) throw verifyRefusal(context, "AGREEMENTS_UNAVAILABLE");
|
|
614
|
+
// Every creation needs a sign-up request behind it, so a sign-in
|
|
615
|
+
// request's token never becomes an account.
|
|
616
|
+
if (!binding) throw verifyRefusal(context, "AGREEMENTS_REQUIRED");
|
|
617
|
+
if (evidence.agreements.length === 0) return null;
|
|
618
|
+
// Checked against the evidence now, not the evidence at request time.
|
|
619
|
+
if (!coversEvidence(binding.agreements, evidence)) {
|
|
620
|
+
throw verifyRefusal(context, "AGREEMENTS_REQUIRED");
|
|
621
|
+
}
|
|
622
|
+
return evidence;
|
|
623
|
+
}
|
|
624
|
+
|
|
380
625
|
if (path.startsWith(CALLBACK_PREFIX)) {
|
|
381
626
|
const { getOAuthState } = await import("better-auth/api");
|
|
382
627
|
const state: unknown = await getOAuthState().catch(() => null);
|
|
@@ -393,9 +638,16 @@ async function agreedEvidence(
|
|
|
393
638
|
}
|
|
394
639
|
|
|
395
640
|
/**
|
|
396
|
-
* The
|
|
397
|
-
*
|
|
398
|
-
*
|
|
641
|
+
* The database hooks (D4). They share one request's context object — Better
|
|
642
|
+
* Auth hands each the endpoint context it runs the handler in — and that
|
|
643
|
+
* object keys the `WeakMap` between them.
|
|
644
|
+
*
|
|
645
|
+
* The magic-link verify creates no Account row and no transaction around its
|
|
646
|
+
* user (better-auth 1.6.22), so its grants are written by the session hook
|
|
647
|
+
* (#9667 D5): after the user insert, before the session row and cookie exist,
|
|
648
|
+
* in a transaction of their own, and the user is deleted if that write fails.
|
|
649
|
+
* Not one transaction — a crash between the two inserts leaves a user with no
|
|
650
|
+
* grant and no session, whom the account interstitial stops (SEC-8765-C).
|
|
399
651
|
*/
|
|
400
652
|
export function signUpAgreementHooks(): DatabaseHooks {
|
|
401
653
|
const pending = new WeakMap<object, ConsentSignUpResponse>();
|
|
@@ -419,29 +671,40 @@ export function signUpAgreementHooks(): DatabaseHooks {
|
|
|
419
671
|
const evidence = pending.get(context);
|
|
420
672
|
if (!evidence) return;
|
|
421
673
|
pending.delete(context);
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
674
|
+
await writeGrants(evidence, account.userId);
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
session: {
|
|
679
|
+
create: {
|
|
680
|
+
// Set only by the magic-link verify's user hook, for a new user.
|
|
681
|
+
before: async (session, context) => {
|
|
682
|
+
if (!context || context.path !== MAGIC_LINK_VERIFY_PATH) return;
|
|
683
|
+
const evidence = pending.get(context);
|
|
684
|
+
if (!evidence) return;
|
|
685
|
+
pending.delete(context);
|
|
686
|
+
const { adapter, internalAdapter } = context.context;
|
|
687
|
+
try {
|
|
688
|
+
await adapter.transaction(() =>
|
|
689
|
+
writeGrants(evidence, session.userId),
|
|
426
690
|
);
|
|
691
|
+
} catch {
|
|
692
|
+
// Fields only — never the address or the token.
|
|
693
|
+
warn({ reason: "grant_write_failed" });
|
|
694
|
+
await internalAdapter.deleteUser(session.userId).catch(() => {
|
|
695
|
+
warn({
|
|
696
|
+
reason: "grant_write_failed",
|
|
697
|
+
errorKind: "delete_user_failed",
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
throw verifyRefusal(context, "AGREEMENTS_UNAVAILABLE");
|
|
701
|
+
}
|
|
702
|
+
const token = bodyField(context.query, "token");
|
|
703
|
+
if (typeof token === "string") {
|
|
704
|
+
await internalAdapter
|
|
705
|
+
.deleteVerificationByIdentifier(linkAgreementsIdentifier(token))
|
|
706
|
+
.catch(() => {});
|
|
427
707
|
}
|
|
428
|
-
await tx.consentGrant.createMany({
|
|
429
|
-
data: evidence.agreements.map((agreement) => ({
|
|
430
|
-
siteId: evidence.workspaceId,
|
|
431
|
-
workspaceId: evidence.workspaceId,
|
|
432
|
-
subjectType: "user",
|
|
433
|
-
subjectId: account.userId,
|
|
434
|
-
personId: null,
|
|
435
|
-
purposeId: agreement.purposeId,
|
|
436
|
-
granted: true,
|
|
437
|
-
source: "sign_up",
|
|
438
|
-
sourceRef: null,
|
|
439
|
-
policyVersion: agreement.policyVersion,
|
|
440
|
-
locale: agreement.locale,
|
|
441
|
-
statement: agreement.statement,
|
|
442
|
-
statementHash: agreement.statementHash,
|
|
443
|
-
})),
|
|
444
|
-
});
|
|
445
708
|
},
|
|
446
709
|
},
|
|
447
710
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// site-contributions.ts — what this site adds to its own account area (#9401 D7).
|
|
2
|
+
//
|
|
3
|
+
// This file is the site's, not the template's. AILK ships it empty and never
|
|
4
|
+
// changes its bytes, so `create-ailk update` meets a site's edit of it as
|
|
5
|
+
// "edited, template unchanged" and leaves that edit alone on every run. Record
|
|
6
|
+
// the edit in `customizations.yaml` (the template guard refuses an edit to an
|
|
7
|
+
// untouched template file the manifest does not name), and keep the section's
|
|
8
|
+
// own code in files the site adds beside it.
|
|
9
|
+
//
|
|
10
|
+
// A module contributes through `account-config.ts`; a site contributes here.
|
|
11
|
+
// The Billing page renders these sections after the modules' own. A section's
|
|
12
|
+
// title is a message key, resolved through `ctx.t`; put the site's strings in
|
|
13
|
+
// `messages/site/<locale>.json`, which the request config merges add-only.
|
|
14
|
+
|
|
15
|
+
import type { AccountBillingSection } from "@working-theory/templates/account";
|
|
16
|
+
|
|
17
|
+
/** Billing-page sections this site adds after the modules' sections. */
|
|
18
|
+
export const siteBillingSections: AccountBillingSection[] = [];
|