agrs-sequelize-sdk 1.4.40 → 1.4.42

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/models/Article.js CHANGED
@@ -31,6 +31,12 @@ module.exports = (sequelize, DataTypes) => {
31
31
  type: DataTypes.STRING(1024),
32
32
  allowNull: true,
33
33
  },
34
+ sourceCampaignId: {
35
+ type: DataTypes.STRING,
36
+ allowNull: true,
37
+ comment:
38
+ "FB campaign id of the campaign that originally created this article. Populated by Tarzo mirror on create-success so duplicate-as-reuse can find the source when this article is reused. Nullable — not all articles have a known source (legacy rows, articles whose source campaign was deleted).",
39
+ },
34
40
  feed: {
35
41
  type: DataTypes.STRING,
36
42
  allowNull: false,
@@ -177,6 +183,10 @@ module.exports = (sequelize, DataTypes) => {
177
183
  unique: true,
178
184
  fields: ['providerId', 'feed'],
179
185
  name: 'unique_provider_per_feed'
186
+ },
187
+ {
188
+ fields: ['sourceCampaignId'],
189
+ name: 'idx_article_source_campaign_id'
180
190
  }
181
191
  ]
182
192
  }
@@ -285,6 +285,29 @@ module.exports = (sequelize, DataTypes) => {
285
285
  { fields: ["vertical", "feed_provider"] },
286
286
  { fields: ["details"], using: "gin" },
287
287
  { fields: ["platform_code"] },
288
+ // Expression index on details->>'ai_stage' for Tarzo-only rows.
289
+ // Powers the hourly reconciler steps 2/5 (awaiting → COMPLETED) and
290
+ // 3/5 (stale → FAILED) added by tarzoMaterializationReconciler.
291
+ // Without this the queries do a full-table scan of the 50GB+ table
292
+ // and time out (verified in prod 2026-07-19: errors=3 every hour).
293
+ // Partial WHERE keeps the index tiny — only Tarzo awaiting/failed
294
+ // rows are indexed, not the whole table.
295
+ {
296
+ name: "idx_v2_ai_stage_tarzo",
297
+ fields: [sequelize.literal(`((details->>'ai_stage'))`)],
298
+ where: sequelize.literal(`(details->>'ai_stage') LIKE 'tarzo_%'`),
299
+ },
300
+ // Composite index for the stale-cleanup query (step 3/5) which
301
+ // filters by ai_stage AND created_at < now() - 6h. Same partial
302
+ // WHERE keeps size minimal.
303
+ {
304
+ name: "idx_v2_ai_stage_tarzo_created_at",
305
+ fields: [
306
+ sequelize.literal(`((details->>'ai_stage'))`),
307
+ { name: "created_at", order: "DESC" },
308
+ ],
309
+ where: sequelize.literal(`(details->>'ai_stage') LIKE 'tarzo_%'`),
310
+ },
288
311
  ],
289
312
  }
290
313
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agrs-sequelize-sdk",
3
- "version": "1.4.40",
3
+ "version": "1.4.42",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "start": "node index.js",