@porulle/plugin-channel-connector 0.29.0 → 0.30.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/dist/index.js CHANGED
@@ -97,14 +97,30 @@ export function channelConnectorPlugin(options = {}) {
97
97
  });
98
98
  if (!result.ok)
99
99
  throw new Error(result.error);
100
+ const jobs = ctx.services.jobs;
100
101
  if (!result.value.exhausted) {
101
- const jobs = ctx.services.jobs;
102
102
  await jobs.enqueue("channel/import-catalog", { orgId, storeId }, {
103
103
  organizationId: orgId,
104
104
  concurrencyKey: storeId,
105
105
  supersedes: true,
106
106
  });
107
107
  }
108
+ else {
109
+ // A finished catalog is not a usable one. `importCatalog` writes entities, variants and
110
+ // prices and never touches `inventory_levels`, so a store whose sweep ends here has a
111
+ // catalog in which every variant rolls up as out of stock — which is what a consumer
112
+ // projection publishes and what a shopper is shown.
113
+ //
114
+ // Inventory used to arrive from `reconcile`, reachable only through the
115
+ // `channel/reconcile-sweep` cron. A deployment that removes its crons therefore loses a
116
+ // data-plane write silently, with every suite still green. Levelling inventory here keeps
117
+ // it inside the one operator action — "import this store" — instead of behind a second
118
+ // one somebody has to remember.
119
+ await jobs.enqueue("channel/sync-inventory", { orgId, storeId }, {
120
+ organizationId: orgId,
121
+ concurrencyKey: storeId,
122
+ });
123
+ }
108
124
  return {
109
125
  output: {
110
126
  imported: result.value.imported,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/plugin-channel-connector",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,15 +19,15 @@
19
19
  "dependencies": {
20
20
  "@hono/zod-openapi": "^1.2.2",
21
21
  "hono": "^4.12.5",
22
- "@porulle/core": "0.29.0"
22
+ "@porulle/core": "0.30.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^24.5.2",
26
26
  "eslint": "^9.39.1",
27
27
  "typescript": "5.9.2",
28
28
  "vitest": "^3.2.4",
29
- "@porulle/eslint-config": "0.1.0",
30
- "@porulle/typescript-config": "0.1.0"
29
+ "@porulle/typescript-config": "0.1.0",
30
+ "@porulle/eslint-config": "0.1.0"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public"
package/src/index.ts CHANGED
@@ -202,13 +202,28 @@ export function channelConnectorPlugin(options: ChannelConnectorPluginOptions =
202
202
  maxItems: CHANNEL_IMPORT_MAX_ITEMS_PER_INVOCATION,
203
203
  });
204
204
  if (!result.ok) throw new Error(result.error);
205
+ const jobs = ctx.services.jobs as JobsAdapter;
205
206
  if (!result.value.exhausted) {
206
- const jobs = ctx.services.jobs as JobsAdapter;
207
207
  await jobs.enqueue("channel/import-catalog", { orgId, storeId }, {
208
208
  organizationId: orgId,
209
209
  concurrencyKey: storeId,
210
210
  supersedes: true,
211
211
  });
212
+ } else {
213
+ // A finished catalog is not a usable one. `importCatalog` writes entities, variants and
214
+ // prices and never touches `inventory_levels`, so a store whose sweep ends here has a
215
+ // catalog in which every variant rolls up as out of stock — which is what a consumer
216
+ // projection publishes and what a shopper is shown.
217
+ //
218
+ // Inventory used to arrive from `reconcile`, reachable only through the
219
+ // `channel/reconcile-sweep` cron. A deployment that removes its crons therefore loses a
220
+ // data-plane write silently, with every suite still green. Levelling inventory here keeps
221
+ // it inside the one operator action — "import this store" — instead of behind a second
222
+ // one somebody has to remember.
223
+ await jobs.enqueue("channel/sync-inventory", { orgId, storeId }, {
224
+ organizationId: orgId,
225
+ concurrencyKey: storeId,
226
+ });
212
227
  }
213
228
  return {
214
229
  output: {