agrs-sequelize-sdk 1.4.42 → 1.4.44
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.
|
@@ -292,6 +292,25 @@ module.exports = (sequelize, DataTypes) => {
|
|
|
292
292
|
{
|
|
293
293
|
fields: ["createdAt"],
|
|
294
294
|
},
|
|
295
|
+
// Partial index mirroring the V2 side (idx_v2_awaiting_by_feed_campaign).
|
|
296
|
+
// The hourly Tarzo reconciler runs the SAME awaiting-materialization
|
|
297
|
+
// WHERE clause against both V1 and V2 (dual-write parity). Without this
|
|
298
|
+
// index the V1 UPDATE seq-scans 15.8M rows / 11GB and hits the 60s
|
|
299
|
+
// statement_timeout (verified in prod 2026-07-19: 207s EXPLAIN).
|
|
300
|
+
//
|
|
301
|
+
// Composite (feed_campaign_id, createdAt DESC) covers both:
|
|
302
|
+
// - step 2/5 join key (rfc.AGRS_CID = l.feed_campaign_id)
|
|
303
|
+
// - step 3/5 stale-age filter (l.createdAt < now() - 6h)
|
|
304
|
+
//
|
|
305
|
+
// Equality predicate — LIKE would be ignored by the planner (proven
|
|
306
|
+
// 2026-07-19). Self-pruning: rows drop out on COMPLETED/FAILED flip.
|
|
307
|
+
{
|
|
308
|
+
name: "idx_v1_awaiting_by_feed_campaign",
|
|
309
|
+
fields: ["feed_campaign_id", { name: "createdAt", order: "DESC" }],
|
|
310
|
+
where: sequelize.literal(
|
|
311
|
+
`status = 'IN_PROGRESS' AND (details->>'ai_stage') = 'tarzo_awaiting_materialization'`
|
|
312
|
+
),
|
|
313
|
+
},
|
|
295
314
|
],
|
|
296
315
|
}
|
|
297
316
|
);
|
|
@@ -285,28 +285,56 @@ module.exports = (sequelize, DataTypes) => {
|
|
|
285
285
|
{ fields: ["vertical", "feed_provider"] },
|
|
286
286
|
{ fields: ["details"], using: "gin" },
|
|
287
287
|
{ fields: ["platform_code"] },
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
//
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
//
|
|
288
|
+
// Partial indexes for the hourly Tarzo reconciler (steps 2/5 and 3/5
|
|
289
|
+
// in reconcilerService.js). Both steps filter on:
|
|
290
|
+
// status='IN_PROGRESS'
|
|
291
|
+
// AND details->>'ai_stage'='tarzo_awaiting_materialization'
|
|
292
|
+
// Predicate is equality — NOT `LIKE 'tarzo_%'` — because Postgres's
|
|
293
|
+
// partial-index prover doesn't cross equality→LIKE, so a LIKE-predicate
|
|
294
|
+
// index would be ignored (verified in prod 2026-07-19). Equality
|
|
295
|
+
// matches the queries verbatim, so the planner picks these up.
|
|
296
|
+
//
|
|
297
|
+
// Column choices:
|
|
298
|
+
// - feed_campaign_id: drives the nested-loop join to
|
|
299
|
+
// rsoc_feed_campaigns.AGRS_CID in step 2/5.
|
|
300
|
+
// - created_at: powers the stale age filter in step 3/5.
|
|
301
|
+
//
|
|
302
|
+
// Self-pruning: rows leave the index as soon as status flips to
|
|
303
|
+
// COMPLETED/FAILED, so index size stays proportional to in-flight
|
|
304
|
+
// rows only.
|
|
295
305
|
{
|
|
296
|
-
name: "
|
|
297
|
-
fields: [
|
|
298
|
-
where: sequelize.literal(
|
|
306
|
+
name: "idx_v2_awaiting_by_feed_campaign",
|
|
307
|
+
fields: ["feed_campaign_id"],
|
|
308
|
+
where: sequelize.literal(
|
|
309
|
+
`status = 'IN_PROGRESS' AND (details->>'ai_stage') = 'tarzo_awaiting_materialization'`
|
|
310
|
+
),
|
|
299
311
|
},
|
|
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
312
|
{
|
|
304
|
-
name: "
|
|
305
|
-
fields: [
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
313
|
+
name: "idx_v2_awaiting_created_at",
|
|
314
|
+
fields: [{ name: "created_at", order: "DESC" }],
|
|
315
|
+
where: sequelize.literal(
|
|
316
|
+
`status = 'IN_PROGRESS' AND (details->>'ai_stage') = 'tarzo_awaiting_materialization'`
|
|
317
|
+
),
|
|
318
|
+
},
|
|
319
|
+
// Partial index for the ai_campaign_queue backfill query in step 2/5
|
|
320
|
+
// (completeAdoptedAwaitingLogs's third UPDATE). After the awaiting log
|
|
321
|
+
// flips to COMPLETED, ai_stage becomes 'tarzo_materialized_and_adopted'
|
|
322
|
+
// and the queue's facebook_campaign_id gets backfilled by joining V2
|
|
323
|
+
// to ai_campaign_queue via process_id.
|
|
324
|
+
//
|
|
325
|
+
// Without this, the query bitmap-scans by status='COMPLETED' (returns
|
|
326
|
+
// 1.2M rows), then filters ai_stage in memory (rejects 1.18M) → 175s
|
|
327
|
+
// seq scan, 60s timeout in prod (verified 2026-07-19).
|
|
328
|
+
//
|
|
329
|
+
// Composite (process_id, feed_campaign_id) supports both the join to
|
|
330
|
+
// ai_campaign_queue.creation_logs_process_id AND the further join to
|
|
331
|
+
// rsoc_feed_campaigns.AGRS_CID.
|
|
332
|
+
{
|
|
333
|
+
name: "idx_v2_adopted_by_process",
|
|
334
|
+
fields: ["process_id", "feed_campaign_id"],
|
|
335
|
+
where: sequelize.literal(
|
|
336
|
+
`status = 'COMPLETED' AND (details->>'ai_stage') = 'tarzo_materialized_and_adopted'`
|
|
337
|
+
),
|
|
310
338
|
},
|
|
311
339
|
],
|
|
312
340
|
}
|