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
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public-read site resolution — which workspace an UNAUTHENTICATED public
|
|
3
|
-
* request serves (#5852, roadmap D4 read half; spokes #7532).
|
|
4
|
-
*
|
|
5
|
-
* THE GUARD MODEL IS FAIL-CLOSED. Two branches yield a workspace, and no
|
|
6
|
-
* other:
|
|
7
|
-
*
|
|
8
|
-
* 1. A REGISTERED SPOKE (#7532, `resolveCallerSite` below). A spoke is a
|
|
9
|
-
* separately deployed site calling this hub server-to-server with its
|
|
10
|
-
* hub-minted key in ONE header, `x-ailk-spoke-key`. The key is looked up
|
|
11
|
-
* by its SHA-256 digest in the hub's registry (`lib/spoke-store.ts`);
|
|
12
|
-
* the matching unrevoked row's workspace is the answer. A key that is
|
|
13
|
-
* malformed, unknown or revoked resolves to NOTHING — never to the
|
|
14
|
-
* alias, never to the default workspace. So does a keyless call on a
|
|
15
|
-
* hub (#7633).
|
|
16
|
-
* 2. An unambiguously one-workspace deployment, answered by the same
|
|
17
|
-
* predicate the authenticated path uses
|
|
18
|
-
* (`services/default-tenant.ts#resolveDefaultWorkspaceId`) — one
|
|
19
|
-
* predicate, reached two ways, never two predicates. Zero workspaces,
|
|
20
|
-
* two or more, or a sole workspace that is not the seeded default all
|
|
21
|
-
* resolve to `unresolved`, and the caller answers 404 before any content
|
|
22
|
-
* query runs. A header-less request takes this branch exactly as it did
|
|
23
|
-
* before spokes existed — but only on a deployment that is not a hub.
|
|
24
|
-
* A hub is a deployment whose spoke registry holds a row, revoked or
|
|
25
|
-
* not (#7633 D1); there a header-less request is refused exactly as an
|
|
26
|
-
* unknown key is, with no switch set. `AILK_HUB_REQUIRE_SPOKE_KEY`
|
|
27
|
-
* `true` refuses it even with an empty registry; `false` is an
|
|
28
|
-
* emergency opt-out that keeps the keyless answer (#7633 D2).
|
|
29
|
-
*
|
|
30
|
-
* IT READS NO HOST. `request.hostname` resolves from `X-Forwarded-Host` under
|
|
31
|
-
* this server's `trustProxy: true` (`server.ts`), which is caller-suppliable
|
|
32
|
-
* and therefore not a tenancy input; `Origin` is client-supplied outside a
|
|
33
|
-
* browser. The one header read here is the spoke key, and a key selects
|
|
34
|
-
* nothing by itself: only the server-side registry row it digests to does.
|
|
35
|
-
*
|
|
36
|
-
* THE CLIENT NEVER SUPPLIES A WORKSPACE. No path parameter, query string,
|
|
37
|
-
* header or body field naming a workspace is read here, on any request. That
|
|
38
|
-
* is roadmap D4's own STOP boundary, not a default.
|
|
39
|
-
*
|
|
40
|
-
* A HEADER-LESS REQUEST LOADS AT MOST ONE READ. With no `DATABASE_URL`, or
|
|
41
|
-
* the flag `false`, the keyless branch reads nothing and imports nothing
|
|
42
|
-
* (#7532 NFR1, #7633 NFR1); off the database adapter the function then
|
|
43
|
-
* returns `not-required` having issued no query and loaded no database
|
|
44
|
-
* module — which is what keeps the no-`DATABASE_URL` scaffold starting.
|
|
45
|
-
* Otherwise it reads the registry ("is this a hub") until it sees a row,
|
|
46
|
-
* holding a "no" for 30 seconds (requests that miss together may each read
|
|
47
|
-
* once) and a "yes" for the life of the process (#7633 D3). The registry
|
|
48
|
-
* module is imported on first use.
|
|
49
|
-
*
|
|
50
|
-
* A FAILED READ (#7633, conductor amendment to NFR3 on the operator's rule
|
|
51
|
-
* that lead capture is never lost). A process that has seen a hub never reads
|
|
52
|
-
* again, so it keeps refusing keyless calls through an outage. Otherwise:
|
|
53
|
-
* with a previous successful "not a hub" the process reuses it, on every
|
|
54
|
-
* route; with none (a cold start during an outage) only the three lead
|
|
55
|
-
* writes, which pass `keylessOnRegistryFailure: "anonymous"`, proceed as on a
|
|
56
|
-
* non-hub, so `routeLead`'s own outage fallback captures the lead. Every
|
|
57
|
-
* other keyless call rejects. Each such failure is logged at error, without
|
|
58
|
-
* the error's message.
|
|
59
|
-
*
|
|
60
|
-
* NO SECRET IS LOGGED. A refusal reaches `request.log.warn` as `{ reason }`
|
|
61
|
-
* (plus `spokeId` for a matched row) — never the key, its digest or its
|
|
62
|
-
* prefix — and never reaches the wire.
|
|
63
|
-
*
|
|
64
|
-
* THE FLOWS ROUTES' WORKSPACE (#7844 D1). `resolveCallerWorkspace` below is
|
|
65
|
-
* the one function the five `/v1/flows` routes (and the open deliverable)
|
|
66
|
-
* resolve their workspace with: a spoke resolves to its own workspace
|
|
67
|
-
* (`viaSpoke: true`), a keyless call through branch 2's one-workspace
|
|
68
|
-
* predicate (#9145 — never the `AILK_SITE_ID` alias, so every anonymous
|
|
69
|
-
* route answers the same workspace for the same deployment), and anything
|
|
70
|
-
* else to `unresolved` with one of two reasons, `spoke-refused` or
|
|
71
|
-
* `ambiguous`. The reasons are for `request.log` only; the routes answer both
|
|
72
|
-
* the same way. It lives here rather than under `routes/flows/` because the
|
|
73
|
-
* two flows route files sit in different module slices, and this file is
|
|
74
|
-
* base tree.
|
|
75
|
-
*/
|
|
76
|
-
import {
|
|
77
|
-
resolvedAdapterKind,
|
|
78
|
-
type ArtifactPrismaClient,
|
|
79
|
-
type ContentAdapter,
|
|
80
|
-
} from "@working-theory/content-adapters";
|
|
81
|
-
import type { FastifyRequest } from "fastify";
|
|
82
|
-
|
|
83
|
-
import { config } from "../config/index.js";
|
|
84
|
-
import { getContentAdapter } from "../lib/content-adapter.js";
|
|
85
|
-
|
|
86
|
-
/** The one request header a spoke names itself with (#7532 D2). */
|
|
87
|
-
const SPOKE_KEY_HEADER = "x-ailk-spoke-key";
|
|
88
|
-
|
|
89
|
-
/** The longest key the hub will hash; a minted key is 52 characters. */
|
|
90
|
-
const SPOKE_KEY_MAX_LENGTH = 128;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Visible ASCII only — the class the visitor-forward key already uses
|
|
94
|
-
* (`packages/api-client` `SAFE_HEADER_TOKEN`; `apps/api` cannot import that
|
|
95
|
-
* package, so this is its own constant). It also refuses the `"a, b"` string
|
|
96
|
-
* Node makes of a duplicated header, because of the space.
|
|
97
|
-
*/
|
|
98
|
-
const SAFE_SPOKE_KEY = /^[\x21-\x7e]+$/;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Who is calling a spoke-aware public surface (#7532 D3).
|
|
102
|
-
*
|
|
103
|
-
* anonymous — no spoke key on a deployment that is not a hub (or the
|
|
104
|
-
* emergency opt-out): resolve exactly as before.
|
|
105
|
-
* spoke — a registered, unrevoked spoke; its workspace is the answer.
|
|
106
|
-
* refused — resolve to NOTHING. `reason` is for `request.log` only.
|
|
107
|
-
*/
|
|
108
|
-
export type CallerSite =
|
|
109
|
-
| { kind: "anonymous" }
|
|
110
|
-
| { kind: "spoke"; spokeId: string; workspaceId: string }
|
|
111
|
-
| {
|
|
112
|
-
kind: "refused";
|
|
113
|
-
reason:
|
|
114
|
-
| "key-required"
|
|
115
|
-
| "key-malformed"
|
|
116
|
-
| "no-database"
|
|
117
|
-
| "key-unknown"
|
|
118
|
-
| "key-revoked";
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
function refuse(
|
|
122
|
-
request: FastifyRequest,
|
|
123
|
-
reason: Extract<CallerSite, { kind: "refused" }>["reason"],
|
|
124
|
-
spokeId?: string,
|
|
125
|
-
): CallerSite {
|
|
126
|
-
request.log.warn(
|
|
127
|
-
spokeId === undefined ? { reason } : { reason, spokeId },
|
|
128
|
-
"[spoke] caller refused",
|
|
129
|
-
);
|
|
130
|
-
return { kind: "refused", reason };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/** How long a "not a hub" answer is held (#7633 D3). */
|
|
134
|
-
const NOT_A_HUB_TTL_MS = 30_000;
|
|
135
|
-
/** Set once the registry has shown a row; never cleared in-process. */
|
|
136
|
-
let hubSeen = false;
|
|
137
|
-
/** Until when a "not a hub" answer stands (epoch ms). */
|
|
138
|
-
let notAHubUntil = 0;
|
|
139
|
-
/** Set once a read has answered "not a hub"; what a failed read reuses. */
|
|
140
|
-
let notAHubSeen = false;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* What a keyless call gets when the hub-status read fails and the process
|
|
144
|
-
* holds no previous answer (#7633 conductor amendment). `"reject"`, the
|
|
145
|
-
* default, lets the error reach the route; `"anonymous"` is for the three
|
|
146
|
-
* lead writes only, so a lead reaches `routeLead`'s outage fallback.
|
|
147
|
-
*/
|
|
148
|
-
export interface ResolveCallerOptions {
|
|
149
|
-
keylessOnRegistryFailure?: "reject" | "anonymous";
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** Whether a keyless call must be refused (#7633 D2, D3). */
|
|
153
|
-
async function hubRequiresKey(
|
|
154
|
-
request: FastifyRequest,
|
|
155
|
-
onFailure: "reject" | "anonymous",
|
|
156
|
-
): Promise<boolean> {
|
|
157
|
-
const mode = config.AILK_HUB_REQUIRE_SPOKE_KEY;
|
|
158
|
-
if (mode === "off") return false;
|
|
159
|
-
// Anything but the automatic default refuses: "on", and any value the
|
|
160
|
-
// parser should never have let through (NFR5).
|
|
161
|
-
if (mode !== "auto") return true;
|
|
162
|
-
// No database, no registry — a single-site deployment (NFR1).
|
|
163
|
-
if (!process.env.DATABASE_URL) return false;
|
|
164
|
-
if (hubSeen) return true;
|
|
165
|
-
if (Date.now() < notAHubUntil) return false;
|
|
166
|
-
let isHub: boolean;
|
|
167
|
-
try {
|
|
168
|
-
const { hasRegisteredSpoke } = await import("../lib/spoke-store.js");
|
|
169
|
-
isHub = await hasRegisteredSpoke();
|
|
170
|
-
} catch (err) {
|
|
171
|
-
// Never held: the next call reads again. The error's own message may
|
|
172
|
-
// name the database, so only its name is logged.
|
|
173
|
-
const fallback = notAHubSeen ? "previous-answer" : onFailure;
|
|
174
|
-
if (fallback === "reject") throw err;
|
|
175
|
-
request.log.error(
|
|
176
|
-
{
|
|
177
|
-
reason: "hub-status-read-failed",
|
|
178
|
-
fallback,
|
|
179
|
-
err: err instanceof Error ? err.name : "unknown",
|
|
180
|
-
},
|
|
181
|
-
"[spoke] hub-status read failed; answering a keyless call as on a non-hub",
|
|
182
|
-
);
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
if (isHub) {
|
|
186
|
-
hubSeen = true;
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
notAHubSeen = true;
|
|
190
|
-
notAHubUntil = Date.now() + NOT_A_HUB_TTL_MS;
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/** Test seam: forget the held answer (as `lib/site.ts` does for its memo). */
|
|
195
|
-
export function __resetHubStatusForTests(): void {
|
|
196
|
-
hubSeen = false;
|
|
197
|
-
notAHubUntil = 0;
|
|
198
|
-
notAHubSeen = false;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Resolve the caller of a spoke-aware public surface. Reads ONE header, the
|
|
203
|
-
* spoke key, and nothing else off the request; see the file header.
|
|
204
|
-
*/
|
|
205
|
-
export async function resolveCallerSite(
|
|
206
|
-
request: FastifyRequest,
|
|
207
|
-
options: ResolveCallerOptions = {},
|
|
208
|
-
): Promise<CallerSite> {
|
|
209
|
-
// Optional chain: a bare `{}` request (the resolver's own suite) is a
|
|
210
|
-
// header-less request.
|
|
211
|
-
const raw: unknown = request.headers?.[SPOKE_KEY_HEADER];
|
|
212
|
-
|
|
213
|
-
if (raw === undefined) {
|
|
214
|
-
return (await hubRequiresKey(
|
|
215
|
-
request,
|
|
216
|
-
options.keylessOnRegistryFailure ?? "reject",
|
|
217
|
-
))
|
|
218
|
-
? refuse(request, "key-required")
|
|
219
|
-
: { kind: "anonymous" };
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// A string[] is refused defensively; Node joins a duplicated custom header
|
|
223
|
-
// into one "a, b" string, which the visible-ASCII test refuses.
|
|
224
|
-
const key = typeof raw === "string" ? raw.trim() : "";
|
|
225
|
-
if (
|
|
226
|
-
key === "" ||
|
|
227
|
-
key.length > SPOKE_KEY_MAX_LENGTH ||
|
|
228
|
-
!SAFE_SPOKE_KEY.test(key)
|
|
229
|
-
) {
|
|
230
|
-
return refuse(request, "key-malformed");
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (!process.env.DATABASE_URL) {
|
|
234
|
-
return refuse(request, "no-database");
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Deferred, like `lib/prisma.js` below: loaded on first use only.
|
|
238
|
-
const { findSpokeByKeyHash, hashSpokeKey } = await import(
|
|
239
|
-
"../lib/spoke-store.js"
|
|
240
|
-
);
|
|
241
|
-
const row = await findSpokeByKeyHash(hashSpokeKey(key));
|
|
242
|
-
if (!row) return refuse(request, "key-unknown");
|
|
243
|
-
if (row.revokedAt !== null) return refuse(request, "key-revoked", row.id);
|
|
244
|
-
return { kind: "spoke", spokeId: row.id, workspaceId: row.workspaceId };
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* The workspace a `/v1/flows` request serves (#7844 D1). `reason` is for
|
|
249
|
-
* `request.log` only; the routes answer both reasons the same way.
|
|
250
|
-
*/
|
|
251
|
-
export type CallerWorkspace =
|
|
252
|
-
| {
|
|
253
|
-
kind: "resolved";
|
|
254
|
-
workspaceId: string;
|
|
255
|
-
viaSpoke: boolean;
|
|
256
|
-
/** #8771 D3 — set exactly when `viaSpoke` is true: the registered spoke's id. */
|
|
257
|
-
spokeId?: string;
|
|
258
|
-
}
|
|
259
|
-
| { kind: "unresolved"; reason: "spoke-refused" | "ambiguous" };
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Resolve the workspace a `/v1/flows` request serves. A spoke resolves to its
|
|
263
|
-
* own workspace; a keyless call through `resolveDefaultWorkspaceId`, the
|
|
264
|
-
* predicate `resolvePublicWorkspace` uses (#9145) — on any content adapter,
|
|
265
|
-
* since a flow is a database row whatever serves the pages; a refused caller
|
|
266
|
-
* to nothing. There is no fallback: a spoke never reaches the default
|
|
267
|
-
* workspace (D5).
|
|
268
|
-
*
|
|
269
|
-
* Calls `resolveCallerSite` with no options, so a failed hub-status read on a
|
|
270
|
-
* keyless call rejects (#7844 C1).
|
|
271
|
-
*/
|
|
272
|
-
export async function resolveCallerWorkspace(
|
|
273
|
-
request: FastifyRequest,
|
|
274
|
-
): Promise<CallerWorkspace> {
|
|
275
|
-
const caller = await resolveCallerSite(request);
|
|
276
|
-
if (caller.kind === "refused") {
|
|
277
|
-
return { kind: "unresolved", reason: "spoke-refused" };
|
|
278
|
-
}
|
|
279
|
-
if (caller.kind === "spoke") {
|
|
280
|
-
return {
|
|
281
|
-
kind: "resolved",
|
|
282
|
-
workspaceId: caller.workspaceId,
|
|
283
|
-
viaSpoke: true,
|
|
284
|
-
spokeId: caller.spokeId,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
// Deferred, like every database import in this file.
|
|
288
|
-
const { resolveDefaultWorkspaceId } = await import("./default-tenant.js");
|
|
289
|
-
const workspaceId = await resolveDefaultWorkspaceId();
|
|
290
|
-
return workspaceId === null
|
|
291
|
-
? { kind: "unresolved", reason: "ambiguous" }
|
|
292
|
-
: { kind: "resolved", workspaceId, viaSpoke: false };
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* The three answers a public read can get. `reason` exists for `request.log`
|
|
297
|
-
* only: the route decides its response from `kind` alone, so no resolution
|
|
298
|
-
* detail reaches an unauthenticated caller (#5852 D7, D8).
|
|
299
|
-
*/
|
|
300
|
-
export type PublicSiteResolution =
|
|
301
|
-
| { kind: "not-required" }
|
|
302
|
-
| { kind: "resolved"; workspaceId: string }
|
|
303
|
-
| {
|
|
304
|
-
kind: "unresolved";
|
|
305
|
-
reason: "ambiguous" | "host-unmatched" | "spoke-refused";
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Resolves the workspace a public read serves, or refuses to.
|
|
310
|
-
*
|
|
311
|
-
* A spoke resolves to its own workspace on any content adapter; a refused
|
|
312
|
-
* caller resolves to nothing; an anonymous caller takes the one-workspace
|
|
313
|
-
* path below, unchanged (#7532 D3).
|
|
314
|
-
*/
|
|
315
|
-
export async function resolvePublicWorkspace(
|
|
316
|
-
request: FastifyRequest,
|
|
317
|
-
): Promise<PublicSiteResolution> {
|
|
318
|
-
const caller = await resolveCallerSite(request);
|
|
319
|
-
if (caller.kind === "refused") {
|
|
320
|
-
return { kind: "unresolved", reason: "spoke-refused" };
|
|
321
|
-
}
|
|
322
|
-
if (caller.kind === "spoke") {
|
|
323
|
-
return { kind: "resolved", workspaceId: caller.workspaceId };
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (resolvedAdapterKind() !== "database") {
|
|
327
|
-
return { kind: "not-required" };
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Deferred — see the module-load note in this file's header (#5852 D6).
|
|
331
|
-
const { resolveDefaultWorkspaceId } = await import("./default-tenant.js");
|
|
332
|
-
const workspaceId = await resolveDefaultWorkspaceId();
|
|
333
|
-
if (workspaceId === null) {
|
|
334
|
-
return { kind: "unresolved", reason: "ambiguous" };
|
|
335
|
-
}
|
|
336
|
-
return { kind: "resolved", workspaceId };
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* The adapter a public content read should use, or `null` when it must refuse.
|
|
341
|
-
*
|
|
342
|
-
* This is the ONE place the three-armed resolution collapses into a decision,
|
|
343
|
-
* so a second public read route cannot grow a second copy of it: `resolved`
|
|
344
|
-
* and `not-required` both yield an adapter, `unresolved` yields `null`. The
|
|
345
|
-
* caller answers `null` with its OWN existing not-found body — which is what
|
|
346
|
-
* keeps a refusal byte-identical to a missing page on `get-page`, and keeps
|
|
347
|
-
* each route's 404 shape its own (#5852 D8). The reason is logged here and
|
|
348
|
-
* never leaves the server.
|
|
349
|
-
*/
|
|
350
|
-
export async function resolvePublicContentAdapter(
|
|
351
|
-
request: FastifyRequest,
|
|
352
|
-
): Promise<ContentAdapter | null> {
|
|
353
|
-
const site = await resolvePublicWorkspace(request);
|
|
354
|
-
if (site.kind === "unresolved") {
|
|
355
|
-
request.log.warn(
|
|
356
|
-
{ reason: site.reason },
|
|
357
|
-
"[Content] no site resolved for public read",
|
|
358
|
-
);
|
|
359
|
-
return null;
|
|
360
|
-
}
|
|
361
|
-
// A spoke on an MDX-adapter hub resolves a workspace (its meeting types are
|
|
362
|
-
// per-workspace), but MDX content is not: it keeps reading the shared
|
|
363
|
-
// source rather than being switched to the database one (#7532 D3).
|
|
364
|
-
if (site.kind === "not-required" || resolvedAdapterKind() !== "database") {
|
|
365
|
-
return getContentAdapter();
|
|
366
|
-
}
|
|
367
|
-
return workspaceContentAdapter(site.workspaceId);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* The content adapter holding ONE workspace's own pages, or `null` when no
|
|
372
|
-
* content is that workspace's (#8514 D9, C13). On the database adapter it is
|
|
373
|
-
* that workspace's database adapter. Off it, the shared content is the
|
|
374
|
-
* deployment's one site — the default workspace's — so only that workspace
|
|
375
|
-
* gets it and every other workspace gets `null`, never the hub's pages
|
|
376
|
-
* (SEC-8514-I). The Admin's plan picker reads its offerings through it.
|
|
377
|
-
*/
|
|
378
|
-
export async function workspaceContentAdapter(
|
|
379
|
-
workspaceId: string,
|
|
380
|
-
): Promise<ContentAdapter | null> {
|
|
381
|
-
if (resolvedAdapterKind() !== "database") {
|
|
382
|
-
// Deferred — see the module-load note in this file's header (#5852 D6).
|
|
383
|
-
const { resolveDefaultWorkspaceId } = await import("./default-tenant.js");
|
|
384
|
-
return (await resolveDefaultWorkspaceId()) === workspaceId ? getContentAdapter() : null;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// The database path, and the only one that needs apps/api's client. The
|
|
388
|
-
// import is deferred for the reason the header gives (#5852 D6), and the
|
|
389
|
-
// generated client is structurally wider than the narrow read surface the
|
|
390
|
-
// adapter declares — the cast names that, and nothing else.
|
|
391
|
-
const { prisma } = await import("../lib/prisma.js");
|
|
392
|
-
return getContentAdapter({
|
|
393
|
-
workspaceId,
|
|
394
|
-
prisma: prisma as unknown as ArtifactPrismaClient,
|
|
395
|
-
});
|
|
396
|
-
}
|