create-ailk 0.20.0 → 0.22.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 +21 -1
- package/component-catalog.json +220 -8
- package/component-catalog.md +21 -9
- package/dist/add-module.js +9 -5
- package/dist/apply-design.d.ts +9 -0
- package/dist/apply-design.js +78 -31
- package/dist/derive-architecture.d.ts +8 -1
- package/dist/derive-architecture.js +38 -3
- package/dist/design-home.d.ts +54 -11
- package/dist/design-home.js +160 -22
- package/dist/design-package.js +7 -2
- package/dist/lib/design-checks.d.ts +6 -1
- package/dist/lib/design-checks.js +23 -2
- package/dist/lib/env-catalog.js +5 -1
- package/dist/module-architecture.js +4 -2
- package/dist/programmatic.js +63 -25
- package/dist/site-chrome.d.ts +8 -0
- package/dist/site-chrome.js +17 -1
- package/dist/site-roster.d.ts +4 -2
- package/dist/site-roster.js +7 -5
- package/dist/spoke-checkout.d.ts +39 -18
- package/dist/spoke-checkout.js +177 -236
- package/dist/starter-grid.js +16 -0
- package/dist/surfaces.js +30 -14
- package/dist/sync-routes.d.ts +28 -0
- package/dist/sync-routes.js +124 -1
- package/dist/template-record.d.ts +4 -3
- package/dist/template-record.js +6 -3
- package/dist/topology.js +25 -1
- package/dist/update.d.ts +6 -1
- package/dist/update.js +125 -18
- package/package.json +3 -3
- package/site-templates/_base/ailk-template.json +2 -2
- package/site-templates/_base/content/en/WorkingAgreementPage/working-agreement.mdx +78 -0
- package/site-templates/designs/minimalism/DESIGN.md +1 -1
- package/site-templates/designs/minimalism/contact/local-business-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-product.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/person-service.mdx +23 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +11 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +34 -23
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +31 -21
- package/templates/README.md +26 -25
- package/templates/apps/api/CLAUDE.md +20 -7
- package/templates/apps/api/jest.config.cjs +1 -0
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +19 -0
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +149 -0
- package/templates/apps/api/src/lib/consent-store.ts +28 -0
- package/templates/apps/api/src/lib/flow-completion-store.ts +136 -0
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +38 -2
- package/templates/apps/api/src/lib/proposal-paid-store.ts +21 -4
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +14 -3
- package/templates/apps/api/src/middleware/auth.ts +13 -6
- package/templates/apps/api/src/openapi/spec.ts +30 -3
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +49 -0
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +41 -0
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +386 -0
- package/templates/apps/api/src/routes/consent/account.ts +266 -0
- package/templates/apps/api/src/routes/consent/index.ts +15 -7
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +36 -0
- package/templates/apps/api/src/routes/content/get-page.ts +4 -0
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +515 -0
- package/templates/apps/api/src/routes/leads/index.ts +161 -7
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +26 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +649 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +154 -19
- package/templates/apps/api/src/server.ts +28 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +1038 -118
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +389 -0
- package/templates/apps/api/src/services/checkout-buyer.ts +100 -4
- package/templates/apps/api/src/services/consent.ts +95 -0
- package/templates/apps/api/src/services/lead-routing.ts +337 -8
- package/templates/apps/api/src/services/magnet-completion.ts +242 -0
- package/templates/apps/api/src/services/person.ts +40 -8
- package/templates/apps/api/src/services/plan-offerings.ts +59 -0
- package/templates/apps/api/src/services/project-listings.ts +6 -1
- package/templates/apps/api/src/services/public-site-resolver.ts +8 -1
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +69 -61
- package/templates/apps/mcp/jest.config.cjs +1 -0
- package/templates/apps/web/.env.example +14 -0
- package/templates/apps/web/CLAUDE.md +139 -3
- package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +6 -2
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +5 -4
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +5 -1
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +2 -0
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +3 -14
- package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +2 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +5 -1
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +160 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/sign-in-card.test.tsx +12 -9
- package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +105 -2
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +36 -3
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +47 -1
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +60 -22
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +16 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +85 -31
- package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +18 -4
- package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +3 -1
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +7 -4
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/agreements-prompt.test.tsx +227 -207
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout-sign-out.test.tsx +17 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout.test.tsx +143 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/new-menu.test.tsx +4 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +385 -89
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/popups.test.tsx +5 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/privacy.test.tsx +44 -5
- package/templates/apps/web/app/[locale]/(authed)/account/account-frame.tsx +68 -34
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +0 -8
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-actions.ts +39 -151
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-gate.ts +61 -0
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-prompt.tsx +143 -140
- package/templates/apps/web/app/[locale]/(authed)/account/layout.tsx +40 -6
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +68 -54
- package/templates/apps/web/app/[locale]/(authed)/account/privacy/page.tsx +5 -1
- package/templates/apps/web/app/[locale]/about/[slug]/page.tsx +46 -0
- package/templates/apps/web/app/[locale]/about/__tests__/about-routes.test.tsx +350 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +83 -1
- package/templates/apps/web/app/[locale]/careers/[slug]/apply.actions.ts +293 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/job-application-form.ts +115 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +146 -1
- package/templates/apps/web/app/[locale]/careers/__tests__/apply.actions.test.ts +310 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/job-application-form.test.ts +143 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/job-apply-page.test.tsx +350 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +29 -3
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/checkout/__tests__/pages.test.tsx +139 -0
- package/templates/apps/web/app/[locale]/checkout/__tests__/thank-you-account.test.tsx +136 -0
- package/templates/apps/web/app/[locale]/checkout/thank-you/page.tsx +114 -0
- package/templates/apps/web/app/[locale]/checkout/unavailable/page.tsx +51 -0
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +24 -1
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +79 -4
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-magnet.test.ts +138 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +17 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-magnet-page.test.tsx +386 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +504 -24
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +12 -3
- package/templates/apps/web/app/[locale]/contact/contact-form-magnet.ts +77 -0
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +2 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +184 -41
- package/templates/apps/web/app/[locale]/contact/intake-script.ts +26 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +120 -16
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +106 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.invite.test.tsx +257 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/account-invite.actions.test.ts +69 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/account-invite.actions.ts +35 -0
- package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/layout.tsx +23 -2
- package/templates/apps/web/app/[locale]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/thanks/[slug]/AccountInviteLink.tsx +89 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/AccountInviteLink.test.tsx +104 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/working-agreement/__tests__/page.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/working-agreement/page.tsx +41 -0
- package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +114 -0
- package/templates/apps/web/app/api/auth/hub/authorize/route.ts +20 -3
- package/templates/apps/web/app/api/checkout/[offering]/route.ts +48 -0
- package/templates/apps/web/app/api/checkout/__tests__/route.test.ts +120 -0
- package/templates/apps/web/app/api/checkout/__tests__/success-path.test.ts +86 -0
- package/templates/apps/web/app/api/hub-session/__tests__/routes.test.ts +44 -1
- package/templates/apps/web/app/api/hub-session/sign-in/route.ts +22 -3
- package/templates/apps/web/app/api/webhooks/stripe/__tests__/route.test.ts +92 -0
- package/templates/apps/web/app/api/webhooks/stripe/route.ts +31 -0
- package/templates/apps/web/auth.ts +28 -2
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/__tests__/account-invite.test.ts +63 -0
- package/templates/apps/web/lib/__tests__/checkout.test.ts +243 -0
- package/templates/apps/web/lib/__tests__/consent-policies.test.ts +23 -0
- package/templates/apps/web/lib/__tests__/deck-page.test.ts +249 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +38 -19
- package/templates/apps/web/lib/account-invite.ts +37 -0
- package/templates/apps/web/lib/checkout-config.ts +27 -0
- package/templates/apps/web/lib/checkout.ts +93 -0
- package/templates/apps/web/lib/consent-policies.ts +22 -0
- package/templates/apps/web/lib/deck-page.ts +192 -0
- package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +111 -0
- package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +88 -32
- package/templates/apps/web/lib/prisma-for-auth.ts +8 -0
- package/templates/apps/web/lib/sign-up-agreements.ts +447 -0
- package/templates/apps/web/lib/site-chrome.ts +2 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
- package/templates/apps/web/messages/en.json +40 -12
- package/templates/apps/web/package.json +1 -0
- package/templates/apps/web/src/lib/__tests__/lead-write.test.ts +187 -0
- package/templates/apps/web/src/lib/__tests__/rate-limit.test.ts +67 -0
- package/templates/apps/web/src/lib/lead-write.ts +90 -0
- package/templates/apps/web/src/lib/rate-limit.ts +79 -0
- package/templates/database/CHANGELOG.md +47 -0
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +79 -0
- package/templates/database/__tests__/flow-completion-migration.test.ts +115 -0
- package/templates/database/__tests__/flow-completion.db.test.ts +136 -0
- package/templates/database/__tests__/seed.test.ts +72 -2
- package/templates/database/inbox/schema.prisma +17 -2
- package/templates/database/jest.config.cjs +1 -0
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +52 -0
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +27 -0
- package/templates/database/package.json +1 -1
- package/templates/database/seed.ts +60 -0
- package/templates/tools/jest/pin-timezone.cjs +34 -0
- package/versions.json +34 -34
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up.actions.ts +0 -125
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* global process */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Shared Jest `globalSetup` — pins every jest run in the workspace to one
|
|
6
|
+
* timezone (#8657).
|
|
7
|
+
*
|
|
8
|
+
* Jest otherwise inherits the developer's `TZ`, so a test that renders a date
|
|
9
|
+
* in local time (`formatDate`, `toLocaleDateString`, `getDate()`) passes in CI,
|
|
10
|
+
* which runs in UTC, and fails on a laptop that does not: the #8578 shape,
|
|
11
|
+
* where UTC-midnight consent fixtures rendered the previous day on an MDT
|
|
12
|
+
* machine and failed 11 release-check rows.
|
|
13
|
+
*
|
|
14
|
+
* WHY `globalSetup` AND NOT `setupFiles`: a setup file runs inside the test
|
|
15
|
+
* sandbox, whose `process.env` is jest's copy of the real one, so assigning
|
|
16
|
+
* `TZ` there never reaches the process clock. `globalSetup` runs in jest's
|
|
17
|
+
* parent process before any worker is spawned: the workers inherit the pinned
|
|
18
|
+
* `TZ`, and Node re-reads an assigned `process.env.TZ` at once, so an in-band
|
|
19
|
+
* run (`--runInBand`, a single test file) is pinned in place too.
|
|
20
|
+
*
|
|
21
|
+
* Every committed `jest.config.cjs` loads this file; the guard is
|
|
22
|
+
* `tests/architecture/jest-timezone-pin.test.ts`, and the value is documented
|
|
23
|
+
* in CONVENTIONS.md § Testing. A test that needs another zone formats with an
|
|
24
|
+
* explicit `timeZone` option rather than changing `TZ`. The create-ailk
|
|
25
|
+
* scaffold ships this file at the same path (`SNAPSHOT_FILES` in
|
|
26
|
+
* packages/create-ailk/scripts/build-templates.mjs), so its copied configs
|
|
27
|
+
* load it unchanged.
|
|
28
|
+
*/
|
|
29
|
+
const PINNED_TZ = "UTC";
|
|
30
|
+
|
|
31
|
+
module.exports = async function pinTimezone() {
|
|
32
|
+
process.env.TZ = PINNED_TZ;
|
|
33
|
+
};
|
|
34
|
+
module.exports.PINNED_TZ = PINNED_TZ;
|
package/versions.json
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
"@working-theory/admin-ui": "0.
|
|
3
|
-
"@working-theory/aeo": "0.
|
|
4
|
-
"@working-theory/agent-context": "0.
|
|
2
|
+
"@working-theory/admin-ui": "0.43.0",
|
|
3
|
+
"@working-theory/aeo": "0.43.0",
|
|
4
|
+
"@working-theory/agent-context": "0.43.0",
|
|
5
5
|
"@working-theory/agent-contract": "0.1.0",
|
|
6
6
|
"@working-theory/agent-memory": "0.0.0",
|
|
7
7
|
"@working-theory/ai": "0.1.0",
|
|
8
|
-
"@working-theory/analytics": "0.
|
|
9
|
-
"@working-theory/api-client": "0.
|
|
8
|
+
"@working-theory/analytics": "0.43.0",
|
|
9
|
+
"@working-theory/api-client": "0.43.0",
|
|
10
10
|
"@working-theory/cda-filesystem": "0.0.0",
|
|
11
|
-
"@working-theory/cli": "0.
|
|
12
|
-
"@working-theory/common": "0.
|
|
11
|
+
"@working-theory/cli": "0.43.0",
|
|
12
|
+
"@working-theory/common": "0.43.0",
|
|
13
13
|
"@working-theory/consent": "0.1.0",
|
|
14
|
-
"@working-theory/content-adapters": "0.
|
|
15
|
-
"@working-theory/content-projection": "0.
|
|
16
|
-
"@working-theory/email": "0.
|
|
14
|
+
"@working-theory/content-adapters": "0.43.0",
|
|
15
|
+
"@working-theory/content-projection": "0.43.0",
|
|
16
|
+
"@working-theory/email": "0.43.0",
|
|
17
17
|
"@working-theory/env": "0.0.0",
|
|
18
|
-
"@working-theory/eslint-config": "0.
|
|
19
|
-
"@working-theory/fumadocs-schema": "0.
|
|
18
|
+
"@working-theory/eslint-config": "0.43.0",
|
|
19
|
+
"@working-theory/fumadocs-schema": "0.43.0",
|
|
20
20
|
"@working-theory/ids": "0.14.0",
|
|
21
|
-
"@working-theory/jsonld": "0.
|
|
22
|
-
"@working-theory/license": "0.
|
|
23
|
-
"@working-theory/metadata": "0.
|
|
24
|
-
"@working-theory/observability": "0.
|
|
25
|
-
"@working-theory/page-renderer": "0.
|
|
21
|
+
"@working-theory/jsonld": "0.43.0",
|
|
22
|
+
"@working-theory/license": "0.43.0",
|
|
23
|
+
"@working-theory/metadata": "0.43.0",
|
|
24
|
+
"@working-theory/observability": "0.43.0",
|
|
25
|
+
"@working-theory/page-renderer": "0.43.0",
|
|
26
26
|
"@working-theory/plugin-mcp": "0.1.3",
|
|
27
|
-
"@working-theory/schema": "0.
|
|
28
|
-
"@working-theory/schema-pack-registry": "0.
|
|
29
|
-
"@working-theory/schema-validator": "0.
|
|
30
|
-
"@working-theory/sections-registry": "0.
|
|
31
|
-
"@working-theory/site-config": "0.
|
|
32
|
-
"@working-theory/spoke-checkout": "0.
|
|
33
|
-
"@working-theory/stripe-client": "0.
|
|
34
|
-
"@working-theory/templates": "0.
|
|
35
|
-
"@working-theory/theme": "0.
|
|
36
|
-
"@working-theory/ui": "0.
|
|
37
|
-
"@working-theory/validation": "0.
|
|
38
|
-
"@working-theory/web-i18n": "0.
|
|
27
|
+
"@working-theory/schema": "0.43.0",
|
|
28
|
+
"@working-theory/schema-pack-registry": "0.43.0",
|
|
29
|
+
"@working-theory/schema-validator": "0.43.0",
|
|
30
|
+
"@working-theory/sections-registry": "0.43.0",
|
|
31
|
+
"@working-theory/site-config": "0.43.0",
|
|
32
|
+
"@working-theory/spoke-checkout": "0.6.0",
|
|
33
|
+
"@working-theory/stripe-client": "0.43.0",
|
|
34
|
+
"@working-theory/templates": "0.43.0",
|
|
35
|
+
"@working-theory/theme": "0.43.0",
|
|
36
|
+
"@working-theory/ui": "0.43.0",
|
|
37
|
+
"@working-theory/validation": "0.43.0",
|
|
38
|
+
"@working-theory/web-i18n": "0.43.0",
|
|
39
39
|
"@working-theory/billing-client": "0.0.0",
|
|
40
40
|
"@working-theory/branding": "0.0.0",
|
|
41
41
|
"@working-theory/license-client": "0.0.0",
|
|
42
42
|
"@working-theory/license-manifest": "0.0.0",
|
|
43
43
|
"@working-theory/partner-session": "0.0.0",
|
|
44
44
|
"@working-theory/preview-protocol": "0.0.0",
|
|
45
|
-
"@working-theory/ui-commerce": "0.23.
|
|
46
|
-
"@working-theory/ui-docs-blog": "0.23.
|
|
47
|
-
"@working-theory/ui-scheduling": "0.
|
|
48
|
-
"@working-theory/ui-signal-collectors": "0.
|
|
45
|
+
"@working-theory/ui-commerce": "0.23.21",
|
|
46
|
+
"@working-theory/ui-docs-blog": "0.23.21",
|
|
47
|
+
"@working-theory/ui-scheduling": "0.24.1",
|
|
48
|
+
"@working-theory/ui-signal-collectors": "0.26.0",
|
|
49
49
|
"@working-theory/web": "0.0.0",
|
|
50
50
|
"@working-theory/api": "1.0.0",
|
|
51
51
|
"@working-theory/mcp": "0.0.0",
|
|
52
|
-
"@working-theory/database": "0.
|
|
52
|
+
"@working-theory/database": "0.43.0"
|
|
53
53
|
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use server";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* sign-up.actions.ts — mints the sign-up card's carried-agreement cookie
|
|
5
|
-
* (#8438 D13, spec
|
|
6
|
-
* docs/specs/8438-consent-registry-and-ledger-step-spec.md C6).
|
|
7
|
-
*
|
|
8
|
-
* `apps/web` never touches the database (the ledger writer is `apps/api`),
|
|
9
|
-
* and Better Auth creates the user from THIS app before any Person exists to
|
|
10
|
-
* record a grant against. So the card remembers which agreements the person
|
|
11
|
-
* ticked, in a short-lived, signed, email-bound cookie — the account home's
|
|
12
|
-
* first signed-in visit (`(authed)/account/actions.ts`'s
|
|
13
|
-
* `acceptCarriedAgreementsAction`) consumes it, one write per agreement,
|
|
14
|
-
* then deletes it either way (single-use).
|
|
15
|
-
*
|
|
16
|
-
* The CONSUME side lives in the account area, not here, deliberately:
|
|
17
|
-
* `(auth)/**` is one of the sign-in seeds a sign-in-less spoke drops
|
|
18
|
-
* (`SPOKE_REMOVAL_SEEDS`, `packages/create-ailk/src/topology.ts` D4), so a
|
|
19
|
-
* file OUTSIDE `(auth)` (the account home's `agreements-prompt.tsx`) must
|
|
20
|
-
* never import FROM here — doing so once failed the scaffolder's own
|
|
21
|
-
* dangling-import check (`spokeExclusions`) for exactly this reason. This
|
|
22
|
-
* file is reached only from `sign-up-card.tsx`, its own directory sibling,
|
|
23
|
-
* so it carries no such obligation. The two files duplicate the small
|
|
24
|
-
* cookie codec (encode here, decode there) rather than share a module,
|
|
25
|
-
* precisely so each side's dependencies stay native to where it lives.
|
|
26
|
-
*
|
|
27
|
-
* Cookie value: `<id>@<version>,…|<issuedAtMs>|<sha256(lowercased email)>|
|
|
28
|
-
* <HMAC-SHA256 over the rest>`, keyed by `BETTER_AUTH_SECRET` — the same
|
|
29
|
-
* dev fallback `apps/web/auth.ts`'s own `resolveSecret()` publishes when it
|
|
30
|
-
* is unset; production refuses to mint without one. That secret is read
|
|
31
|
-
* directly HERE rather than importing `resolveSecret` from `auth.ts`: that
|
|
32
|
-
* module statically imports the `better-auth` ESM package, which every
|
|
33
|
-
* broad page-level test suite that renders `/sign-up` would then have to
|
|
34
|
-
* add to its `../../../../auth` mock. `__Host-` prefixed, httpOnly,
|
|
35
|
-
* `Secure`, one hour, `SameSite=Lax` — the `__Host-` prefix needs `Secure`,
|
|
36
|
-
* so development over plain `http://localhost` uses the unprefixed name
|
|
37
|
-
* instead (SEC-8438-5).
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
import { createHash, createHmac } from "node:crypto";
|
|
41
|
-
|
|
42
|
-
import { consentPurposeById, SITE_CONSENT_CONFIG_DEFAULTS } from "@working-theory/validation";
|
|
43
|
-
import { cookies } from "next/headers";
|
|
44
|
-
|
|
45
|
-
const SECURE_COOKIE_NAME = "__Host-ailk-signup-agreements";
|
|
46
|
-
const DEV_COOKIE_NAME = "ailk-signup-agreements";
|
|
47
|
-
const MAX_AGE_SECONDS = 60 * 60;
|
|
48
|
-
|
|
49
|
-
/** The string `auth.ts`'s own `resolveSecret()` publishes — see file header. */
|
|
50
|
-
const DEV_FALLBACK_SECRET =
|
|
51
|
-
"ailk-dev-fallback-secret-published-in-this-repo-never-use-in-production";
|
|
52
|
-
|
|
53
|
-
/** Mirrors `auth.ts`'s `resolveSecret()` exactly, without importing it. */
|
|
54
|
-
function signUpAgreementsSecret(): string {
|
|
55
|
-
const configured = process.env.BETTER_AUTH_SECRET;
|
|
56
|
-
if (configured) return configured;
|
|
57
|
-
const isBuildPhase = process.env.NEXT_PHASE === "phase-production-build";
|
|
58
|
-
if (process.env.NODE_ENV === "production" && !isBuildPhase) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
"BETTER_AUTH_SECRET is required in production: it signs the carried sign-up-agreement cookie.",
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return DEV_FALLBACK_SECRET;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function cookieName(): string {
|
|
67
|
-
return process.env.NODE_ENV === "production" ? SECURE_COOKIE_NAME : DEV_COOKIE_NAME;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function emailHash(email: string): string {
|
|
71
|
-
return createHash("sha256").update(email.trim().toLowerCase()).digest("hex");
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function sign(payload: string): string {
|
|
75
|
-
return createHmac("sha256", signUpAgreementsSecret()).update(payload).digest("hex");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface CarriedPurpose {
|
|
79
|
-
id: string;
|
|
80
|
-
version: number;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function encodeCarriedAgreements(
|
|
84
|
-
purposes: CarriedPurpose[],
|
|
85
|
-
email: string,
|
|
86
|
-
issuedAtMs: number,
|
|
87
|
-
): string {
|
|
88
|
-
const purposesPart = purposes.map((p) => `${p.id}@${p.version}`).join(",");
|
|
89
|
-
const payload = `${purposesPart}|${issuedAtMs}|${emailHash(email)}`;
|
|
90
|
-
return `${payload}|${sign(payload)}`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Mints the carried-agreement cookie from the ticked `signUp` agreements,
|
|
95
|
-
* read back from the registry for their CURRENT version — never trusting a
|
|
96
|
-
* version the client might assert. Purposes the registry no longer marks
|
|
97
|
-
* `signUp` are dropped. Never throws: a failed mint just means the account
|
|
98
|
-
* home's first visit asks explicitly instead (D13's "Otherwise" card).
|
|
99
|
-
*/
|
|
100
|
-
export async function rememberSignUpAgreementsAction(
|
|
101
|
-
email: string,
|
|
102
|
-
purposeIds: string[],
|
|
103
|
-
): Promise<void> {
|
|
104
|
-
try {
|
|
105
|
-
const config = SITE_CONSENT_CONFIG_DEFAULTS;
|
|
106
|
-
const purposes: CarriedPurpose[] = [];
|
|
107
|
-
for (const id of purposeIds) {
|
|
108
|
-
const purpose = consentPurposeById(config, id);
|
|
109
|
-
if (purpose?.signUp) purposes.push({ id: purpose.id, version: purpose.policyVersion });
|
|
110
|
-
}
|
|
111
|
-
if (purposes.length === 0) return;
|
|
112
|
-
|
|
113
|
-
const value = encodeCarriedAgreements(purposes, email, Date.now());
|
|
114
|
-
const cookieStore = await cookies();
|
|
115
|
-
cookieStore.set(cookieName(), value, {
|
|
116
|
-
httpOnly: true,
|
|
117
|
-
secure: process.env.NODE_ENV === "production",
|
|
118
|
-
sameSite: "lax",
|
|
119
|
-
path: "/",
|
|
120
|
-
maxAge: MAX_AGE_SECONDS,
|
|
121
|
-
});
|
|
122
|
-
} catch {
|
|
123
|
-
// Convenience only — see file header.
|
|
124
|
-
}
|
|
125
|
-
}
|