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,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The Stripe-backed Offerings catalog source (#8922, spec
|
|
3
|
-
* docs/specs/8922-the-may-sell-product-list-spec.md D2; contract
|
|
4
|
-
* docs/specs/8879-the-offerings-security-contract-key-spec.md C8, T1, T7) —
|
|
5
|
-
* the `OfferingsSourceFor` the routes pass to the read services: one
|
|
6
|
-
* Organization's active Products and Prices, read through its own
|
|
7
|
-
* connection's client (#8907 D12) and paged to the normalizer's caps.
|
|
8
|
-
*
|
|
9
|
-
* `stripeCatalogSourceFor` does no work when called, so it can never throw
|
|
10
|
-
* outside the services' failure memo (#8876 D8). It takes a bare
|
|
11
|
-
* Organization id and checks neither the tenant nor the claim — its callers
|
|
12
|
-
* do — so `architecture.yaml` confines it to the exact files that call it.
|
|
13
|
-
*
|
|
14
|
-
* BOUNDED (SEC-8922-3). Each list is paged by calls, not items: at most
|
|
15
|
-
* `OFFERINGS_CATALOG_PRODUCTS_MAX / 100` product calls and
|
|
16
|
-
* `OFFERINGS_CATALOG_PRICES_MAX / 100` price calls, stopping early on
|
|
17
|
-
* `has_more: false`, an empty page, a page whose last id repeats the cursor
|
|
18
|
-
* it was asked with, or a full count. The whole read is bounded by
|
|
19
|
-
* `OFFERINGS_CATALOG_READ_TIMEOUT_MS`; after it fails, no further call is
|
|
20
|
-
* started.
|
|
21
|
-
*
|
|
22
|
-
* A list cut off at its cap while Stripe still had more is logged as
|
|
23
|
-
* `catalog_truncated` (SEC-8922-7), with the Organization and nothing else.
|
|
24
|
-
*
|
|
25
|
-
* Nothing is filtered or cached here: the client lives only inside
|
|
26
|
-
* one read (C8), and every field is normalized once by `normalizeCatalog`
|
|
27
|
-
* (T1). A disconnected or unusable connection rejects, never reading as an
|
|
28
|
-
* empty catalog; a Stripe error rejects as itself, and the services turn it
|
|
29
|
-
* into `OfferingsSourceError` without its text.
|
|
30
|
-
*/
|
|
31
|
-
import { logger } from "@working-theory/observability";
|
|
32
|
-
|
|
33
|
-
import {
|
|
34
|
-
OFFERINGS_CATALOG_PRICES_MAX,
|
|
35
|
-
OFFERINGS_CATALOG_PRODUCTS_MAX,
|
|
36
|
-
type OfferingsCatalog,
|
|
37
|
-
type OfferingsCatalogSource,
|
|
38
|
-
} from "./catalog.js";
|
|
39
|
-
import { stripeClientForOrganization } from "./connection.js";
|
|
40
|
-
|
|
41
|
-
import type { OfferingsSourceFor } from "./index.js";
|
|
42
|
-
|
|
43
|
-
/** The longest one catalog read may take, connection lookup included. */
|
|
44
|
-
export const OFFERINGS_CATALOG_READ_TIMEOUT_MS = 20_000;
|
|
45
|
-
|
|
46
|
-
const PAGE_LIMIT = 100;
|
|
47
|
-
|
|
48
|
-
/** No usable connection, or the read timed out. The message is fixed; there is no cause. */
|
|
49
|
-
export class OfferingsCatalogUnavailableError extends Error {
|
|
50
|
-
constructor() {
|
|
51
|
-
super("The Offerings catalog source is unavailable");
|
|
52
|
-
this.name = "OfferingsCatalogUnavailableError";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface ListParams {
|
|
57
|
-
active: true;
|
|
58
|
-
limit: number;
|
|
59
|
-
starting_after?: string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
interface ListPage<T> {
|
|
63
|
-
data: T[];
|
|
64
|
-
has_more: boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* One list paged to `maxItems`, by at most `maxItems / PAGE_LIMIT` calls.
|
|
69
|
-
* `truncated` when the bound stopped it while Stripe still had more.
|
|
70
|
-
*/
|
|
71
|
-
async function pageAll<T extends { id?: unknown }>(
|
|
72
|
-
list: (params: ListParams) => PromiseLike<ListPage<T>>,
|
|
73
|
-
maxItems: number,
|
|
74
|
-
aborted: () => boolean,
|
|
75
|
-
): Promise<{ items: T[]; truncated: boolean }> {
|
|
76
|
-
const items: T[] = [];
|
|
77
|
-
let after: string | undefined;
|
|
78
|
-
for (let call = 0; call < maxItems / PAGE_LIMIT && items.length < maxItems; call++) {
|
|
79
|
-
if (aborted()) throw new OfferingsCatalogUnavailableError();
|
|
80
|
-
const page = await list({
|
|
81
|
-
active: true,
|
|
82
|
-
limit: PAGE_LIMIT,
|
|
83
|
-
...(after !== undefined && { starting_after: after }),
|
|
84
|
-
});
|
|
85
|
-
items.push(...page.data);
|
|
86
|
-
const last = page.data.at(-1)?.id;
|
|
87
|
-
if (!page.has_more || typeof last !== "string" || last === after) return { items, truncated: false };
|
|
88
|
-
after = last;
|
|
89
|
-
}
|
|
90
|
-
return { items, truncated: true };
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** The Organization's catalog source. Builds nothing until it is read. */
|
|
94
|
-
export const stripeCatalogSourceFor: OfferingsSourceFor = (
|
|
95
|
-
organizationId: string,
|
|
96
|
-
): OfferingsCatalogSource => ({
|
|
97
|
-
async listActiveCatalog(): Promise<OfferingsCatalog> {
|
|
98
|
-
let aborted = false;
|
|
99
|
-
const isAborted = () => aborted;
|
|
100
|
-
const read = (async (): Promise<OfferingsCatalog> => {
|
|
101
|
-
const connection = await stripeClientForOrganization(organizationId);
|
|
102
|
-
if (connection.kind !== "ok") throw new OfferingsCatalogUnavailableError();
|
|
103
|
-
const { client } = connection;
|
|
104
|
-
const products = pageAll(
|
|
105
|
-
(params) => client.products.list(params),
|
|
106
|
-
OFFERINGS_CATALOG_PRODUCTS_MAX,
|
|
107
|
-
isAborted,
|
|
108
|
-
);
|
|
109
|
-
const prices = pageAll((params) => client.prices.list(params), OFFERINGS_CATALOG_PRICES_MAX, isAborted);
|
|
110
|
-
// Each loop is caught on its own, so a page that rejects after the
|
|
111
|
-
// other loop or the timeout has failed the read is never unhandled.
|
|
112
|
-
products.catch(() => undefined);
|
|
113
|
-
prices.catch(() => undefined);
|
|
114
|
-
const [productPages, pricePages] = await Promise.all([products, prices]);
|
|
115
|
-
if (productPages.truncated || pricePages.truncated) {
|
|
116
|
-
logger.warn(
|
|
117
|
-
{ organizationId, reason: "catalog_truncated" },
|
|
118
|
-
"[offerings] catalog over its read cap",
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
return { products: productPages.items, prices: pricePages.items };
|
|
122
|
-
})();
|
|
123
|
-
read.catch(() => undefined);
|
|
124
|
-
|
|
125
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
126
|
-
const timeout = new Promise<never>((_resolve, reject) => {
|
|
127
|
-
timer = setTimeout(() => {
|
|
128
|
-
aborted = true;
|
|
129
|
-
reject(new OfferingsCatalogUnavailableError());
|
|
130
|
-
}, OFFERINGS_CATALOG_READ_TIMEOUT_MS);
|
|
131
|
-
});
|
|
132
|
-
try {
|
|
133
|
-
return await Promise.race([read, timeout]);
|
|
134
|
-
} finally {
|
|
135
|
-
clearTimeout(timer);
|
|
136
|
-
// A loop still running after the other one failed starts no more calls.
|
|
137
|
-
aborted = true;
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
});
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The Offerings sets and the snapshot (#8876, spec
|
|
3
|
-
* docs/specs/8876-the-offerings-data-model-typed-spec.md D6) — the one file
|
|
4
|
-
* naming the org-enabled set, the workspace selection and its snapshot, and,
|
|
5
|
-
* for this service, the workspace's Organization.
|
|
6
|
-
*
|
|
7
|
-
* Every argument is a server-resolved id, never a request value, except a
|
|
8
|
-
* set or selection handed to a writer, which its caller checked and the
|
|
9
|
-
* writer parses; and no function lists or enumerates. The selection read
|
|
10
|
-
* never names the snapshot, so checkout's allowlist (contract A4) can never
|
|
11
|
-
* read the display copy.
|
|
12
|
-
*
|
|
13
|
-
* This file writes the snapshot, only into a row that exists; for #8922, the
|
|
14
|
-
* org-enabled set; and, for #8926, the workspace selection and Recommended,
|
|
15
|
-
* creating its row.
|
|
16
|
-
*/
|
|
17
|
-
import {
|
|
18
|
-
offeringsProductIdsSchema,
|
|
19
|
-
workspaceOfferingsSelectionSchema,
|
|
20
|
-
type OfferingsSnapshot,
|
|
21
|
-
} from "@working-theory/validation";
|
|
22
|
-
|
|
23
|
-
import { prisma } from "../../lib/prisma.js";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* An Offerings result, or a set handed to a writer, failed its schema. The
|
|
27
|
-
* message is fixed; there is no cause. Re-exported by `index.ts`.
|
|
28
|
-
*/
|
|
29
|
-
export class OfferingsShapeError extends Error {
|
|
30
|
-
constructor() {
|
|
31
|
-
super("An Offerings result failed its schema");
|
|
32
|
-
this.name = "OfferingsShapeError";
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface WorkspaceSelection {
|
|
37
|
-
shownProductIds: string[];
|
|
38
|
-
/** The shown Prices (#9070 D1); empty for a row saved per Product. */
|
|
39
|
-
shownPriceIds: string[];
|
|
40
|
-
recommendedPlanProductId: string | null;
|
|
41
|
-
recommendedAddonProductId: string | null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface WorkspaceSnapshotRow {
|
|
45
|
-
snapshot: unknown;
|
|
46
|
-
snapshotAt: Date | null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** The workspace's own Organization, or `null` for no workspace. */
|
|
50
|
-
export async function organizationIdOfWorkspace(workspaceId: string): Promise<string | null> {
|
|
51
|
-
const row = await prisma.workspace.findUnique({
|
|
52
|
-
where: { id: workspaceId },
|
|
53
|
-
select: { organizationId: true },
|
|
54
|
-
});
|
|
55
|
-
return row?.organizationId ?? null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** The org-enabled set; no row is the empty set. */
|
|
59
|
-
export async function readEnabledProductIds(organizationId: string): Promise<string[]> {
|
|
60
|
-
const row = await prisma.organizationOfferings.findUnique({
|
|
61
|
-
where: { organizationId },
|
|
62
|
-
select: { enabledProductIds: true },
|
|
63
|
-
});
|
|
64
|
-
return row?.enabledProductIds ?? [];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Replace the org-enabled set (#8922 D4), creating the row on an
|
|
69
|
-
* Organization's first save. Every set is parsed first — at most 100
|
|
70
|
-
* distinct Stripe ids — so the bound holds for every writer.
|
|
71
|
-
*/
|
|
72
|
-
export async function writeEnabledProductIds(organizationId: string, productIds: string[]): Promise<void> {
|
|
73
|
-
const parsed = offeringsProductIdsSchema.safeParse(productIds);
|
|
74
|
-
if (!parsed.success) throw new OfferingsShapeError();
|
|
75
|
-
await prisma.organizationOfferings.upsert({
|
|
76
|
-
where: { organizationId },
|
|
77
|
-
create: { organizationId, enabledProductIds: parsed.data },
|
|
78
|
-
update: { enabledProductIds: parsed.data },
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** The shown set and Recommended, or `null` for no row. Never the snapshot. */
|
|
83
|
-
export async function readWorkspaceSelection(workspaceId: string): Promise<WorkspaceSelection | null> {
|
|
84
|
-
return prisma.workspaceOfferings.findUnique({
|
|
85
|
-
where: { workspaceId },
|
|
86
|
-
select: {
|
|
87
|
-
shownProductIds: true,
|
|
88
|
-
shownPriceIds: true,
|
|
89
|
-
recommendedPlanProductId: true,
|
|
90
|
-
recommendedAddonProductId: true,
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Replace the workspace's selection (#8926 D5), creating the row on its first
|
|
97
|
-
* save. Every selection is parsed first — at most 100 distinct Product ids
|
|
98
|
-
* and 300 Price ids, Prices exactly when Products (#9070 D4), each
|
|
99
|
-
* Recommended shown — so the database's CHECKs never fire and no new save is
|
|
100
|
-
* at the per-Product grain. Never names the snapshot, so a save keeps the
|
|
101
|
-
* last good copy.
|
|
102
|
-
*/
|
|
103
|
-
export async function writeWorkspaceSelection(
|
|
104
|
-
workspaceId: string,
|
|
105
|
-
selection: WorkspaceSelection,
|
|
106
|
-
): Promise<void> {
|
|
107
|
-
const parsed = workspaceOfferingsSelectionSchema.safeParse(selection);
|
|
108
|
-
if (!parsed.success) throw new OfferingsShapeError();
|
|
109
|
-
const { shownProductIds, shownPriceIds, recommendedPlanProductId, recommendedAddonProductId } =
|
|
110
|
-
parsed.data;
|
|
111
|
-
await prisma.workspaceOfferings.upsert({
|
|
112
|
-
where: { workspaceId },
|
|
113
|
-
create: { workspaceId, shownProductIds, shownPriceIds, recommendedPlanProductId, recommendedAddonProductId },
|
|
114
|
-
update: { shownProductIds, shownPriceIds, recommendedPlanProductId, recommendedAddonProductId },
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** The last-good snapshot and its time, or `null` for no row. */
|
|
119
|
-
export async function readWorkspaceSnapshot(workspaceId: string): Promise<WorkspaceSnapshotRow | null> {
|
|
120
|
-
return prisma.workspaceOfferings.findUnique({
|
|
121
|
-
where: { workspaceId },
|
|
122
|
-
select: { snapshot: true, snapshotAt: true },
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Write a parsed snapshot and its time together (the pairing CHECK). Creates
|
|
128
|
-
* no row, and never replaces a snapshot dated after `at` (unless it is dated
|
|
129
|
-
* more than `futureSkewMs` past it, which no reader serves): `false` when
|
|
130
|
-
* nothing was written.
|
|
131
|
-
*/
|
|
132
|
-
export async function writeWorkspaceSnapshot(
|
|
133
|
-
workspaceId: string,
|
|
134
|
-
snapshot: OfferingsSnapshot,
|
|
135
|
-
at: Date,
|
|
136
|
-
futureSkewMs: number,
|
|
137
|
-
): Promise<boolean> {
|
|
138
|
-
const { count } = await prisma.workspaceOfferings.updateMany({
|
|
139
|
-
where: {
|
|
140
|
-
workspaceId,
|
|
141
|
-
OR: [
|
|
142
|
-
{ snapshotAt: null },
|
|
143
|
-
{ snapshotAt: { lte: at } },
|
|
144
|
-
{ snapshotAt: { gt: new Date(at.getTime() + futureSkewMs) } },
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
data: { snapshot, snapshotAt: at },
|
|
148
|
-
});
|
|
149
|
-
return count > 0;
|
|
150
|
-
}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file owner-workspaces.ts
|
|
3
|
-
* @description The ONE site→workspace resolution in `apps/api`.
|
|
4
|
-
*
|
|
5
|
-
* A `Lead` is keyed on `siteId` and a `Workspace` on `id`, but the two are the
|
|
6
|
-
* SAME value space named per namespace — `database/config/schema.prisma` says
|
|
7
|
-
* as much of `ProjectListing`, "the one keyed on `siteId` rather than
|
|
8
|
-
* `workspaceId`". So ownership is the direct membership test
|
|
9
|
-
* `siteId ∈ workspaceIds`, never a join through a mapping table, and every
|
|
10
|
-
* caller that needs it resolves it here rather than writing a second path: a
|
|
11
|
-
* divergent isolation path across two PII surfaces is exactly the thing that
|
|
12
|
-
* turns into rework when the multi-tenant product arrives.
|
|
13
|
-
*
|
|
14
|
-
* Callers: `lead-promotion.ts` (lead → user promotion, #3586) and
|
|
15
|
-
* `leads-inbox.ts` (the owner's leads read, #5678).
|
|
16
|
-
*
|
|
17
|
-
* ## Why this is its own file rather than a `lead-promotion.ts` export
|
|
18
|
-
*
|
|
19
|
-
* `paidModuleTemplateExclusions()` (`packages/create-ailk/src/module-architecture.ts`)
|
|
20
|
-
* walks the import graph from each paid module's `ownedFiles` to a fixed point
|
|
21
|
-
* and drops every file that reaches one, so that a keyless scaffold carries no
|
|
22
|
-
* paid source. `lead-promotion.ts` is inside that closure and always has been,
|
|
23
|
-
* which means anything importing it is dropped too. Putting this function
|
|
24
|
-
* there and importing it from the leads read would have carried the closure
|
|
25
|
-
* through `leads-inbox.ts` and `routes/leads/list.ts` into `server.ts`, and a
|
|
26
|
-
* scaffold with no server entry point does not build — the same base-breaking
|
|
27
|
-
* cascade `module-architecture.ts` records twice in its own comments, measured
|
|
28
|
-
* here before this file existed. Keeping the resolution in a module that
|
|
29
|
-
* reaches nothing excluded is what lets both callers share it.
|
|
30
|
-
*
|
|
31
|
-
* Nothing in this file may name `tenant-context.js` in an import form,
|
|
32
|
-
* including inside a comment: the closure's scanner is a regular expression
|
|
33
|
-
* over the file's text and does not know which lines are code.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import type { Id } from "@working-theory/ids";
|
|
37
|
-
|
|
38
|
-
import { isModuleEnabled } from "../config/modules.js";
|
|
39
|
-
import { loadSlice } from "../lib/slice-load.js";
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* The tenant-context module is a multi-tenant SLICE the OSS strip removes
|
|
43
|
-
* (#5182), and `listTenancy` is a VALUE — a runtime call, not an erasable type
|
|
44
|
-
* — so a static import, or a specifier written literally at the call site,
|
|
45
|
-
* would be TS2307 on the public tree: `tsc` resolves a string-literal
|
|
46
|
-
* specifier whether or not the branch containing it can ever run.
|
|
47
|
-
*
|
|
48
|
-
* The remedy is the one `server.ts` and `lead-promotion.ts` already use: gate
|
|
49
|
-
* the call on `isModuleEnabled('multi-tenant')` and read the specifier from
|
|
50
|
-
* this constant, so it is not a literal at the call site. What defeats
|
|
51
|
-
* resolution is the INDIRECTION, not the type of the value. The constant form
|
|
52
|
-
* matters too — `@vercel/nft` constant-propagates a module-level binding into
|
|
53
|
-
* the dynamic call and emits the file, which a table lookup would hide from it
|
|
54
|
-
* (#5304 D3).
|
|
55
|
-
*
|
|
56
|
-
* `apps/api` is a `tsc`-only surface with no bundler, which is the
|
|
57
|
-
* precondition that makes this sound here.
|
|
58
|
-
*/
|
|
59
|
-
const TENANT_CONTEXT_SPECIFIER = "./tenant-context.js";
|
|
60
|
-
|
|
61
|
-
/** The one export this file needs from the multi-tenant slice. */
|
|
62
|
-
interface TenantContextSlice {
|
|
63
|
-
listTenancy: (params: {
|
|
64
|
-
userId: Id<"user">;
|
|
65
|
-
sessionTenant: undefined;
|
|
66
|
-
}) => Promise<
|
|
67
|
-
| {
|
|
68
|
-
ok: true;
|
|
69
|
-
value: {
|
|
70
|
-
organizations: Array<{
|
|
71
|
-
role: string;
|
|
72
|
-
workspaces: Array<{ id: string }>;
|
|
73
|
-
}>;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
| { ok: false; error: { message: string } }
|
|
77
|
-
>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* One workspace the caller belongs to, carrying the role they hold in its
|
|
82
|
-
* organization. `role` is the organization-level `Membership.role`
|
|
83
|
-
* (`owner | admin | member`) the tenancy assembler already returns — typed as a
|
|
84
|
-
* plain string here rather than `MembershipRole`, because that type lives in
|
|
85
|
-
* the stripped slice this file may not name.
|
|
86
|
-
*/
|
|
87
|
-
export type OwnerWorkspace = { id: string; role: string };
|
|
88
|
-
|
|
89
|
-
export type ResolveOwnerWorkspacesResult =
|
|
90
|
-
| { ok: true; value: OwnerWorkspace[] }
|
|
91
|
-
| { ok: false; error: { message: string } };
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Resolve the caller's OWN workspaces.
|
|
95
|
-
*
|
|
96
|
-
* Delegates to the sole cross-namespace tenancy assembler — this file never
|
|
97
|
-
* issues a raw membership or workspace model query of its own, which
|
|
98
|
-
* `architecture.yaml`'s tenant-scope forbidden pattern reserves to the
|
|
99
|
-
* tenant-context and tenant-db modules.
|
|
100
|
-
*
|
|
101
|
-
* Module-conditional, and #5677 changed what that MEANS rather than what it
|
|
102
|
-
* does. `services/default-tenant.ts` now resolves the seeded default
|
|
103
|
-
* Workspace on every build, so a module-less deployment does have a
|
|
104
|
-
* resolvable workspace — the empty result below is a deliberate scope limit,
|
|
105
|
-
* not a statement that there is nothing to resolve. Wiring this resolver to
|
|
106
|
-
* that default is a behavior change for BOTH callers at once (promotion would
|
|
107
|
-
* begin stamping `promotedUserId` on single-tenant leads, which
|
|
108
|
-
* `/v1/flow-checkouts/me` and `/v1/waitlist-signups/me` join through), and it
|
|
109
|
-
* needs the deployment to pin `AILK_SITE_ID` to `DEFAULT_WORKSPACE_ID` —
|
|
110
|
-
* `siteId` comes from `lib/site.ts` while `workspaceId` is the sentinel, and
|
|
111
|
-
* `siteId ∈ workspaceIds` only matches when those agree.
|
|
112
|
-
*/
|
|
113
|
-
export async function resolveOwnerWorkspaces(
|
|
114
|
-
userId: Id<"user">,
|
|
115
|
-
): Promise<ResolveOwnerWorkspacesResult> {
|
|
116
|
-
if (!isModuleEnabled("multi-tenant")) return { ok: true, value: [] };
|
|
117
|
-
|
|
118
|
-
const specifier: string = TENANT_CONTEXT_SPECIFIER;
|
|
119
|
-
const { listTenancy } = (await loadSlice(
|
|
120
|
-
specifier,
|
|
121
|
-
() => import(specifier),
|
|
122
|
-
)) as TenantContextSlice;
|
|
123
|
-
const tenancy = await listTenancy({ userId, sessionTenant: undefined });
|
|
124
|
-
if (!tenancy.ok) return { ok: false, error: tenancy.error };
|
|
125
|
-
|
|
126
|
-
return {
|
|
127
|
-
ok: true,
|
|
128
|
-
value: tenancy.value.organizations.flatMap((org) =>
|
|
129
|
-
org.workspaces.map((workspace) => ({ id: workspace.id, role: org.role })),
|
|
130
|
-
),
|
|
131
|
-
};
|
|
132
|
-
}
|