create-ailk 0.23.0 → 0.24.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 +27 -14
- package/dist/add-module.js +6 -1
- package/dist/add-route.js +7 -1
- package/dist/derive-architecture.js +17 -0
- package/dist/lib/scaffold-render-sweep.d.ts +33 -0
- package/dist/lib/scaffold-render-sweep.js +45 -0
- package/dist/module-architecture.js +17 -0
- package/dist/sync-routes.d.ts +30 -4
- package/dist/sync-routes.js +271 -18
- package/package.json +3 -3
- package/templates/.env.example +4 -0
- package/templates/CLAUDE.md +4 -2
- package/templates/apps/api/.env.example +7 -0
- package/templates/apps/api/CLAUDE.md +25 -11
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +4 -1
- package/templates/apps/api/src/lib/__tests__/site.test.ts +16 -0
- package/templates/apps/api/src/lib/site.ts +4 -1
- package/templates/apps/api/src/lib/stripe.ts +3 -0
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +127 -0
- package/templates/apps/api/src/openapi/spec.ts +333 -0
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +18 -11
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +126 -0
- package/templates/apps/api/src/routes/content/get-page.ts +34 -119
- package/templates/apps/api/src/routes/content/list-pages.ts +15 -36
- package/templates/apps/api/src/routes/content/search.ts +16 -45
- package/templates/apps/api/src/routes/leads/index.ts +364 -298
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +20 -9
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +17 -6
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +1 -1
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +1 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +2 -0
- package/templates/apps/api/src/server.ts +25 -0
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +121 -4
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +10 -0
- package/templates/apps/api/src/services/__tests__/person.test.ts +28 -0
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +6 -0
- package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +202 -0
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +15 -18
- package/templates/apps/api/src/services/abandon-email.ts +28 -5
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +2 -7
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +53 -0
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +107 -0
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +4 -0
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +4 -0
- package/templates/apps/api/src/services/offerings/catalog.ts +10 -0
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +23 -5
- package/templates/apps/api/src/services/offerings/connection.ts +83 -3
- package/templates/apps/api/src/services/offerings/index.ts +6 -6
- package/templates/apps/api/src/services/person.ts +23 -0
- package/templates/apps/api/src/services/project-listings.ts +43 -31
- package/templates/apps/mcp/CLAUDE.md +11 -5
- package/templates/apps/mcp/__tests__/app-entry.test.ts +2 -2
- package/templates/apps/mcp/__tests__/http-transport.test.ts +91 -10
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +8 -3
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -25
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +22 -7
- package/templates/apps/mcp/__tests__/list_pages.test.ts +84 -44
- package/templates/apps/mcp/__tests__/locale.test.ts +41 -56
- package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +189 -0
- package/templates/apps/mcp/__tests__/read_content.test.ts +115 -78
- package/templates/apps/mcp/__tests__/request_callback.test.ts +63 -128
- package/templates/apps/mcp/__tests__/search_content.test.ts +76 -61
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +82 -167
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +59 -130
- package/templates/apps/mcp/package.json +1 -0
- package/templates/apps/mcp/src/abuse/index.ts +18 -11
- package/templates/apps/mcp/src/http-transport.ts +47 -9
- package/templates/apps/mcp/src/lib/content-adapter.ts +0 -26
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +5 -4
- package/templates/apps/mcp/src/lib/site-config.ts +53 -0
- package/templates/apps/mcp/src/tools/capture_lead.ts +30 -28
- package/templates/apps/mcp/src/tools/index.ts +22 -21
- package/templates/apps/mcp/src/tools/list_pages.ts +27 -33
- package/templates/apps/mcp/src/tools/read_content.ts +46 -40
- package/templates/apps/mcp/src/tools/request_callback.ts +21 -28
- package/templates/apps/mcp/src/tools/search_content.ts +20 -24
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +23 -26
- package/templates/apps/web/CLAUDE.md +12 -3
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +14 -4
- package/templates/apps/web/app/[locale]/contact/intake-script.ts +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +21 -4
- package/templates/apps/web/lib/__tests__/magnet-routes.test.ts +7 -0
- package/templates/apps/web/lib/magnet-routes.ts +3 -1
- package/templates/apps/web/lib/newsletter.actions.ts +9 -6
- package/templates/database/CHANGELOG.md +20 -0
- package/templates/database/__tests__/seed.test.ts +33 -1
- package/templates/database/__tests__/trial-magnet-migration.test.ts +186 -0
- package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +28 -0
- package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +23 -0
- package/templates/database/package.json +1 -1
- package/templates/database/seed.ts +27 -0
- package/templates/tools/lint-architecture.ts +205 -1
- package/versions.json +34 -34
- package/templates/apps/api/src/routes/content/slug.ts +0 -9
package/README.md
CHANGED
|
@@ -214,9 +214,9 @@ as-is, they never fail the check, and `--apply` never overwrites them.
|
|
|
214
214
|
|
|
215
215
|
`--apply` only creates route directories that are absent, through the same
|
|
216
216
|
copier a fresh scaffold uses (so the copied files are byte-identical to a fresh
|
|
217
|
-
scaffold's). It never rewrites or deletes an existing file,
|
|
218
|
-
outside `apps/web/app/[locale]
|
|
219
|
-
no-op. `--apply` exits 0 on success.
|
|
217
|
+
scaffold's). It never rewrites or deletes an existing file, writes nothing
|
|
218
|
+
outside `apps/web/app/[locale]/` except the local modules those routes import
|
|
219
|
+
(below), runs no install, and a second run is a no-op. `--apply` exits 0 on success.
|
|
220
220
|
|
|
221
221
|
**Scope.** Every core route (`about`, `contact`, `faq`, `thanks/[slug]`,
|
|
222
222
|
`sign-in`) is always checked, and so is the `(authed)` route GROUP —
|
|
@@ -232,17 +232,30 @@ gated off at scaffold time is listed as skipped, not missing — its absence is
|
|
|
232
232
|
deliberate, not drift. Add a surface with `--sync-architecture` and the
|
|
233
233
|
`add-page` skill, not with `sync-routes`.
|
|
234
234
|
|
|
235
|
-
**The
|
|
236
|
-
files OUTSIDE their own route directory — `
|
|
237
|
-
`apps/web/lib/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
235
|
+
**The local-module dependency contract (#5014, #9406).** Some routes import
|
|
236
|
+
files OUTSIDE their own route directory — `purchase/success/page.tsx` imports
|
|
237
|
+
`apps/web/src/lib/commerce-claim.ts`; the `(authed)` group's `layout.tsx`
|
|
238
|
+
imports `apps/web/auth.ts`. Copying a route's directory alone would leave those
|
|
239
|
+
imports dangling in an older consumer that never had them. So `sync-routes`
|
|
240
|
+
resolves every relative import (`./`, `../`) of every file the route would
|
|
241
|
+
copy, and of every helper that brings in turn, against the site first and then
|
|
242
|
+
the template. `ROUTE_DEPENDENCIES` in `src/surfaces.ts` is a declared
|
|
243
|
+
supplement, unioned with what the resolver finds. Each imported module has one
|
|
244
|
+
of three outcomes:
|
|
245
|
+
|
|
246
|
+
- **Copied** — the site lacks it and the template has it: `--apply` copies it
|
|
247
|
+
(never overwriting) and check mode lists it under `copies:` and `Also
|
|
248
|
+
required`.
|
|
249
|
+
- **Left as-is** — the site has it and its copy differs from the template's:
|
|
250
|
+
it is named under `left as-is (differs from the template)` and never
|
|
251
|
+
written. The route is still copied; run your type-check afterwards.
|
|
252
|
+
- **Refused** — the import resolves to no file in the site or the template,
|
|
253
|
+
only to a spoke-excluded file, or to a surface the site does not carry: the
|
|
254
|
+
route is listed under `cannot resolve:` and `--apply` does not write it, nor
|
|
255
|
+
its sub-routes, nor a route that imports from it. Its ancestor route is still
|
|
256
|
+
copied without the refused sub-tree.
|
|
257
|
+
|
|
258
|
+
`ROUTE_MESSAGE_NAMESPACES`
|
|
246
259
|
does the same for the i18n namespaces a route's copy needs
|
|
247
260
|
(`signIn`, `account`, `waitlistDashboard.gate`) — but CHECK-ONLY: a
|
|
248
261
|
consumer's `apps/web/messages/<locale>.json` already exists and may carry
|
package/dist/add-module.js
CHANGED
|
@@ -351,7 +351,9 @@ export function formatAddModuleReport(result, moduleName) {
|
|
|
351
351
|
const lines = [
|
|
352
352
|
`[create-ailk] add-module ${moduleName} → ${result.targetDir}`,
|
|
353
353
|
];
|
|
354
|
-
if (result.report.length === 0 &&
|
|
354
|
+
if (result.report.length === 0 &&
|
|
355
|
+
result.routes.applied.length === 0 &&
|
|
356
|
+
result.routes.refused.length === 0) {
|
|
355
357
|
lines.push(`Nothing to add — the site already carries everything ${moduleName} brings.`);
|
|
356
358
|
}
|
|
357
359
|
if (written.length > 0) {
|
|
@@ -387,6 +389,9 @@ export function formatAddModuleReport(result, moduleName) {
|
|
|
387
389
|
lines.push(`Also copied ${routes.appliedDependencies.length} file(s) those routes import:`);
|
|
388
390
|
lines.push(...routes.appliedDependencies.map((dep) => ` ${dep}`));
|
|
389
391
|
}
|
|
392
|
+
if (routes.refused.length > 0) {
|
|
393
|
+
lines.push(`Routes not copied (${routes.refused.length}) — an import does not resolve (run create-ailk sync-routes for the paths): ${routes.refused.join(", ")}`);
|
|
394
|
+
}
|
|
390
395
|
if (routes.missingMessageNamespaces.length > 0) {
|
|
391
396
|
lines.push("Also required — message namespace(s) not found in apps/web/messages/en.json (add manually, not auto-merged):");
|
|
392
397
|
lines.push(...routes.missingMessageNamespaces.map((ns) => ` ${ns}`));
|
package/dist/add-route.js
CHANGED
|
@@ -226,13 +226,16 @@ export function formatAddRouteReport(result) {
|
|
|
226
226
|
const skipped = result.report.filter((row) => row.action === "skipped");
|
|
227
227
|
const routes = result.routes ?? {
|
|
228
228
|
applied: [],
|
|
229
|
+
refused: [],
|
|
229
230
|
appliedDependencies: [],
|
|
230
231
|
missingMessageNamespaces: [],
|
|
231
232
|
};
|
|
232
233
|
const lines = [
|
|
233
234
|
`[create-ailk] add-route ${result.route} → ${result.targetDir}`,
|
|
234
235
|
];
|
|
235
|
-
if (result.report.length === 0 &&
|
|
236
|
+
if (result.report.length === 0 &&
|
|
237
|
+
routes.applied.length === 0 &&
|
|
238
|
+
routes.refused.length === 0) {
|
|
236
239
|
lines.push(`Nothing to add — the site already carries the ${result.route} route.`);
|
|
237
240
|
}
|
|
238
241
|
if (routes.applied.length > 0) {
|
|
@@ -243,6 +246,9 @@ export function formatAddRouteReport(result) {
|
|
|
243
246
|
lines.push(`Also copied ${routes.appliedDependencies.length} file(s) those routes import:`);
|
|
244
247
|
lines.push(...routes.appliedDependencies.map((dep) => ` ${dep}`));
|
|
245
248
|
}
|
|
249
|
+
if (routes.refused.length > 0) {
|
|
250
|
+
lines.push(`Routes not copied (${routes.refused.length}) — an import does not resolve (run create-ailk sync-routes for the paths): ${routes.refused.join(", ")}`);
|
|
251
|
+
}
|
|
246
252
|
if (written.length > 0) {
|
|
247
253
|
lines.push(`Written (${written.length}):`);
|
|
248
254
|
lines.push(...written.map((row) => ` ${row.path}`));
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { ARCHITECTURE_BASE, MODULE_SLICES, normalizeModules, } from "./module-architecture.js";
|
|
17
17
|
import { CORE_SURFACE_PATHS, RECOGNIZED_SURFACES, resolveSurfaces, } from "./surfaces.js";
|
|
18
|
+
/** The npm scope a site consumes and never forks (#9191). */
|
|
19
|
+
const PACKAGE_SCOPE = "@working-theory/";
|
|
18
20
|
/** A spoke's composition tiers (#7426 D8): its data and API are the hub's. */
|
|
19
21
|
const SPOKE_TIERS = {
|
|
20
22
|
data: "none — the hub's database",
|
|
@@ -314,6 +316,20 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
314
316
|
for (const s of slices)
|
|
315
317
|
extraForbidden.push(...(s.forbiddenPatterns ?? []));
|
|
316
318
|
const forbidden = mergeForbidden([...ARCHITECTURE_BASE.forbiddenPatterns], extraForbidden).map(scoped);
|
|
319
|
+
// The upgradeable-consumer rules (#9191): the workspaces this scaffold
|
|
320
|
+
// creates and the in-scope package names it gives them. The site lint
|
|
321
|
+
// reads this block to refuse a forked, patched or pinned-off package.
|
|
322
|
+
// Every app the scaffold ships is named `@working-theory/<dir>`.
|
|
323
|
+
const upgradeableConsumer = {
|
|
324
|
+
package_scope: PACKAGE_SCOPE,
|
|
325
|
+
workspaces: spoke ? ["apps/*"] : ["apps/*", "database"],
|
|
326
|
+
scaffold_packages: [
|
|
327
|
+
...(spoke ? [] : ["database"]),
|
|
328
|
+
...Object.keys(apps),
|
|
329
|
+
]
|
|
330
|
+
.map((dir) => `${PACKAGE_SCOPE}${dir}`)
|
|
331
|
+
.sort(),
|
|
332
|
+
};
|
|
317
333
|
const doc = {
|
|
318
334
|
version: ARCHITECTURE_BASE.version,
|
|
319
335
|
...(spoke ? { topology: "spoke" } : {}),
|
|
@@ -330,6 +346,7 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
330
346
|
apps,
|
|
331
347
|
...(nsSlice ? { namespaces: namespacesToYaml(nsSlice) } : {}),
|
|
332
348
|
forbidden_patterns: forbidden.map(forbiddenToYaml),
|
|
349
|
+
upgradeable_consumer: upgradeableConsumer,
|
|
333
350
|
};
|
|
334
351
|
const header = [
|
|
335
352
|
"# Architecture Boundaries — AI Launch Kit site",
|
|
@@ -21,6 +21,39 @@ export declare const MAX_REDIRECTS = 5;
|
|
|
21
21
|
* so each entry must answer exactly 404. A 200 means the gate stopped gating.
|
|
22
22
|
*/
|
|
23
23
|
export declare const CLAIM_GATED_ROUTES: Readonly<Record<string, string>>;
|
|
24
|
+
/**
|
|
25
|
+
* Routes whose answer depends on whether the site has a hub to ask (#9423),
|
|
26
|
+
* and the flow each one sells. With no API origin configured the flow read
|
|
27
|
+
* is `not-configured` and the route must answer exactly 404 — the no-hub
|
|
28
|
+
* 404 where the module that owns it is installed, Next's own 404 where it
|
|
29
|
+
* is not. With one configured it must render its own content.
|
|
30
|
+
*/
|
|
31
|
+
export declare const HUB_GATED_ROUTES: Readonly<Record<string, string>>;
|
|
32
|
+
/**
|
|
33
|
+
* The API origin names `apps/web` reads, in step with `apiOriginConfigured()`
|
|
34
|
+
* in `apps/web/app/[locale]/flows/[slug]/magnet-page.tsx`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const HUB_ORIGIN_ENV_NAMES: readonly ["AILK_API_URL", "NEXT_PUBLIC_AILK_API_URL", "NEXT_PUBLIC_API_URL"];
|
|
37
|
+
/**
|
|
38
|
+
* Whether a served `apps/web` has an API origin: a non-empty value for one
|
|
39
|
+
* of `HUB_ORIGIN_ENV_NAMES` in the serve environment or assigned in one of
|
|
40
|
+
* the env files Next loads (`envFileTexts`).
|
|
41
|
+
*/
|
|
42
|
+
export declare function hubOriginConfigured(env: Readonly<Record<string, string | undefined>>, envFileTexts: string[]): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* A `HUB_GATED_ROUTES` entry. Hub configured: the page must render its own
|
|
45
|
+
* content (`assessPageRender`). No hub: exactly 404 with no redirect — a 200
|
|
46
|
+
* means the no-hub branch stopped running.
|
|
47
|
+
*/
|
|
48
|
+
export declare function assessHubGatedRoute(input: {
|
|
49
|
+
route: string;
|
|
50
|
+
hubConfigured: boolean;
|
|
51
|
+
hops: RedirectHop[];
|
|
52
|
+
status: number | null;
|
|
53
|
+
contentType: string | null;
|
|
54
|
+
html: string;
|
|
55
|
+
locale: string;
|
|
56
|
+
}): SweepVerdict;
|
|
24
57
|
/**
|
|
25
58
|
* A route whose live page needs an env var the driver never sets (#6146).
|
|
26
59
|
* While it is unset the route serves its Free placeholder seed instead
|
|
@@ -37,6 +37,51 @@ export const CLAIM_GATED_ROUTES = {
|
|
|
37
37
|
"/purchase/success": "commerce",
|
|
38
38
|
"/purchase/cancel": "commerce",
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Routes whose answer depends on whether the site has a hub to ask (#9423),
|
|
42
|
+
* and the flow each one sells. With no API origin configured the flow read
|
|
43
|
+
* is `not-configured` and the route must answer exactly 404 — the no-hub
|
|
44
|
+
* 404 where the module that owns it is installed, Next's own 404 where it
|
|
45
|
+
* is not. With one configured it must render its own content.
|
|
46
|
+
*/
|
|
47
|
+
export const HUB_GATED_ROUTES = {
|
|
48
|
+
"/trial": "trial",
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The API origin names `apps/web` reads, in step with `apiOriginConfigured()`
|
|
52
|
+
* in `apps/web/app/[locale]/flows/[slug]/magnet-page.tsx`.
|
|
53
|
+
*/
|
|
54
|
+
export const HUB_ORIGIN_ENV_NAMES = ["AILK_API_URL", "NEXT_PUBLIC_AILK_API_URL", "NEXT_PUBLIC_API_URL"];
|
|
55
|
+
/**
|
|
56
|
+
* Whether a served `apps/web` has an API origin: a non-empty value for one
|
|
57
|
+
* of `HUB_ORIGIN_ENV_NAMES` in the serve environment or assigned in one of
|
|
58
|
+
* the env files Next loads (`envFileTexts`).
|
|
59
|
+
*/
|
|
60
|
+
export function hubOriginConfigured(env, envFileTexts) {
|
|
61
|
+
if (HUB_ORIGIN_ENV_NAMES.some((name) => Boolean(env[name])))
|
|
62
|
+
return true;
|
|
63
|
+
return envFileTexts.some((text) => HUB_ORIGIN_ENV_NAMES.some((name) => new RegExp(`^\\s*(?:export\\s+)?${name}\\s*=\\s*["']?[^\\s"'#]`, "m").test(text)));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A `HUB_GATED_ROUTES` entry. Hub configured: the page must render its own
|
|
67
|
+
* content (`assessPageRender`). No hub: exactly 404 with no redirect — a 200
|
|
68
|
+
* means the no-hub branch stopped running.
|
|
69
|
+
*/
|
|
70
|
+
export function assessHubGatedRoute(input) {
|
|
71
|
+
const { route, hubConfigured, hops, status, contentType, html, locale } = input;
|
|
72
|
+
const flow = HUB_GATED_ROUTES[route];
|
|
73
|
+
if (hubConfigured) {
|
|
74
|
+
const rendered = assessPageRender({ route, hops, status, contentType, html, locale });
|
|
75
|
+
return { ok: rendered.ok, reason: `${rendered.reason} (hub-gated: ${flow}, hub configured)` };
|
|
76
|
+
}
|
|
77
|
+
if (hops.length > 0 || status !== 404) {
|
|
78
|
+
const first = hops[0];
|
|
79
|
+
const seen = first ? `${first.status} redirect` : `status ${status}`;
|
|
80
|
+
const why = status === 200 ? "rendered with no hub to ask" : `expected 404, got ${seen}`;
|
|
81
|
+
return { ok: false, reason: `${route} -> ${why} (hub-gated: ${flow}, no hub)` };
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, reason: `404 (hub-gated: ${flow}, no hub)` };
|
|
84
|
+
}
|
|
40
85
|
/**
|
|
41
86
|
* A route whose live page needs an env var the driver never sets (#6146).
|
|
42
87
|
* While it is unset the route serves its Free placeholder seed instead
|
|
@@ -863,6 +863,13 @@ export const MODULE_SLICES = {
|
|
|
863
863
|
// tenant-db.ts import, co-owned with `workspace` for the same reason.
|
|
864
864
|
"apps/api/src/routes/workspaces/orders.ts",
|
|
865
865
|
"apps/api/src/services/inbox-orders.ts",
|
|
866
|
+
// #9254 DD5 — the Inbox callbacks read: the same gate and the same
|
|
867
|
+
// tenant-db.ts import, co-owned with `workspace` for the same reason.
|
|
868
|
+
"apps/api/src/routes/workspaces/callbacks.ts",
|
|
869
|
+
// #9287 DD2 — Start, Get and Extend trial: the same gate and the same
|
|
870
|
+
// tenant-db.ts import, co-owned with `workspace` for the same reason.
|
|
871
|
+
"apps/api/src/routes/workspaces/trial.ts",
|
|
872
|
+
"apps/api/src/services/trial.ts",
|
|
866
873
|
// #852 D8 — the People reads: the same workspace||multi-tenant gate and
|
|
867
874
|
// the same tenant-db.ts import, co-owned with `workspace` for the same
|
|
868
875
|
// reason.
|
|
@@ -1035,6 +1042,11 @@ export const MODULE_SLICES = {
|
|
|
1035
1042
|
// Co-owned with `multi-tenant` (#9170), as the reads above.
|
|
1036
1043
|
"apps/api/src/routes/workspaces/orders.ts",
|
|
1037
1044
|
"apps/api/src/services/inbox-orders.ts",
|
|
1045
|
+
// Co-owned with `multi-tenant` (#9254 DD5), as the reads above.
|
|
1046
|
+
"apps/api/src/routes/workspaces/callbacks.ts",
|
|
1047
|
+
// Co-owned with `multi-tenant` (#9287 DD2), as the reads above.
|
|
1048
|
+
"apps/api/src/routes/workspaces/trial.ts",
|
|
1049
|
+
"apps/api/src/services/trial.ts",
|
|
1038
1050
|
// Co-owned with `multi-tenant` (#852 D8), as the reads above.
|
|
1039
1051
|
"apps/api/src/routes/workspaces/people.ts",
|
|
1040
1052
|
// Co-owned with `multi-tenant` (#7877 D9, D11) — see that slice's entry.
|
|
@@ -1719,6 +1731,11 @@ export const MODULE_SLICES = {
|
|
|
1719
1731
|
// its siblings (the note above).
|
|
1720
1732
|
"apps/web/app/[locale]/careers/apply/page.tsx",
|
|
1721
1733
|
"apps/web/app/[locale]/careers/[slug]/apply/page.tsx",
|
|
1734
|
+
// #9287 DD10 — the trial magnet pair. Its own `trial` route segment,
|
|
1735
|
+
// which no surface gates, so `ownedFiles` keeps both pages out of a
|
|
1736
|
+
// keyless scaffold, beside the careers walks.
|
|
1737
|
+
"apps/web/app/[locale]/trial/page.tsx",
|
|
1738
|
+
"apps/web/app/[locale]/trial/request/page.tsx",
|
|
1722
1739
|
// #5581 U4 — the eleven signal-collectors components + the slice's own
|
|
1723
1740
|
// re-export entry point moved to packages-paid/ui-signal-collectors;
|
|
1724
1741
|
// the package is delivered to a keyed scaffold via `patches` below,
|
package/dist/sync-routes.d.ts
CHANGED
|
@@ -49,12 +49,23 @@ export interface SyncRoutesResult {
|
|
|
49
49
|
missing: RouteReport[];
|
|
50
50
|
/** Route dirs present but with a direct file absent or changed, sorted. */
|
|
51
51
|
modified: RouteReport[];
|
|
52
|
-
/** Route dirs copied this run (the missing list when applying, else empty). */
|
|
52
|
+
/** Route dirs copied this run (the missing list minus `refused` when applying, else empty). */
|
|
53
53
|
applied: string[];
|
|
54
54
|
/**
|
|
55
|
-
* `
|
|
56
|
-
*
|
|
57
|
-
|
|
55
|
+
* Missing routes `--apply` does not write because an import does not
|
|
56
|
+
* resolve (#9406 DD4) — reported in check mode too. Sorted.
|
|
57
|
+
*/
|
|
58
|
+
refused: string[];
|
|
59
|
+
/**
|
|
60
|
+
* Per missing route, the local modules its files import (#9406 DD5): one
|
|
61
|
+
* entry per route with any non-empty list, sorted by route.
|
|
62
|
+
*/
|
|
63
|
+
routeImports: RouteImportReport[];
|
|
64
|
+
/**
|
|
65
|
+
* Files, of any route in `missing` not `refused`, absent from the target:
|
|
66
|
+
* its `ROUTE_DEPENDENCIES` entries unioned with the `copies` its imports
|
|
67
|
+
* resolve to (#9406). Copied when `apply` is set (never overwriting), else
|
|
68
|
+
* reported only. Sorted, deduplicated.
|
|
58
69
|
*/
|
|
59
70
|
missingDependencies: string[];
|
|
60
71
|
/** Dependency files copied this run. Sorted. */
|
|
@@ -96,6 +107,21 @@ export interface RetiredCheckoutReport {
|
|
|
96
107
|
/** Generated files rewritten (without `apply`: to rewrite) — the billing action. */
|
|
97
108
|
rewritten: string[];
|
|
98
109
|
}
|
|
110
|
+
/** One missing route's site-local imports (#9406 DD5) — see `walkRouteImports`. */
|
|
111
|
+
export interface RouteImportReport {
|
|
112
|
+
/** ROUTE_ROOT-relative, `/`-separated. */
|
|
113
|
+
route: string;
|
|
114
|
+
/** Template files the route reaches that the site lacks — copied with `--apply`. Sorted. */
|
|
115
|
+
copies: string[];
|
|
116
|
+
/** Files the route reaches that the site has, whose bytes differ from the template's — never written. Sorted. */
|
|
117
|
+
differs: string[];
|
|
118
|
+
/** Imports that resolve nowhere this sync can write; any entry refuses the route. Sorted by `from`, then `specifier`. */
|
|
119
|
+
unresolved: Array<{
|
|
120
|
+
specifier: string;
|
|
121
|
+
from: string;
|
|
122
|
+
reason: string;
|
|
123
|
+
}>;
|
|
124
|
+
}
|
|
99
125
|
/** One `NO_STRUCTURED_DATA_ROUTES` element: its source text, dedented, and the routes it exempts. */
|
|
100
126
|
interface StructuredDataExemption {
|
|
101
127
|
route: string;
|