diff --git a/backend/applications/tests/sharedSubpathExports.test.ts b/backend/applications/tests/sharedSubpathExports.test.ts index cecc6a7c3..bdff1c1a9 100644 --- a/backend/applications/tests/sharedSubpathExports.test.ts +++ b/backend/applications/tests/sharedSubpathExports.test.ts @@ -23,16 +23,15 @@ const REPO_ROOT = path.resolve(__dirname, '../../..') const SHARED_PKG = path.join(REPO_ROOT, 'shared', 'package.json') /** - * billing-service still imports `@fuzefront/shared/dist/kafka`. It does not - * crash only because its runtime image copies `shared/dist` WITHOUT - * `shared/package.json` (see services/billing-service/Dockerfile), so there is - * no `exports` map in the image to enforce — it works by accident, and adding - * that one COPY line would break it exactly as applications-service broke. - * Recorded here as a known exception rather than silently excluded; migrating - * it needs its tsconfig `paths` and jest moduleNameMapper updated too, which - * is deliberately not bundled into an incident fix for a different service. + * billing-service used to import `@fuzefront/shared/dist/kafka` and only + * avoided crashing because its runtime image copied `shared/dist` WITHOUT + * `shared/package.json`, so there was no `exports` map in the image to + * enforce — it worked by accident. Fixed in #753: the imports now name the + * supported `@fuzefront/shared/kafka` subpath, with tsconfig `paths`, jest + * `moduleNameMapper`, and the Dockerfile's `shared/package.json` COPY updated + * to match. No exception left to record here. */ -const KNOWN_UNMIGRATED = ['services/billing-service/'] +const KNOWN_UNMIGRATED: string[] = [] // Matches only real import syntax — `from '...'` / `require('...')` — not any // quoted occurrence. An earlier version matched backtick-delimited text too and diff --git a/services/billing-service/Dockerfile b/services/billing-service/Dockerfile index 6b57ffcf4..a641beb1c 100644 --- a/services/billing-service/Dockerfile +++ b/services/billing-service/Dockerfile @@ -61,6 +61,16 @@ RUN apk add --no-cache dumb-init && \ COPY --from=base /app/services/billing-service/node_modules ./services/billing-service/node_modules COPY --from=build /app/shared/dist ./shared/dist +# shared/package.json carries the `exports` map that makes `@fuzefront/shared/kafka` +# (the supported subpath — see src/index.ts et al.) resolvable at all: with no +# package.json here, Node has no `exports` to consult and a subpath import beyond +# the package root simply 404s (MODULE_NOT_FOUND), it does not "fall back" to +# anything. Omitting this file is NOT a safe shortcut — a prior version of this +# image omitted it, which happened to make an undeclared deep path +# (`@fuzefront/shared/dist/kafka`) resolve by accident (no exports map to enforce +# against). That was the bug fixed here (issue #753); this COPY is what makes the +# *correct* subpath import work in the image the same way it works locally. +COPY --from=build /app/shared/package.json ./shared/package.json # shared/dist/kafka/* does require('zod') + kafkajs at runtime, resolved by walking # UP from the file → it reaches /app/node_modules. The service deps (which include # zod + kafkajs) only sat in the sibling services/billing-service/node_modules, diff --git a/services/billing-service/jest.config.js b/services/billing-service/jest.config.js index e26cc80cc..00251e6c5 100644 --- a/services/billing-service/jest.config.js +++ b/services/billing-service/jest.config.js @@ -12,8 +12,10 @@ module.exports = { // Pointing to shared/src/index.ts would pull in AppContext.tsx (JSX), which ts-jest // cannot compile without --jsx. Since billing-service only ever imports from the kafka // sub-tree of shared, the narrower mapping is intentional — not a partial-import trap. + // The mapper key names the SUPPORTED subpath (@fuzefront/shared/kafka, matching the + // package's declared `exports`), not the dist/ internal it used to point at. moduleNameMapper: { - '^@fuzefront/shared/dist/kafka$': '/../../shared/src/kafka/index.ts', + '^@fuzefront/shared/kafka$': '/../../shared/src/kafka/index.ts', '^@izzywdev/fuzefront-identity$': '/../../packages/identity/src/index.ts', '^@fuzefront/shared$': '/../../shared/src/kafka/index.ts', }, diff --git a/services/billing-service/src/index.ts b/services/billing-service/src/index.ts index bb03b3c26..f649672c8 100644 --- a/services/billing-service/src/index.ts +++ b/services/billing-service/src/index.ts @@ -3,7 +3,7 @@ import { createKafkaClient, TypedProducer, TypedConsumer, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { loadConfig } from './config'; import { createApp, AppDeps } from './app'; import { createPool, runMigrations } from './db'; diff --git a/services/billing-service/src/kafka/consumer.ts b/services/billing-service/src/kafka/consumer.ts index 681745f42..b447f5cf3 100644 --- a/services/billing-service/src/kafka/consumer.ts +++ b/services/billing-service/src/kafka/consumer.ts @@ -5,7 +5,7 @@ import { billingUsageRecordedSchemaV1, BillingUsageRecordedPayloadV1, FuzeEvent, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { MeteringService } from '../services/metering.service'; /** diff --git a/services/billing-service/src/kafka/org-deleted.consumer.ts b/services/billing-service/src/kafka/org-deleted.consumer.ts index 3fb27c841..3cdb532e4 100644 --- a/services/billing-service/src/kafka/org-deleted.consumer.ts +++ b/services/billing-service/src/kafka/org-deleted.consumer.ts @@ -5,7 +5,7 @@ import { identityOrgDeletedSchemaV1, IdentityOrgDeletedPayloadV1, FuzeEvent, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { handleOrgDeleted, OrgDeletedHandlerDeps, diff --git a/services/billing-service/src/kafka/org-deleted.handler.ts b/services/billing-service/src/kafka/org-deleted.handler.ts index 1c49167a3..5d8c934cf 100644 --- a/services/billing-service/src/kafka/org-deleted.handler.ts +++ b/services/billing-service/src/kafka/org-deleted.handler.ts @@ -1,7 +1,7 @@ import { FuzeEvent, IdentityOrgDeletedPayloadV1, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { CustomerRepository } from '../repositories/customer.repository'; import { SubscriptionRepository } from '../repositories/subscription.repository'; import { SubscriptionService } from '../services/subscription.service'; diff --git a/services/billing-service/src/kafka/producer.ts b/services/billing-service/src/kafka/producer.ts index d1ee9a7a4..d2642a90d 100644 --- a/services/billing-service/src/kafka/producer.ts +++ b/services/billing-service/src/kafka/producer.ts @@ -9,7 +9,7 @@ import { BillingTenantRegisteredPayloadV1, billingPaymentMethodUpdatedSchemaV1, BillingPaymentMethodUpdatedPayloadV1, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { randomUUID } from 'crypto'; /** diff --git a/services/billing-service/src/kafka/ref-index.consumer.ts b/services/billing-service/src/kafka/ref-index.consumer.ts index 525d3e8ab..010b45ab2 100644 --- a/services/billing-service/src/kafka/ref-index.consumer.ts +++ b/services/billing-service/src/kafka/ref-index.consumer.ts @@ -3,7 +3,7 @@ import { TypedConsumer, TypedProducer, FuzeEvent, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { applyEventToRefIndex, REF_INDEX_TOPICS, diff --git a/services/billing-service/tests/kafka/org-deleted.handler.test.ts b/services/billing-service/tests/kafka/org-deleted.handler.test.ts index a82561f3a..7591131f4 100644 --- a/services/billing-service/tests/kafka/org-deleted.handler.test.ts +++ b/services/billing-service/tests/kafka/org-deleted.handler.test.ts @@ -3,7 +3,7 @@ import { FuzeEvent, TOPICS, IdentityOrgDeletedPayloadV1, -} from '@fuzefront/shared/dist/kafka'; +} from '@fuzefront/shared/kafka'; import { BillingCustomer, BillingSubscription } from '../../src/types'; const ORG_ID = '33333333-3333-3333-3333-333333333333'; diff --git a/services/billing-service/tsconfig.json b/services/billing-service/tsconfig.json index f20af9ad3..15486938f 100644 --- a/services/billing-service/tsconfig.json +++ b/services/billing-service/tsconfig.json @@ -4,6 +4,10 @@ "module": "commonjs", "outDir": "./dist", "rootDir": "./src", + "baseUrl": ".", + "paths": { + "@fuzefront/shared/kafka": ["../../shared/dist/kafka/index.d.ts"] + }, "strict": false, "noImplicitAny": false, "declaration": true,