@beignet/cli 0.0.36 → 0.0.38

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.
Files changed (95) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +36 -5
  3. package/dist/config.d.ts +15 -1
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +30 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/inspect.js +21 -17
  8. package/dist/inspect.js.map +1 -1
  9. package/dist/lint.d.ts.map +1 -1
  10. package/dist/lint.js +27 -6
  11. package/dist/lint.js.map +1 -1
  12. package/dist/make/inbox.js +7 -7
  13. package/dist/make/inbox.js.map +1 -1
  14. package/dist/make/payments.d.ts +2 -1
  15. package/dist/make/payments.d.ts.map +1 -1
  16. package/dist/make/payments.js +15 -11
  17. package/dist/make/payments.js.map +1 -1
  18. package/dist/make/shared.d.ts +1 -1
  19. package/dist/make/shared.d.ts.map +1 -1
  20. package/dist/make/shared.js +49 -37
  21. package/dist/make/shared.js.map +1 -1
  22. package/dist/make/tenancy.js +8 -8
  23. package/dist/make/tenancy.js.map +1 -1
  24. package/dist/make.d.ts.map +1 -1
  25. package/dist/make.js +27 -16
  26. package/dist/make.js.map +1 -1
  27. package/dist/operational-error-reporting.d.ts +15 -0
  28. package/dist/operational-error-reporting.d.ts.map +1 -0
  29. package/dist/operational-error-reporting.js +42 -0
  30. package/dist/operational-error-reporting.js.map +1 -0
  31. package/dist/outbox.d.ts.map +1 -1
  32. package/dist/outbox.js +73 -0
  33. package/dist/outbox.js.map +1 -1
  34. package/dist/provider-add.js +17 -17
  35. package/dist/provider-add.js.map +1 -1
  36. package/dist/provider-audit.d.ts.map +1 -1
  37. package/dist/provider-audit.js +11 -6
  38. package/dist/provider-audit.js.map +1 -1
  39. package/dist/schedule.d.ts.map +1 -1
  40. package/dist/schedule.js +28 -1
  41. package/dist/schedule.js.map +1 -1
  42. package/dist/task.d.ts.map +1 -1
  43. package/dist/task.js +37 -4
  44. package/dist/task.js.map +1 -1
  45. package/dist/templates/base.d.ts.map +1 -1
  46. package/dist/templates/base.js +6 -1
  47. package/dist/templates/base.js.map +1 -1
  48. package/dist/templates/db/index.d.ts +1 -0
  49. package/dist/templates/db/index.d.ts.map +1 -1
  50. package/dist/templates/db/index.js.map +1 -1
  51. package/dist/templates/db/mysql.d.ts.map +1 -1
  52. package/dist/templates/db/mysql.js +16 -0
  53. package/dist/templates/db/mysql.js.map +1 -1
  54. package/dist/templates/db/postgres.d.ts.map +1 -1
  55. package/dist/templates/db/postgres.js +16 -0
  56. package/dist/templates/db/postgres.js.map +1 -1
  57. package/dist/templates/db/sqlite.d.ts.map +1 -1
  58. package/dist/templates/db/sqlite.js +16 -0
  59. package/dist/templates/db/sqlite.js.map +1 -1
  60. package/dist/templates/index.d.ts.map +1 -1
  61. package/dist/templates/index.js +4 -3
  62. package/dist/templates/index.js.map +1 -1
  63. package/dist/templates/server.d.ts +2 -2
  64. package/dist/templates/server.d.ts.map +1 -1
  65. package/dist/templates/server.js +56 -40
  66. package/dist/templates/server.js.map +1 -1
  67. package/dist/templates/shared.js +3 -3
  68. package/dist/templates/shared.js.map +1 -1
  69. package/dist/templates/testing.js +1 -1
  70. package/dist/templates/todos.js +6 -6
  71. package/package.json +4 -4
  72. package/src/config.ts +66 -2
  73. package/src/inspect.ts +31 -19
  74. package/src/lint.ts +35 -4
  75. package/src/make/inbox.ts +7 -7
  76. package/src/make/payments.ts +23 -15
  77. package/src/make/shared.ts +56 -40
  78. package/src/make/tenancy.ts +8 -8
  79. package/src/make.ts +30 -16
  80. package/src/operational-error-reporting.ts +60 -0
  81. package/src/outbox.ts +77 -0
  82. package/src/provider-add.ts +21 -17
  83. package/src/provider-audit.ts +28 -11
  84. package/src/schedule.ts +32 -1
  85. package/src/task.ts +41 -4
  86. package/src/templates/base.ts +6 -1
  87. package/src/templates/db/index.ts +1 -0
  88. package/src/templates/db/mysql.ts +16 -0
  89. package/src/templates/db/postgres.ts +16 -0
  90. package/src/templates/db/sqlite.ts +16 -0
  91. package/src/templates/index.ts +4 -3
  92. package/src/templates/server.ts +56 -42
  93. package/src/templates/shared.ts +3 -3
  94. package/src/templates/testing.ts +1 -1
  95. package/src/templates/todos.ts +6 -6
package/src/inspect.ts CHANGED
@@ -558,7 +558,7 @@ function inspectConvention(
558
558
  ]);
559
559
  const missingResourceGenerator = missingRequirements(files, [
560
560
  config.paths.appContext,
561
- config.paths.infrastructurePorts,
561
+ config.paths.portWiring,
562
562
  config.paths.ports,
563
563
  config.paths.server,
564
564
  config.paths.useCaseBuilder,
@@ -1515,9 +1515,9 @@ async function inspectCanonicalConformance(
1515
1515
  "server/providers.ts should own provider registration, even when the provider list is small.",
1516
1516
  },
1517
1517
  {
1518
- file: config.paths.infrastructurePorts,
1518
+ file: config.paths.portWiring,
1519
1519
  reason:
1520
- "infra/app-ports.ts should wire concrete app ports for the selected runtime.",
1520
+ "infra/port-wiring.ts should wire concrete app ports for the selected runtime.",
1521
1521
  },
1522
1522
  {
1523
1523
  file: config.paths.routesBuilder,
@@ -2067,7 +2067,7 @@ async function inspectProductionReadiness(
2067
2067
  );
2068
2068
  const configFiles = operationalConfigFiles(files, config);
2069
2069
  const infrastructurePath = directoryPath(
2070
- path.dirname(config.paths.infrastructurePorts),
2070
+ path.dirname(config.paths.portWiring),
2071
2071
  );
2072
2072
  const schemaDir = `${infrastructurePath}/db/schema`;
2073
2073
  let hasSecurityHeadersHook = false;
@@ -2228,7 +2228,10 @@ async function inspectProductionReadiness(
2228
2228
  provider.variants,
2229
2229
  providerEntries,
2230
2230
  )) {
2231
- for (const envVar of variant.requiredEnv) {
2231
+ for (const envVar of configuredProviderRequiredEnv(
2232
+ variant.requiredEnv,
2233
+ config,
2234
+ )) {
2232
2235
  if (
2233
2236
  await providerRequiredEnvExists(
2234
2237
  targetDir,
@@ -2275,7 +2278,10 @@ async function inspectProductionReadiness(
2275
2278
  continue;
2276
2279
  }
2277
2280
 
2278
- for (const envVar of provider.requiredEnv ?? []) {
2281
+ for (const envVar of configuredProviderRequiredEnv(
2282
+ provider.requiredEnv ?? [],
2283
+ config,
2284
+ )) {
2279
2285
  if (
2280
2286
  await providerRequiredEnvExists(
2281
2287
  targetDir,
@@ -2561,7 +2567,7 @@ async function inspectPaymentsProductionReadiness(
2561
2567
  diagnostics.push({
2562
2568
  severity: "warning",
2563
2569
  code: "BEIGNET_BILLING_ENTITLEMENTS_PROVIDER_MISSING",
2564
- file: path.dirname(config.paths.infrastructurePorts),
2570
+ file: path.dirname(config.paths.portWiring),
2565
2571
  message:
2566
2572
  "features/billing/entitlements.ts exists, but no infra or server provider appears to call createBillingEntitlements(...). Wire the billing-backed entitlements port into AppPorts so paid feature gates use app billing state.",
2567
2573
  });
@@ -3028,7 +3034,7 @@ async function hasBillingEntitlementsProviderWiring(
3028
3034
  config: ResolvedBeignetConfig,
3029
3035
  sourceCache: Map<string, string>,
3030
3036
  ): Promise<boolean> {
3031
- const infraPath = path.dirname(config.paths.infrastructurePorts);
3037
+ const infraPath = path.dirname(config.paths.portWiring);
3032
3038
  const serverPath = path.dirname(config.paths.server);
3033
3039
  const candidateFiles = files.filter(
3034
3040
  (file) =>
@@ -3413,13 +3419,13 @@ function isInfraOrServerFile(
3413
3419
  ): boolean {
3414
3420
  const serverDir = directoryPath(path.dirname(config.paths.server));
3415
3421
  const infrastructureDir = directoryPath(
3416
- path.dirname(config.paths.infrastructurePorts),
3422
+ path.dirname(config.paths.portWiring),
3417
3423
  );
3418
3424
 
3419
3425
  return (
3420
3426
  file === config.paths.server ||
3421
3427
  file.startsWith(`${serverDir}/`) ||
3422
- file === config.paths.infrastructurePorts ||
3428
+ file === config.paths.portWiring ||
3423
3429
  file.startsWith(`${infrastructureDir}/`)
3424
3430
  );
3425
3431
  }
@@ -3544,9 +3550,7 @@ async function inspectWorkflowRegistrationDrift(
3544
3550
  }
3545
3551
  }
3546
3552
 
3547
- const infraDir = directoryPath(
3548
- path.dirname(config.paths.infrastructurePorts),
3549
- );
3553
+ const infraDir = directoryPath(path.dirname(config.paths.portWiring));
3550
3554
  const listenerTarget = drift.listeners.wiringFile
3551
3555
  ? `${drift.listeners.wiringFile}, which already calls registerListeners(...)`
3552
3556
  : drift.listeners.eventBusFile
@@ -4376,7 +4380,7 @@ async function inspectDatabaseLifecycleDrift(
4376
4380
  const sourceCache = new Map<string, string>();
4377
4381
  const resources = await collectResourceNames(targetDir, files, config);
4378
4382
  const infrastructurePath = directoryPath(
4379
- path.dirname(config.paths.infrastructurePorts),
4383
+ path.dirname(config.paths.portWiring),
4380
4384
  );
4381
4385
  const featuresPath = directoryPath(config.paths.features);
4382
4386
  const repositoriesPath = path.join(
@@ -5539,6 +5543,14 @@ function configuredProviderRequiredTables(
5539
5543
  );
5540
5544
  }
5541
5545
 
5546
+ function configuredProviderRequiredEnv(
5547
+ envVars: readonly string[],
5548
+ config: ResolvedBeignetConfig,
5549
+ ): string[] {
5550
+ const ignored = new Set(config.providerAudit.ignoreRequiredEnv);
5551
+ return envVars.filter((envVar) => !ignored.has(envVar));
5552
+ }
5553
+
5542
5554
  function configuredProviderRequiredTable(
5543
5555
  tableName: string,
5544
5556
  config: ResolvedBeignetConfig,
@@ -7287,21 +7299,21 @@ async function inspectResourceSlices(
7287
7299
  "errors.ts",
7288
7300
  );
7289
7301
  const infrastructureDir = `${directoryPath(
7290
- path.dirname(config.paths.infrastructurePorts),
7302
+ path.dirname(config.paths.portWiring),
7291
7303
  )}/${resource}/`;
7292
7304
  const drizzleSchemaFile = path.join(
7293
- path.dirname(config.paths.infrastructurePorts),
7305
+ path.dirname(config.paths.portWiring),
7294
7306
  "db",
7295
7307
  "schema",
7296
7308
  `${resource}.ts`,
7297
7309
  );
7298
7310
  const drizzleRepositoryFile = path.join(
7299
- path.dirname(config.paths.infrastructurePorts),
7311
+ path.dirname(config.paths.portWiring),
7300
7312
  resource,
7301
7313
  `drizzle-${singular}-repository.ts`,
7302
7314
  );
7303
7315
  const memoryRepositoryFile = path.join(
7304
- path.dirname(config.paths.infrastructurePorts),
7316
+ path.dirname(config.paths.portWiring),
7305
7317
  resource,
7306
7318
  `in-memory-${singular}-repository.ts`,
7307
7319
  );
@@ -7639,7 +7651,7 @@ async function collectResourceNames(
7639
7651
  const portsPath = directoryPath(path.dirname(config.paths.ports));
7640
7652
  const featuresPath = directoryPath(config.paths.features);
7641
7653
  const infrastructurePath = directoryPath(
7642
- path.dirname(config.paths.infrastructurePorts),
7654
+ path.dirname(config.paths.portWiring),
7643
7655
  );
7644
7656
 
7645
7657
  for (const file of files) {
package/src/lint.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { readdir, readFile, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import ts from "typescript";
3
4
  import { createPainter } from "./ansi.js";
4
5
  import {
5
6
  type BeignetConfig,
@@ -89,6 +90,7 @@ export async function lintApp(
89
90
  const diagnostics: LintDiagnostic[] = [];
90
91
  const sourceFiles = lintSourceFiles(files);
91
92
  const sourceFileSet = new Set(sourceFiles);
93
+ const atAliasRoot = resolveAtAliasRoot(targetDir);
92
94
  const sourceByFile = new Map<string, string>();
93
95
  const importGraph: ImportGraph = new Map();
94
96
 
@@ -96,7 +98,10 @@ export async function lintApp(
96
98
  const sourceLayer = classifyPath(file, config);
97
99
  const source = await readFile(path.join(targetDir, file), "utf8");
98
100
  sourceByFile.set(file, source);
99
- importGraph.set(file, parseImports(source, file, sourceFileSet));
101
+ importGraph.set(
102
+ file,
103
+ parseImports(source, file, sourceFileSet, atAliasRoot),
104
+ );
100
105
 
101
106
  if (sourceLayer === "test" || sourceLayer === "unknown") continue;
102
107
 
@@ -281,15 +286,40 @@ function parseImports(
281
286
  source: string,
282
287
  importerFile: string,
283
288
  files: Set<string>,
289
+ atAliasRoot: string,
284
290
  ): ImportReference[] {
285
291
  const references = parseImportSpecifiers(source);
286
292
 
287
293
  return references.map((reference) => ({
288
294
  ...reference,
289
- ...resolveImport(reference.importPath, importerFile, files),
295
+ ...resolveImport(reference.importPath, importerFile, files, atAliasRoot),
290
296
  }));
291
297
  }
292
298
 
299
+ function resolveAtAliasRoot(targetDir: string): string {
300
+ const tsconfigPath = path.join(targetDir, "tsconfig.json");
301
+ const parsed = ts.getParsedCommandLineOfConfigFile(
302
+ tsconfigPath,
303
+ {},
304
+ {
305
+ ...ts.sys,
306
+ onUnRecoverableConfigFileDiagnostic: () => {},
307
+ },
308
+ );
309
+ const aliasTarget = parsed?.options.paths?.["@/*"]?.[0];
310
+ if (!aliasTarget) return "";
311
+
312
+ const targetWithoutWildcard = aliasTarget.replace(/[/\\]?\*$/, "");
313
+ const baseUrl = parsed.options.baseUrl ?? targetDir;
314
+ const absoluteTarget = path.resolve(baseUrl, targetWithoutWildcard);
315
+ const relativeTarget = normalizePath(
316
+ path.relative(targetDir, absoluteTarget),
317
+ );
318
+ if (relativeTarget === "" || relativeTarget === ".") return "";
319
+ if (relativeTarget === ".." || relativeTarget.startsWith("../")) return "";
320
+ return directoryPath(relativeTarget);
321
+ }
322
+
293
323
  function parseImportSpecifiers(
294
324
  source: string,
295
325
  ): Array<{ importPath: string; kind: ImportKind; offset: number }> {
@@ -590,11 +620,12 @@ function resolveImport(
590
620
  importPath: string,
591
621
  importerFile: string,
592
622
  files: Set<string>,
623
+ atAliasRoot: string,
593
624
  ): Pick<ImportReference, "packageName" | "resolvedPath"> {
594
625
  if (importPath.startsWith("@/")) {
595
626
  return {
596
627
  resolvedPath: resolveLocalImportPath(
597
- stripKnownExtension(importPath.slice(2)),
628
+ stripKnownExtension(path.posix.join(atAliasRoot, importPath.slice(2))),
598
629
  files,
599
630
  ),
600
631
  };
@@ -1171,7 +1202,7 @@ function classifyPath(
1171
1202
  if (
1172
1203
  isUnder(
1173
1204
  normalizedPath,
1174
- directoryPath(path.dirname(config.paths.infrastructurePorts)),
1205
+ directoryPath(path.dirname(config.paths.portWiring)),
1175
1206
  )
1176
1207
  ) {
1177
1208
  return "infra";
package/src/make/inbox.ts CHANGED
@@ -265,7 +265,7 @@ export async function updateInboxWiring(
265
265
  options,
266
266
  )
267
267
  ) {
268
- updated.add(config.paths.infrastructurePorts);
268
+ updated.add(config.paths.portWiring);
269
269
  }
270
270
  if (
271
271
  await updateDrizzleSchemaIndexExports(
@@ -1119,7 +1119,7 @@ import {
1119
1119
  \tcreateTestPorts,
1120
1120
  } from "@beignet/core/testing";
1121
1121
  import type { AppContext } from "${aliasModule(config.paths.appContext)}";
1122
- import { appPorts } from "${aliasModule(config.paths.infrastructurePorts)}";
1122
+ import { initialPorts } from "${aliasModule(config.paths.portWiring)}";
1123
1123
  import type { AppTransactionPorts } from "${aliasModule(config.paths.ports)}";
1124
1124
  import { getUnreadCountUseCase } from "../use-cases/get-unread-count";
1125
1125
  import { listInboxUseCase } from "../use-cases/list-inbox";
@@ -1140,9 +1140,9 @@ function createHarness(
1140
1140
  \tconst inbox = options.inbox ?? createMemoryInboxRepository();
1141
1141
  \tconst actor = options.actor ?? createTestUserActor("user_test");
1142
1142
  \tconst fixture = createTestPorts<AppContext["ports"], AppTransactionPorts>({
1143
- \t\tbase: appPorts,
1143
+ \t\tbase: initialPorts,
1144
1144
  \t\toverrides: {
1145
- \t\t\tgate: appPorts.gate,
1145
+ \t\t\tgate: initialPorts.gate,
1146
1146
  \t\t\tinbox,
1147
1147
  \t\t},
1148
1148
  \t});
@@ -1305,7 +1305,7 @@ import {
1305
1305
  \tdefineInboxNotificationChannel,
1306
1306
  \ttype InboxNotificationInput,
1307
1307
  } from "${channelModule}";
1308
- import { appPorts } from "${aliasModule(config.paths.infrastructurePorts)}";
1308
+ import { initialPorts } from "${aliasModule(config.paths.portWiring)}";
1309
1309
  import { defineNotification } from "${aliasModule(config.paths.notificationsBuilder)}";
1310
1310
  import type { AppTransactionPorts } from "${aliasModule(config.paths.ports)}";
1311
1311
  import { createMemoryInboxRepository } from "./factories/inbox-notification";
@@ -1340,9 +1340,9 @@ const skippingNotification = defineNotification("inbox.channel-skip-test", {
1340
1340
  function createHarness() {
1341
1341
  \tconst inbox = createMemoryInboxRepository();
1342
1342
  \tconst fixture = createTestPorts<AppContext["ports"], AppTransactionPorts>({
1343
- \t\tbase: appPorts,
1343
+ \t\tbase: initialPorts,
1344
1344
  \t\toverrides: {
1345
- \t\t\tgate: appPorts.gate,
1345
+ \t\t\tgate: initialPorts.gate,
1346
1346
  \t\t\tinbox,
1347
1347
  \t\t},
1348
1348
  \t});
@@ -82,7 +82,13 @@ export async function makePayments(
82
82
 
83
83
  const database = await detectResourceDatabase(targetDir, config);
84
84
  const ui = await detectUiShell(targetDir, config);
85
- const generatedFiles = paymentsFiles(config, database, { ui });
85
+ const tenantScoped = await fileExists(
86
+ path.join(targetDir, config.paths.features, "workspaces/contracts.ts"),
87
+ );
88
+ const generatedFiles = paymentsFiles(config, database, {
89
+ ui,
90
+ idempotencyScope: tenantScoped ? "actor-tenant" : "actor",
91
+ });
86
92
  const plannedFiles = await planGeneratedFiles(targetDir, generatedFiles, {
87
93
  force: Boolean(options.force),
88
94
  });
@@ -246,7 +252,7 @@ export async function updatePaymentsWiring(
246
252
  }
247
253
  if (await updatePaymentsEntitlementsPort(targetDir, config, options)) {
248
254
  updated.add(config.paths.ports);
249
- updated.add(config.paths.infrastructurePorts);
255
+ updated.add(config.paths.portWiring);
250
256
  }
251
257
  if (
252
258
  await updateInfrastructureDeferredPorts(
@@ -256,7 +262,7 @@ export async function updatePaymentsWiring(
256
262
  options,
257
263
  )
258
264
  ) {
259
- updated.add(config.paths.infrastructurePorts);
265
+ updated.add(config.paths.portWiring);
260
266
  }
261
267
  if (
262
268
  await updateDrizzleSchemaIndexExports(
@@ -354,10 +360,7 @@ export async function updatePaymentsEntitlementsPort(
354
360
  if (!options.dryRun) await writeFile(portsFilePath, portsNext);
355
361
  }
356
362
 
357
- const infrastructureFilePath = path.join(
358
- targetDir,
359
- config.paths.infrastructurePorts,
360
- );
363
+ const infrastructureFilePath = path.join(targetDir, config.paths.portWiring);
361
364
  const infrastructureOriginal = await readFile(infrastructureFilePath, "utf8");
362
365
  const infrastructureNext = appendDeferredPortKey(
363
366
  infrastructureOriginal,
@@ -368,7 +371,7 @@ export async function updatePaymentsEntitlementsPort(
368
371
  !/["']entitlements["']/.test(infrastructureOriginal)
369
372
  ) {
370
373
  throw new Error(
371
- `Could not find the deferred port list in ${config.paths.infrastructurePorts}. Add "entitlements" manually, or restore the generated infrastructure ports file before running make payments.`,
374
+ `Could not find the deferred port list in ${config.paths.portWiring}. Add "entitlements" manually, or restore the generated port wiring file before running make payments.`,
372
375
  );
373
376
  }
374
377
  if (infrastructureNext !== infrastructureOriginal) {
@@ -558,7 +561,10 @@ export async function updateBillingSettingsNav(
558
561
  export function paymentsFiles(
559
562
  config: ResolvedBeignetConfig,
560
563
  database: DatabaseName,
561
- options: { ui: boolean } = { ui: false },
564
+ options: {
565
+ ui: boolean;
566
+ idempotencyScope?: "actor" | "actor-tenant";
567
+ } = { ui: false },
562
568
  ): GeneratedFile[] {
563
569
  const uiFiles: GeneratedFile[] = options.ui
564
570
  ? [
@@ -611,7 +617,7 @@ export function paymentsFiles(
611
617
  },
612
618
  {
613
619
  path: path.join(config.paths.features, "billing/contracts.ts"),
614
- content: billingContractsFile(),
620
+ content: billingContractsFile(options.idempotencyScope ?? "actor"),
615
621
  },
616
622
  {
617
623
  path: path.join(config.paths.features, "billing/use-cases/index.ts"),
@@ -846,7 +852,9 @@ export function isBillingAccountActive(
846
852
  `;
847
853
  }
848
854
 
849
- export function billingContractsFile(): string {
855
+ export function billingContractsFile(
856
+ idempotencyScope: "actor" | "actor-tenant" = "actor",
857
+ ): string {
850
858
  return `import { defineContractGroup } from "@beignet/core/contracts";
851
859
  import { z } from "zod";
852
860
  import {
@@ -883,7 +891,7 @@ export const createCheckoutSession = checkoutBilling
883
891
  \t\tidempotency: {
884
892
  \t\t\trequired: true,
885
893
  \t\t\theader: "idempotency-key",
886
- \t\t\tscope: "actor-tenant",
894
+ \t\t\tscope: "${idempotencyScope}",
887
895
  \t\t\tttlSec: 86_400,
888
896
  \t\t},
889
897
  \t})
@@ -1410,7 +1418,7 @@ import {
1410
1418
  \tcreateTestPorts,
1411
1419
  } from "@beignet/core/testing";
1412
1420
  import type { AppContext } from "${aliasModule(config.paths.appContext)}";
1413
- import { appPorts } from "@/infra/app-ports";
1421
+ import { initialPorts } from "@/infra/port-wiring";
1414
1422
  import type { AppTransactionPorts } from "@/ports";
1415
1423
  import { createBillingEntitlements } from "../entitlements";
1416
1424
  import type { BillingAccount, BillingRepository } from "../ports";
@@ -1451,11 +1459,11 @@ function createHarness(options: { actor?: AppContext["actor"] } = {}) {
1451
1459
  \tconst billing = createMemoryBillingRepository();
1452
1460
  \tconst actor = options.actor ?? createTestUserActor("user_test");
1453
1461
  \tconst fixture = createTestPorts<AppContext["ports"], AppTransactionPorts>({
1454
- \t\tbase: appPorts,
1462
+ \t\tbase: initialPorts,
1455
1463
  \t\toverrides: {
1456
1464
  \t\t\tbilling,
1457
1465
  \t\t\tentitlements: createBillingEntitlements(billing),
1458
- \t\t\tgate: appPorts.gate,
1466
+ \t\t\tgate: initialPorts.gate,
1459
1467
  \t\t},
1460
1468
  \t});
1461
1469
  \tconst createContext = createTestContextFactory<