create-ailk 0.18.0 → 0.19.1
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/LICENSE +6 -5
- package/NOTICE +2 -0
- package/dist/add-module.js +11 -3
- package/dist/category-profile.d.ts +10 -0
- package/dist/category-profile.js +21 -0
- package/dist/derive-architecture.d.ts +5 -1
- package/dist/derive-architecture.js +8 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/license-key-files.d.ts +6 -3
- package/dist/lib/license-key-files.js +8 -2
- package/dist/lib/scaffold-render-sweep.d.ts +32 -0
- package/dist/lib/scaffold-render-sweep.js +76 -3
- package/dist/license-set.d.ts +1 -1
- package/dist/license-set.js +13 -8
- package/dist/module-architecture.js +128 -3
- package/dist/programmatic.js +11 -1
- package/dist/site-roster.js +21 -4
- package/dist/spoke-checkout.d.ts +11 -3
- package/dist/spoke-checkout.js +62 -12
- package/dist/starter-grid.d.ts +1 -1
- package/dist/surfaces.d.ts +14 -0
- package/dist/surfaces.js +170 -1
- package/dist/template-manifest.d.ts +4 -3
- package/dist/topology.d.ts +7 -2
- package/dist/topology.js +88 -3
- package/package.json +5 -4
- package/templates/.env.example +3 -3
- package/templates/.github/workflows/ci.yml +5 -0
- package/templates/apps/api/.env.example +17 -1
- package/templates/apps/api/CLAUDE.md +31 -7
- package/templates/apps/api/LICENSE +6 -5
- package/templates/apps/api/NOTICE +2 -0
- package/templates/apps/api/jest.config.cjs +4 -29
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +19 -0
- package/templates/apps/api/src/__tests__/stripe-boot.test.ts +132 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +17 -0
- package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +237 -0
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +334 -0
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +38 -0
- package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +217 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +7 -0
- package/templates/apps/api/src/lib/consent-store.ts +335 -0
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +5 -4
- package/templates/apps/api/src/lib/stripe.ts +176 -3
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +272 -39
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +51 -0
- package/templates/apps/api/src/middleware/auth.ts +214 -46
- package/templates/apps/api/src/middleware/rate-limit.ts +5 -0
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +167 -0
- package/templates/apps/api/src/routes/checkout/session.ts +3 -3
- package/templates/apps/api/src/routes/checkout/sessions.ts +6 -4
- package/templates/apps/api/src/routes/consent/cookie.ts +90 -0
- package/templates/apps/api/src/routes/consent/index.ts +18 -0
- package/templates/apps/api/src/routes/consent/unsubscribe.ts +127 -0
- package/templates/apps/api/src/routes/leads/index.ts +19 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +5 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +17 -4
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +2 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +159 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +158 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +2 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +17 -0
- package/templates/apps/api/src/server.ts +218 -16
- package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +503 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +18 -3
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +173 -4
- package/templates/apps/api/src/services/__tests__/person.test.ts +392 -0
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +87 -0
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +57 -17
- package/templates/apps/api/src/services/consent.ts +488 -3
- package/templates/apps/api/src/services/lead-routing.ts +135 -14
- package/templates/apps/api/src/services/person.ts +501 -1
- package/templates/apps/api/src/services/project-listings.ts +7 -2
- package/templates/apps/api/src/services/request-confirm.ts +52 -0
- package/templates/apps/api/src/services/revalidation.ts +11 -1
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/.env.example +10 -0
- package/templates/apps/mcp/CLAUDE.md +9 -4
- package/templates/apps/mcp/LICENSE +6 -5
- package/templates/apps/mcp/NOTICE +2 -0
- package/templates/apps/mcp/__tests__/abuse/guard.test.ts +198 -0
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +15 -3
- package/templates/apps/mcp/__tests__/boot.test.ts +78 -1
- package/templates/apps/mcp/__tests__/http-transport.test.ts +291 -2
- package/templates/apps/mcp/__tests__/request_callback.test.ts +69 -7
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +69 -8
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +69 -7
- package/templates/apps/mcp/jest.config.cjs +3 -44
- package/templates/apps/mcp/src/abuse/index.ts +117 -21
- package/templates/apps/mcp/src/boot.ts +5 -23
- package/templates/apps/mcp/src/http-transport.ts +93 -73
- package/templates/apps/mcp/src/index.ts +2 -0
- package/templates/apps/mcp/src/request-context.ts +52 -0
- package/templates/apps/mcp/src/tools/capture_lead.ts +9 -1
- package/templates/apps/mcp/src/tools/request_callback.ts +9 -1
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +9 -1
- package/templates/apps/web/LICENSE +6 -5
- package/templates/apps/web/NOTICE +2 -0
- package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +3 -3
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/account-frame-sign-out.test.tsx +175 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +302 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/general.test.tsx +724 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/hub-mode.test.tsx +346 -41
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/item.test.tsx +11 -13
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout-sign-out.test.tsx +146 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout.test.tsx +232 -29
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/new-menu.test.tsx +305 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/new-popups.test.tsx +82 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/notifications.test.tsx +140 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +163 -72
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/popups.test.tsx +451 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/security.test.tsx +409 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/settings.test.tsx +65 -380
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/support.test.tsx +16 -11
- package/templates/apps/web/app/[locale]/(authed)/account/account-data.ts +1 -1
- package/templates/apps/web/app/[locale]/(authed)/account/account-frame.tsx +188 -54
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +24 -45
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/page.tsx +253 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/review-form.tsx +145 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/versions/[version]/file/route.ts +100 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/file-route.test.ts +179 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/page.test.tsx +514 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/review.test.tsx +288 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/artifact-actions.ts +123 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/artifact-data.ts +82 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/page.tsx +174 -0
- package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +172 -0
- package/templates/apps/web/app/[locale]/(authed)/account/billing-source.ts +147 -0
- package/templates/apps/web/app/[locale]/(authed)/account/components/request-quote.tsx +229 -0
- package/templates/apps/web/app/[locale]/(authed)/account/components/schedule-service.tsx +276 -0
- package/templates/apps/web/app/[locale]/(authed)/account/components/send-message.tsx +128 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/billing-anchor.tsx +27 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/contact-actions.ts +81 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/deletion-request.tsx +132 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/page.tsx +193 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/profile-form.tsx +104 -0
- package/templates/apps/web/app/[locale]/(authed)/account/general/profile-source.ts +73 -0
- package/templates/apps/web/app/[locale]/(authed)/account/inbox/message/[id]/file/__tests__/route.test.ts +18 -8
- package/templates/apps/web/app/[locale]/(authed)/account/inbox/message/[id]/file/route.ts +4 -6
- package/templates/apps/web/app/[locale]/(authed)/account/layout.tsx +30 -4
- package/templates/apps/web/app/[locale]/(authed)/account/new-actions.ts +219 -0
- package/templates/apps/web/app/[locale]/(authed)/account/new-menu.tsx +340 -0
- package/templates/apps/web/app/[locale]/(authed)/account/new-popups.tsx +107 -0
- package/templates/apps/web/app/[locale]/(authed)/account/notifications/page.tsx +57 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +85 -26
- package/templates/apps/web/app/[locale]/(authed)/account/profile-actions.ts +116 -0
- package/templates/apps/web/app/[locale]/(authed)/account/security/page.tsx +132 -0
- package/templates/apps/web/app/[locale]/(authed)/account/security/security-panel.tsx +102 -0
- package/templates/apps/web/app/[locale]/(authed)/account/security/security-source.ts +62 -0
- package/templates/apps/web/app/[locale]/(authed)/account/settings/page.tsx +13 -354
- package/templates/apps/web/app/[locale]/(authed)/account/settings-frame.tsx +116 -0
- package/templates/apps/web/app/[locale]/(authed)/account/sign-in-method.ts +37 -0
- package/templates/apps/web/app/[locale]/(authed)/account/support-actions.ts +9 -10
- package/templates/apps/web/app/[locale]/layout.tsx +23 -4
- package/templates/apps/web/app/api/auth/hub/__tests__/continuation.test.ts +143 -0
- package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +62 -10
- package/templates/apps/web/app/api/auth/hub/authorize/route.ts +22 -7
- package/templates/apps/web/app/api/auth/hub/continuation.ts +73 -0
- package/templates/apps/web/app/api/auth/hub/continue/[ref]/__tests__/route.test.ts +188 -0
- package/templates/apps/web/app/api/auth/hub/continue/[ref]/route.ts +53 -0
- package/templates/apps/web/app/robots.txt/route.ts +10 -4
- package/templates/apps/web/auth.ts +25 -2
- package/templates/apps/web/lib/__tests__/account-config.test.ts +258 -46
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +84 -0
- package/templates/apps/web/lib/account-config.ts +188 -52
- package/templates/apps/web/lib/auth-email.ts +45 -10
- package/templates/apps/web/lib/hub-session/__tests__/hub-session.test.ts +143 -0
- package/templates/apps/web/lib/hub-session/index.ts +1 -0
- package/templates/apps/web/lib/hub-session/reseal.ts +90 -0
- package/templates/apps/web/lib/hub-session/seal.ts +13 -9
- package/templates/apps/web/lib/topology.generated.ts +33 -0
- package/templates/apps/web/messages/en.json +194 -33
- package/templates/database/CHANGELOG.md +37 -0
- package/templates/database/LICENSE +6 -5
- package/templates/database/NOTICE +2 -0
- package/templates/database/README.md +1 -1
- package/templates/database/__tests__/consent-ledger.db.test.ts +345 -0
- package/templates/database/__tests__/fence-fan-out.db.test.ts +6 -2
- package/templates/database/__tests__/fixtures/person-contact-backfill.json +182 -0
- package/templates/database/__tests__/member-area.db.test.ts +15 -3
- package/templates/database/__tests__/member-contract-migration.test.ts +85 -0
- package/templates/database/__tests__/member-contract.db.test.ts +413 -0
- package/templates/database/__tests__/person-contact.db.test.ts +563 -0
- package/templates/database/__tests__/person.db.test.ts +3 -1
- package/templates/database/__tests__/seed.test.ts +54 -2
- package/templates/database/inbox/schema.prisma +166 -25
- package/templates/database/migrations/20261012120000_member_contract/migration.sql +192 -0
- package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +20 -0
- package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +122 -0
- package/templates/database/migrations/20261014120000_person_contact/migration.sql +231 -0
- package/templates/database/package.json +3 -2
- package/templates/database/seed.ts +34 -2
- package/versions.json +36 -36
- package/templates/apps/api/src/__tests__/content-write-production-boot.test.ts +0 -104
- package/templates/apps/api/src/__tests__/cors.test.ts +0 -276
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +0 -279
- package/templates/apps/api/src/__tests__/openapi-keyless-hub.test.ts +0 -122
- package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +0 -167
- package/templates/apps/api/src/__tests__/root-modules.test.ts +0 -175
- package/templates/apps/api/src/__tests__/schedule-forwarded-rate-limit.test.ts +0 -117
- package/templates/apps/api/src/__tests__/server.test.ts +0 -591
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +0 -175
- package/templates/apps/api/src/openapi/__tests__/surface-drift.test.ts +0 -293
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +0 -1620
- package/templates/apps/api/src/routes/project-listings/__tests__/directory.test.ts +0 -528
- package/templates/apps/api/src/routes/workspaces/__tests__/inbox-wire-schemas.test.ts +0 -198
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +0 -652
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +0 -408
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +0 -476
- package/templates/apps/mcp/__tests__/audit.test.ts +0 -346
- package/templates/apps/mcp/__tests__/parity.test.ts +0 -325
- package/templates/apps/mcp/__tests__/workspace-surface.test.ts +0 -364
- package/templates/apps/web/app/[locale]/(authed)/account/settings/color-mode.tsx +0 -68
- package/templates/apps/web/app/[locale]/(authed)/account/settings/deletion-request.tsx +0 -55
- package/templates/apps/web/app/[locale]/(authed)/account/settings/name-form.tsx +0 -118
- package/templates/database/__tests__/build.test.ts +0 -131
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The spoke's session re-seal (#8232, spec
|
|
3
|
+
* docs/specs/8232-member-settings-account-general-and-spec.md D11; roadmap
|
|
4
|
+
* D9).
|
|
5
|
+
*
|
|
6
|
+
* After a member saves their name through the hub (`PATCH /v1/member/profile`),
|
|
7
|
+
* the sealed session cookie still names the person as they were at sign-in.
|
|
8
|
+
* `resealHubSession()` re-reads the person from the hub's own record,
|
|
9
|
+
* `GET /v1/hub-sign-in/me`, with the session's credential, and writes the
|
|
10
|
+
* cookie again so the next render shows the new name:
|
|
11
|
+
*
|
|
12
|
+
* - no hub-session configuration (a single site) or no session cookie ⇒
|
|
13
|
+
* `"skipped"`, with no call;
|
|
14
|
+
* - `/me` refusing, throwing, or answering a person of the wrong shape ⇒
|
|
15
|
+
* `"failed"`, and the cookie is left as it is (sign-out is the sign-out
|
|
16
|
+
* route's job — a transient hub error never signs the member out);
|
|
17
|
+
* - otherwise only `user` changes. `v`, `accessToken` and `expiresAt` are
|
|
18
|
+
* kept exactly and `Max-Age` is the remaining lifetime, so a re-seal
|
|
19
|
+
* never extends a session (SEC-8232-1). The cookie's name, key and
|
|
20
|
+
* attributes are the ones the callback route writes at sign-in
|
|
21
|
+
* (`cookieHeader`: `HttpOnly`, `SameSite=Lax`, `Path=/`, `Secure` on an
|
|
22
|
+
* https site — SEC-8232-2).
|
|
23
|
+
*
|
|
24
|
+
* It tests no topology: a single site has no configuration and no cookie.
|
|
25
|
+
* Nothing here logs a credential, a cookie value, a name or an email.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { hubSignIn } from "@working-theory/api-client";
|
|
29
|
+
import { cookies, headers } from "next/headers";
|
|
30
|
+
|
|
31
|
+
import { hubSessionConfig } from "./config";
|
|
32
|
+
import { seal } from "./seal";
|
|
33
|
+
import { type HubSessionUser, readHubSessionPayload, sessionCookieName } from "./session";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The person `/me` names, when every field is the type the session holds.
|
|
37
|
+
* It repeats `session.ts`'s private shape check on purpose: `sync-routes`
|
|
38
|
+
* brings this file to a scaffold whose own `session.ts` it never updates,
|
|
39
|
+
* so it cannot rely on a new export there.
|
|
40
|
+
*/
|
|
41
|
+
function sessionUser(value: unknown): HubSessionUser | null {
|
|
42
|
+
if (typeof value !== "object" || value === null) return null;
|
|
43
|
+
const user = value as Record<string, unknown>;
|
|
44
|
+
const { name, email, emailVerified, createdAt } = user;
|
|
45
|
+
if (
|
|
46
|
+
typeof email !== "string" ||
|
|
47
|
+
typeof emailVerified !== "boolean" ||
|
|
48
|
+
typeof createdAt !== "string" ||
|
|
49
|
+
(name !== null && typeof name !== "string")
|
|
50
|
+
) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return { name, email, emailVerified, createdAt };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Re-seals the hub session cookie from the hub's `/me`. Never throws. */
|
|
57
|
+
export async function resealHubSession(): Promise<"resealed" | "skipped" | "failed"> {
|
|
58
|
+
const config = hubSessionConfig();
|
|
59
|
+
if (config === null) return "skipped";
|
|
60
|
+
const payload = readHubSessionPayload(await headers());
|
|
61
|
+
if (payload === null) return "skipped";
|
|
62
|
+
const maxAge = Math.floor((payload.expiresAt - Date.now()) / 1000);
|
|
63
|
+
if (maxAge <= 0) return "skipped";
|
|
64
|
+
|
|
65
|
+
let user: HubSessionUser | null;
|
|
66
|
+
try {
|
|
67
|
+
const res = await hubSignIn.me({
|
|
68
|
+
headers: { authorization: `Bearer ${payload.accessToken}` },
|
|
69
|
+
});
|
|
70
|
+
user = res.ok ? sessionUser(res.body.user) : null;
|
|
71
|
+
} catch {
|
|
72
|
+
user = null;
|
|
73
|
+
}
|
|
74
|
+
if (user === null) return "failed";
|
|
75
|
+
|
|
76
|
+
const name = sessionCookieName(config);
|
|
77
|
+
try {
|
|
78
|
+
(await cookies()).set(name, seal({ ...payload, user }, config.sessionSecret, "session", name), {
|
|
79
|
+
httpOnly: true,
|
|
80
|
+
sameSite: "lax",
|
|
81
|
+
path: "/",
|
|
82
|
+
maxAge,
|
|
83
|
+
secure: config.secure,
|
|
84
|
+
});
|
|
85
|
+
} catch {
|
|
86
|
+
// Outside a Server Action or route handler Next refuses a cookie write.
|
|
87
|
+
return "failed";
|
|
88
|
+
}
|
|
89
|
+
return "resealed";
|
|
90
|
+
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Sealed
|
|
2
|
+
* Sealed values for the hub sign-in (#7894 D7, #8146 D3).
|
|
3
3
|
*
|
|
4
|
-
* AES-256-GCM with a fresh 12-byte IV per seal. The key is HKDF-SHA256 of
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* AES-256-GCM with a fresh 12-byte IV per seal. The key is HKDF-SHA256 of the
|
|
5
|
+
* caller's secret with one info string per purpose, so the three purposes
|
|
6
|
+
* never share a key, and the caller-supplied name is the additional
|
|
7
|
+
* authenticated data, so a value sealed for one name never opens as another.
|
|
8
|
+
* Two secrets feed this module: `AILK_HUB_SESSION_SECRET` for the spoke's
|
|
9
|
+
* `session` and `flow` cookies, and `BETTER_AUTH_SECRET` for the hub's
|
|
10
|
+
* `continue` ref (`app/api/auth/hub/continuation.ts`, hub and standalone
|
|
11
|
+
* sites only; the entry is unused on a spoke). The key never derives from the
|
|
12
|
+
* client secret: a leaked client secret forges no spoke session.
|
|
10
13
|
*
|
|
11
14
|
* Wire form: base64url(iv ‖ tag ‖ ciphertext). Anything that does not open —
|
|
12
15
|
* a wrong key, a wrong name, a truncated or altered value — reads as `null`,
|
|
@@ -20,12 +23,13 @@ import {
|
|
|
20
23
|
randomBytes,
|
|
21
24
|
} from "node:crypto";
|
|
22
25
|
|
|
23
|
-
/** The
|
|
24
|
-
export type SealPurpose = "session" | "flow";
|
|
26
|
+
/** The things this module seals, each under its own derived key. */
|
|
27
|
+
export type SealPurpose = "session" | "flow" | "continue";
|
|
25
28
|
|
|
26
29
|
const INFO: Record<SealPurpose, string> = {
|
|
27
30
|
session: "ailk-hub-session/v1",
|
|
28
31
|
flow: "ailk-hub-flow/v1",
|
|
32
|
+
continue: "ailk-hub-continue/v1",
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
const IV_BYTES = 12;
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
// `--hub-sign-in` (#7894) it reads the sealed hub-session cookie.
|
|
8
8
|
// UNSERVED_MCP_TOOLS names the MCP tools /.well-known/mcp.json leaves out
|
|
9
9
|
// on this topology (#8070).
|
|
10
|
+
// loadSpokeBilling reaches the spoke billing action only on a spoke that
|
|
11
|
+
// signs in through its hub and carries commerce (#8217); elsewhere, null.
|
|
12
|
+
// readOwnAccounts lists the signed-in person's own sign-in accounts through
|
|
13
|
+
// Better Auth on a hub (#8431); a spoke has none here, so it answers null.
|
|
10
14
|
|
|
11
15
|
export const TOPOLOGY: "hub" | "spoke" = "hub";
|
|
12
16
|
export const UNSERVED_MCP_TOOLS: readonly string[] = [];
|
|
@@ -30,7 +34,36 @@ export async function readSession(headers: Headers): Promise<SiteSession> {
|
|
|
30
34
|
return auth.api.getSession({ headers });
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
export async function readOwnAccounts(
|
|
38
|
+
headers: Headers,
|
|
39
|
+
): Promise<ReadonlyArray<{ providerId: string }> | null> {
|
|
40
|
+
const { auth } = await import("../auth");
|
|
41
|
+
return auth.api.listUserAccounts({ headers });
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
export async function registerSiteStores(): Promise<void> {
|
|
34
45
|
const { registerLicenseKeyStore } = await import("./license-key-store");
|
|
35
46
|
await registerLicenseKeyStore();
|
|
36
47
|
}
|
|
48
|
+
|
|
49
|
+
export type SpokeCard = { brand: string; last4: string; expMonth: number; expYear: number };
|
|
50
|
+
|
|
51
|
+
export type SpokeBillingRead =
|
|
52
|
+
| {
|
|
53
|
+
kind: "subscription";
|
|
54
|
+
status: "trialing" | "active" | "past_due" | "canceled";
|
|
55
|
+
planName: string | null;
|
|
56
|
+
paymentMethod: SpokeCard | null;
|
|
57
|
+
unreadable: boolean;
|
|
58
|
+
}
|
|
59
|
+
| { kind: "none"; unreadable: boolean }
|
|
60
|
+
| { kind: "failed" };
|
|
61
|
+
|
|
62
|
+
export type SpokeBilling = {
|
|
63
|
+
read(): Promise<SpokeBillingRead>;
|
|
64
|
+
portalUrl(): Promise<string | null>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export function loadSpokeBilling(): Promise<SpokeBilling | null> {
|
|
68
|
+
return Promise.resolve(null);
|
|
69
|
+
}
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"home": {
|
|
72
72
|
"heading": "My Site",
|
|
73
|
-
"emptyState": "
|
|
73
|
+
"emptyState": "Home page content coming soon."
|
|
74
74
|
},
|
|
75
75
|
"about": {
|
|
76
76
|
"heading": "About",
|
|
@@ -573,12 +573,64 @@
|
|
|
573
573
|
"account": {
|
|
574
574
|
"title": "Your account",
|
|
575
575
|
"description": "What changed, what's coming, and what needs you.",
|
|
576
|
+
"artifacts": {
|
|
577
|
+
"title": "Artifacts",
|
|
578
|
+
"lead": "Work delivered to you, newest first.",
|
|
579
|
+
"all": "All artifacts",
|
|
580
|
+
"facets": "Filter artifacts",
|
|
581
|
+
"reviewGroup": "Review",
|
|
582
|
+
"filter": "Show",
|
|
583
|
+
"empty": "Nothing has been delivered to you yet.",
|
|
584
|
+
"facetEmpty": "No artifacts here.",
|
|
585
|
+
"error": "We couldn't load your artifacts.",
|
|
586
|
+
"itemError": "We couldn't load this artifact.",
|
|
587
|
+
"retry": "Retry",
|
|
588
|
+
"back": "Artifacts",
|
|
589
|
+
"caption": "Artifact",
|
|
590
|
+
"versions": "Versions",
|
|
591
|
+
"version": "Version {version}",
|
|
592
|
+
"deliveredOn": "Delivered {date}",
|
|
593
|
+
"approvedOn": "Approved {date}",
|
|
594
|
+
"download": "Download {filename}",
|
|
595
|
+
"view": "View",
|
|
596
|
+
"columns": {
|
|
597
|
+
"title": "Title",
|
|
598
|
+
"latest": "Latest",
|
|
599
|
+
"delivered": "Delivered",
|
|
600
|
+
"review": "Review"
|
|
601
|
+
},
|
|
602
|
+
"states": {
|
|
603
|
+
"approved": "Approved",
|
|
604
|
+
"changesRequested": "Changes requested",
|
|
605
|
+
"ready": "Ready for review"
|
|
606
|
+
},
|
|
607
|
+
"reviewApproved": "You approved this version on {date}.",
|
|
608
|
+
"reviewChangesRequested": "You requested changes on {date}.",
|
|
609
|
+
"review": {
|
|
610
|
+
"heading": "Review version {version}",
|
|
611
|
+
"comment": "Comment",
|
|
612
|
+
"commentHint": "Needed to request changes.",
|
|
613
|
+
"approve": "Approve",
|
|
614
|
+
"requestChanges": "Request changes",
|
|
615
|
+
"submitting": "Sending…",
|
|
616
|
+
"sent": "Thanks — your review was sent.",
|
|
617
|
+
"waiting": "You requested changes. The next version will appear here.",
|
|
618
|
+
"errors": {
|
|
619
|
+
"commentRequired": "Add a comment to request changes.",
|
|
620
|
+
"closed": "This version can't be reviewed now. It may already be approved.",
|
|
621
|
+
"notLatest": "A newer version has arrived. Reload the page to review it.",
|
|
622
|
+
"rateLimited": "Too many requests. Try again later.",
|
|
623
|
+
"failed": "We couldn't send your review. Try again."
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
},
|
|
576
627
|
"frame": {
|
|
577
628
|
"home": "Home",
|
|
578
629
|
"inbox": "Inbox",
|
|
579
630
|
"forYou": "For you",
|
|
580
631
|
"settings": "Settings",
|
|
581
632
|
"signOut": "Log out",
|
|
633
|
+
"signOutFailed": "We couldn't log you out. You're still signed in; try again.",
|
|
582
634
|
"help": "Help",
|
|
583
635
|
"contactSupport": "Contact support",
|
|
584
636
|
"helpCenter": "Help center",
|
|
@@ -590,7 +642,9 @@
|
|
|
590
642
|
"collapseAside": "Collapse panel",
|
|
591
643
|
"expandAside": "Expand panel",
|
|
592
644
|
"openAside": "Open For you",
|
|
593
|
-
"closeAside": "Close For you"
|
|
645
|
+
"closeAside": "Close For you",
|
|
646
|
+
"library": "Library",
|
|
647
|
+
"artifacts": "Artifacts"
|
|
594
648
|
},
|
|
595
649
|
"forYou": {
|
|
596
650
|
"title": "For you",
|
|
@@ -617,10 +671,9 @@
|
|
|
617
671
|
"title": "Inbox",
|
|
618
672
|
"lead": "What changed, and what's coming.",
|
|
619
673
|
"tabs": {
|
|
620
|
-
"
|
|
621
|
-
"
|
|
622
|
-
"scheduled": "Scheduled"
|
|
623
|
-
"all": "All"
|
|
674
|
+
"all": "All",
|
|
675
|
+
"purchases": "Purchases",
|
|
676
|
+
"scheduled": "Scheduled"
|
|
624
677
|
},
|
|
625
678
|
"empty": "Nothing here yet.",
|
|
626
679
|
"error": "We couldn't load everything in your Inbox.",
|
|
@@ -642,60 +695,112 @@
|
|
|
642
695
|
},
|
|
643
696
|
"settings": {
|
|
644
697
|
"title": "Settings",
|
|
645
|
-
"
|
|
698
|
+
"back": "Back",
|
|
699
|
+
"account": "Account",
|
|
646
700
|
"general": {
|
|
647
701
|
"title": "General",
|
|
648
|
-
"lead": "Your
|
|
702
|
+
"lead": "Your profile and appearance.",
|
|
649
703
|
"colorMode": "Color mode",
|
|
650
704
|
"light": "Light",
|
|
651
705
|
"auto": "Auto",
|
|
652
706
|
"dark": "Dark",
|
|
653
707
|
"name": "Name",
|
|
654
|
-
"
|
|
708
|
+
"photo": "Photo",
|
|
709
|
+
"photoPlaceholder": "https://",
|
|
710
|
+
"photoHint": "A link to a square image, starting with https://. Leave it empty to show your initials.",
|
|
655
711
|
"email": "Email",
|
|
656
712
|
"save": "Save changes",
|
|
657
713
|
"saving": "Saving…",
|
|
658
714
|
"saved": "Saved.",
|
|
659
|
-
"unsaved": "Unsaved changes",
|
|
660
|
-
"clean": "No unsaved changes",
|
|
661
715
|
"nameRequired": "Enter your name.",
|
|
662
|
-
"saveError": "We couldn't save your
|
|
663
|
-
"
|
|
716
|
+
"saveError": "We couldn't save your changes. Try again.",
|
|
717
|
+
"photoInvalid": "Enter a link that starts with https://.",
|
|
718
|
+
"unverified": "Confirm your email address first, then try again.",
|
|
719
|
+
"unavailable": "Profile changes aren't available on this site yet.",
|
|
720
|
+
"contact": {
|
|
721
|
+
"title": "Contact details",
|
|
722
|
+
"lead": "Kept on this site, for the people you work with here.",
|
|
723
|
+
"givenName": "First name",
|
|
724
|
+
"familyName": "Last name",
|
|
725
|
+
"telephone": "Phone",
|
|
726
|
+
"address": "Address",
|
|
727
|
+
"companyName": "Company",
|
|
728
|
+
"jobTitle": "Job title",
|
|
729
|
+
"save": "Save contact details",
|
|
730
|
+
"saving": "Saving…",
|
|
731
|
+
"saved": "Saved.",
|
|
732
|
+
"addressIncomplete": "Fill in the address line, city, state or region, postal code and country, or clear the whole address.",
|
|
733
|
+
"unavailable": "Contact details aren't available on this site right now.",
|
|
734
|
+
"errors": {
|
|
735
|
+
"telephone": "Enter the phone number with its country code.",
|
|
736
|
+
"invalid": "Some of these details couldn't be saved. Check them and try again.",
|
|
737
|
+
"unverified": "Confirm your email address first, then try again.",
|
|
738
|
+
"unavailable": "Contact details can't be saved on this site yet.",
|
|
739
|
+
"failed": "We couldn't save your contact details. Try again."
|
|
740
|
+
}
|
|
741
|
+
}
|
|
664
742
|
},
|
|
665
743
|
"security": {
|
|
666
744
|
"title": "Security",
|
|
667
|
-
"
|
|
668
|
-
"
|
|
669
|
-
"
|
|
670
|
-
"
|
|
671
|
-
"
|
|
672
|
-
"
|
|
673
|
-
"
|
|
674
|
-
"
|
|
675
|
-
"
|
|
745
|
+
"methodsHeading": "Sign-in methods",
|
|
746
|
+
"passwordLabel": "Password",
|
|
747
|
+
"passwordSet": "Set",
|
|
748
|
+
"passwordNotSet": "Not set",
|
|
749
|
+
"setHint": "Add a password so you can also sign in with your email and password.",
|
|
750
|
+
"changeHint": "Change the password you sign in with.",
|
|
751
|
+
"setNote": "We'll email {email} a secure link to create your password.",
|
|
752
|
+
"changeNote": "We'll email {email} a secure link to change your password.",
|
|
753
|
+
"setButton": "Set password",
|
|
754
|
+
"changeButton": "Change password",
|
|
755
|
+
"sending": "Sending…",
|
|
756
|
+
"sent": "Link sent. It works once, for an hour. Saving a password signs you out everywhere.",
|
|
757
|
+
"sendFailed": "We couldn't send the email. Try again in a few minutes.",
|
|
758
|
+
"logOut": "Log out",
|
|
759
|
+
"logOutFailed": "Log out didn't finish. Try again.",
|
|
760
|
+
"signsInWith": "You sign in with {methods}.",
|
|
761
|
+
"signedInAs": "You're signed in as {email}.",
|
|
762
|
+
"methods": {
|
|
763
|
+
"google": "Google",
|
|
764
|
+
"github": "GitHub",
|
|
765
|
+
"magicLink": "a link sent to {email}",
|
|
766
|
+
"password": "your email and password"
|
|
767
|
+
},
|
|
768
|
+
"managedAt": "Your sign-in is managed at {hub}.",
|
|
769
|
+
"managedUnnamed": "Your sign-in is managed by our main site.",
|
|
770
|
+
"manageOnHub": "Manage sign-in on {hub}",
|
|
771
|
+
"passwordUnavailable": "We couldn't check your password settings."
|
|
676
772
|
},
|
|
677
773
|
"notifications": {
|
|
678
|
-
"title": "Notifications"
|
|
679
|
-
|
|
680
|
-
|
|
774
|
+
"title": "Notifications"
|
|
775
|
+
},
|
|
776
|
+
"signIn": {
|
|
777
|
+
"lead": "How you sign in to this site."
|
|
681
778
|
},
|
|
682
779
|
"privacy": {
|
|
683
|
-
"title": "Privacy",
|
|
684
780
|
"lead": "Cookies and your data.",
|
|
685
781
|
"cookies": "Cookie settings",
|
|
686
782
|
"deletion": "Request account deletion",
|
|
687
783
|
"deletionLead": "Ask the site owner to delete your account and its data. We'll confirm by email.",
|
|
688
|
-
"
|
|
784
|
+
"deletionSentSite": "Sent to the site operator. They'll confirm by email.",
|
|
785
|
+
"deletionSentHub": "Sent to the hub operator. They'll confirm by email.",
|
|
786
|
+
"deletionUnverified": "Confirm your email address first, then ask again.",
|
|
787
|
+
"deletionUnavailable": "This site can't take deletion requests right now.",
|
|
689
788
|
"deletionError": "We couldn't send your request. Try again in a moment.",
|
|
690
|
-
"
|
|
691
|
-
"
|
|
789
|
+
"deletionViaSupport": "To ask for your account to be deleted, contact support.",
|
|
790
|
+
"deletionSupportLink": "Contact support"
|
|
692
791
|
},
|
|
693
792
|
"billing": {
|
|
694
793
|
"title": "Billing",
|
|
695
|
-
"lead": "Your
|
|
696
|
-
"
|
|
697
|
-
"
|
|
794
|
+
"lead": "Your plan and payment method.",
|
|
795
|
+
"currentPlan": "Current plan",
|
|
796
|
+
"unnamedPlan": "Your subscription",
|
|
797
|
+
"accessEnds": "Access ends {date}",
|
|
798
|
+
"card": "{brand} ending in {last4}, expires {month}/{year}",
|
|
799
|
+
"noCard": "No card on file",
|
|
698
800
|
"manage": "Manage billing",
|
|
801
|
+
"none": "You don't have a subscription.",
|
|
802
|
+
"unavailable": "We couldn't load your billing details.",
|
|
803
|
+
"unreadable": "Some of your billing is with another Stripe account, so it isn't shown here.",
|
|
699
804
|
"statuses": {
|
|
700
805
|
"trialing": "Trial",
|
|
701
806
|
"active": "Active",
|
|
@@ -731,7 +836,19 @@
|
|
|
731
836
|
"offer": "Offer",
|
|
732
837
|
"amount": "Amount",
|
|
733
838
|
"period": "Period",
|
|
734
|
-
"date": "Date"
|
|
839
|
+
"date": "Date",
|
|
840
|
+
"unavailable": "Not recorded"
|
|
841
|
+
},
|
|
842
|
+
"appointments": {
|
|
843
|
+
"heading": "My appointments",
|
|
844
|
+
"untitled": "Appointment",
|
|
845
|
+
"starts": "Starts",
|
|
846
|
+
"ends": "Ends",
|
|
847
|
+
"statuses": {
|
|
848
|
+
"pending": "Pending",
|
|
849
|
+
"confirmed": "Confirmed",
|
|
850
|
+
"cancelled": "Cancelled"
|
|
851
|
+
}
|
|
735
852
|
},
|
|
736
853
|
"pieces": {
|
|
737
854
|
"heading": "My pieces",
|
|
@@ -750,6 +867,50 @@
|
|
|
750
867
|
"subscription": {
|
|
751
868
|
"headline": "Your payment didn't go through",
|
|
752
869
|
"action": "Update payment method"
|
|
870
|
+
},
|
|
871
|
+
"new": {
|
|
872
|
+
"trigger": "New",
|
|
873
|
+
"close": "Close",
|
|
874
|
+
"loading": "Loading…",
|
|
875
|
+
"loadFailed": "This could not load.",
|
|
876
|
+
"retry": "Try again",
|
|
877
|
+
"submitting": "Sending…",
|
|
878
|
+
"optional": "Optional",
|
|
879
|
+
"actions": {
|
|
880
|
+
"scheduleService": "Schedule service",
|
|
881
|
+
"requestQuote": "Request quote",
|
|
882
|
+
"sendMessage": "Send message"
|
|
883
|
+
},
|
|
884
|
+
"schedule": {
|
|
885
|
+
"service": "Service",
|
|
886
|
+
"duration": "{minutes} min",
|
|
887
|
+
"time": "Time",
|
|
888
|
+
"notes": "Notes",
|
|
889
|
+
"submit": "Book",
|
|
890
|
+
"none": "No times are offered right now. You can send a message instead.",
|
|
891
|
+
"suggest": "Send a message",
|
|
892
|
+
"noSlots": "No open times in the next 14 days."
|
|
893
|
+
},
|
|
894
|
+
"quote": {
|
|
895
|
+
"submit": "Send request"
|
|
896
|
+
},
|
|
897
|
+
"message": {
|
|
898
|
+
"subject": "Subject",
|
|
899
|
+
"body": "Message",
|
|
900
|
+
"link": "Link",
|
|
901
|
+
"linkHelp": "Must start with https://.",
|
|
902
|
+
"submit": "Send"
|
|
903
|
+
},
|
|
904
|
+
"errors": {
|
|
905
|
+
"linkNotHttps": "A link must start with https://.",
|
|
906
|
+
"answersInvalid": "Some answers do not fit this form. Check them and try again.",
|
|
907
|
+
"requestFormOff": "Requests are switched off right now.",
|
|
908
|
+
"meetingTypeNotOffered": "This service is no longer offered.",
|
|
909
|
+
"slotUnavailable": "That time was just taken. Pick another.",
|
|
910
|
+
"tooManyRequests": "Too many requests. Try again later.",
|
|
911
|
+
"invalidInput": "Check what you entered and try again.",
|
|
912
|
+
"failed": "This could not be sent. Try again."
|
|
913
|
+
}
|
|
753
914
|
}
|
|
754
915
|
},
|
|
755
916
|
"admin": {
|
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @working-theory/database
|
|
2
2
|
|
|
3
|
+
## 0.40.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#8497](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/8497) [`52df359`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/52df359fb2a4d1aff488136126dba16d13e49a26) Thanks [@samuelhenry](https://github.com/samuelhenry)! - Contact details on the client record ([#8435](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/8435), spec docs/specs/8435-contact-details-on-the-client-spec.md).
|
|
8
|
+
|
|
9
|
+
A Person now carries a given name, a family name, an E.164 telephone, a six-part address, a company name and a job title, with the two columns that say who last saved them by hand. `callbacks` and `subscribers` gain a `person_id` foreign key. A capture fills only a blank field of an uncurated Person; the operator edits the contact from the Person page and a client edits their own on the site, from the account General tab. A magnet field's `mapsTo` tag names the contact field it fills: `email`, `name`, `givenName`, `familyName`, `phone`, `address`, `company`, `jobTitle`. Additive; the migration (`20261014120000_person_contact`, its second half the idempotent backfill) deploys before the code.
|
|
10
|
+
|
|
11
|
+
- [#8490](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/8490) [`64adcf9`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/64adcf9b58a3f3be3b42782e14018234b263b9bc) Thanks [@samuelhenry](https://github.com/samuelhenry)! - The consent ledger ([#8438](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/8438), the API half). The per-site consent registry gains a kind (`agreement` · `consent` · `preference`), a plain description, a policy link and a policy version per purpose, and its platform default now declares `service_terms`, `account_terms` and `analytics_cookies`; a registry stored before this change still parses and means what it meant. `consent_grants` becomes the one ledger: each row names its source (`cookie_banner` · `sign_up` · `magnet` · `account_settings` · `email_unsubscribe` · `api`), its policy version and, when known, its Person, and the database refuses to change or truncate a stored row. A new `consent_visitor_links` table joins a banner visitor to the Person a later form identifies. `@working-theory/api-client` gains `consent.recordCookieChoice`, `consent.unsubscribe`, `member.consents` and `member.setConsent`; `@working-theory/validation` gains their wire schemas and the `platform-consents` permission. Run the new migration before deploying code that writes the ledger.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`52df359`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/52df359fb2a4d1aff488136126dba16d13e49a26), [`64adcf9`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/64adcf9b58a3f3be3b42782e14018234b263b9bc)]:
|
|
16
|
+
- @working-theory/validation@0.40.0
|
|
17
|
+
- @working-theory/ids@0.13.0
|
|
18
|
+
|
|
19
|
+
## 0.39.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- [#8177](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/8177) [`6fa07d3`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/6fa07d36321033e1661de34eaee8427eb7e1a6ca) Thanks [@samuelhenry](https://github.com/samuelhenry)! - The member area data model ([#8168](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/8168)): the schema and wire contract the member reads, member writes and provider routes build on. No route changes.
|
|
24
|
+
|
|
25
|
+
- `@working-theory/database` — `PieceVersion` (`piece_versions`): one delivery of a piece to its client, a private file or an https link, numbered per piece, with the client's review on it; held to its shape by CHECKs and by one composite foreign key onto `pieces(id, person_id, workspace_id)`. `Piece.approvedAt`. `Interaction.kind` (`message` · `quote` · `review`) and `payload`, and `inbound` beside `outbound`; an outbound row stays a payload-free `message`. `FlowDefinition.customersEnabled`. Migration `20261012120000_member_contract` backfills a draft `request-quote` contact magnet into every workspace, never overwriting an existing one, and `db:seed` gives the default workspace the same magnet.
|
|
26
|
+
- `@working-theory/validation` — the Phase 1 member contract in `member.ts`: reads, writes, write responses, the stored payloads, the vocabularies and `memberErrorCodeSchema`, and `isHttpsLink`. `requestQuoteFlowConfig`, `REQUEST_QUOTE_FLOW_SLUG`, `REQUEST_QUOTE_FLOW_TITLE`, `flowCustomersEnabledSchema` and `FLOW_CUSTOMERS_ENABLED_DEFAULT` in `flow.ts`. `plainText` is exported. `subscriptionMeResponseSchema` gains optional `planName` and `paymentMethod`; today's body still parses.
|
|
27
|
+
- `@working-theory/site-config` — `MeetingsSchema` gains optional `customerSlugs` (no default, duplicates refused).
|
|
28
|
+
- `@working-theory/ids` — the `pver_` prefix (`pieceVersion`).
|
|
29
|
+
|
|
30
|
+
- [#8235](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/8235) [`2f8a0fe`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/2f8a0fed78739b758f9db44caecbb297e009d841) Thanks [@samuelhenry](https://github.com/samuelhenry)! - `Lead.spokeCheckout` ([#8185](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/8185)): a `leads.spoke_checkout BOOLEAN NOT NULL DEFAULT false` column, migration `20261013120000_lead_spoke_checkout`. The hub sets it at creation for a spoke's live paid checkout lead (a registered spoke's key, not relayed, a `cs_live_` Idempotency-Key and the checkout shape) and never updates it. Existing rows read false; there is no backfill. Apply the migration before deploying the API that writes it.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- [#8321](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/8321) [`f17db78`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/f17db78cc14671473c976d4098b1bdc001f517be) Thanks [@samuelhenry](https://github.com/samuelhenry)! - Licence metadata only: `LICENSE` is now the canonical, unmodified Apache-2.0 text, and the package ships a `NOTICE` file carrying the copyright notice (`Copyright 2026 SalesSmyth LLC`). The previous `LICENSE` appendix named a stale holder. No behavior change.
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [[`6fb73eb`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/6fb73eb106836a6d201111f460de0811711a1f39), [`6fa07d3`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/6fa07d36321033e1661de34eaee8427eb7e1a6ca), [`55567c6`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/55567c678b2338523959569457499531c6aac374), [`f17db78`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/f17db78cc14671473c976d4098b1bdc001f517be), [`caeffba`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/caeffba335a8c8f232cedc901babfb6674e319f5)]:
|
|
37
|
+
- @working-theory/validation@0.39.0
|
|
38
|
+
- @working-theory/ids@0.12.0
|
|
39
|
+
|
|
3
40
|
## 0.38.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
Apache License
|
|
2
3
|
Version 2.0, January 2004
|
|
3
4
|
http://www.apache.org/licenses/
|
|
@@ -137,8 +138,8 @@
|
|
|
137
138
|
|
|
138
139
|
6. Trademarks. This License does not grant permission to use the trade
|
|
139
140
|
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
-
except as required for
|
|
141
|
-
reproducing the content of the NOTICE file.
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
143
|
|
|
143
144
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
145
|
agreed to in writing, Licensor provides the Work (and each
|
|
@@ -162,7 +163,7 @@
|
|
|
162
163
|
other commercial damages or losses), even if such Contributor
|
|
163
164
|
has been advised of the possibility of such damages.
|
|
164
165
|
|
|
165
|
-
9. Accepting Warranty or
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
167
|
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
168
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
169
|
or other liability obligations and/or rights consistent with this
|
|
@@ -171,7 +172,7 @@
|
|
|
171
172
|
of any other Contributor, and only if You agree to indemnify,
|
|
172
173
|
defend, and hold each Contributor harmless for any liability
|
|
173
174
|
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
-
of your accepting any such warranty or
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
175
176
|
|
|
176
177
|
END OF TERMS AND CONDITIONS
|
|
177
178
|
|
|
@@ -186,7 +187,7 @@
|
|
|
186
187
|
same "printed page" as the copyright notice for easier
|
|
187
188
|
identification within third-party archives.
|
|
188
189
|
|
|
189
|
-
Copyright
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
191
|
|
|
191
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
193
|
you may not use this file except in compliance with the License.
|
|
@@ -69,7 +69,7 @@ model RefreshToken {
|
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
# Mobile app authenticates with token
|
|
72
|
-
curl -H "Authorization: Bearer
|
|
72
|
+
curl -H "Authorization: Bearer <access-token>" \
|
|
73
73
|
https://api.customer-site.com/api/user/profile
|
|
74
74
|
|
|
75
75
|
# Refresh expired access token
|