agrs-sequelize-sdk 1.4.59 → 1.4.61

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 (120) hide show
  1. package/migrations/2026-05-17-PIXELS-FOLLOWUP.md +85 -85
  2. package/migrations/2026-05-17-add-platform-to-ad.js +19 -19
  3. package/migrations/2026-05-17-add-platform-to-adaccount.js +19 -19
  4. package/migrations/2026-05-17-add-platform-to-adperformance.js +19 -19
  5. package/migrations/2026-05-17-add-platform-to-adset.js +19 -19
  6. package/migrations/2026-05-17-add-platform-to-adsetperformance.js +19 -19
  7. package/migrations/2026-05-17-add-platform-to-aiarticleretryqueue.js +19 -19
  8. package/migrations/2026-05-17-add-platform-to-aicampaignqueue.js +19 -19
  9. package/migrations/2026-05-17-add-platform-to-article.js +19 -19
  10. package/migrations/2026-05-17-add-platform-to-campaign.js +19 -19
  11. package/migrations/2026-05-17-add-platform-to-codefuelcampaign.js +19 -19
  12. package/migrations/2026-05-17-add-platform-to-dynamicfeed.js +19 -19
  13. package/migrations/2026-05-17-add-platform-to-facebookretryqueue.js +19 -19
  14. package/migrations/2026-05-17-add-platform-to-pages.js +19 -19
  15. package/migrations/2026-05-17-add-platform-to-presets.js +19 -19
  16. package/migrations/2026-05-18-add-group-id-to-ai-campaign-queue.js +18 -18
  17. package/migrations/2026-05-18-add-platform-code-to-creation-logs.js +65 -65
  18. package/migrations/2026-05-18-add-platform-code-to-pixels.js +55 -55
  19. package/migrations/2026-05-18-add-platform-code-to-rsoc-feed-campaigns.js +55 -55
  20. package/migrations/2026-05-18-add-platform-date-index-to-adperformance.js +16 -16
  21. package/migrations/2026-05-18-add-platform-date-index-to-adsetperformance.js +16 -16
  22. package/migrations/2026-05-18-add-review-status-to-ad.js +36 -36
  23. package/migrations/2026-05-18-create-canonical-insights.js +84 -84
  24. package/migrations/2026-05-18-create-snapchat-public-profiles.js +68 -68
  25. package/migrations/2026-05-18-create-tiktok-identities.js +71 -71
  26. package/migrations/2026-05-18-create-tiktok-snapchat-campaigns.js +143 -143
  27. package/migrations/2026-05-18-create-tt-snp-adset-ad-tables.js +309 -309
  28. package/migrations/RUN_ME_MANUALLY_2026-05-17.sql +99 -99
  29. package/migrations/add-requested-from-dashboard-to-articles.js +17 -17
  30. package/migrations/change-adset-name-to-text.js +79 -79
  31. package/models/AICampaignQueue.js +151 -151
  32. package/models/AIGenerationLog.js +85 -85
  33. package/models/AIGenerationRequest.js +212 -212
  34. package/models/AdAccountValues.js +25 -25
  35. package/models/AdHistory.js +30 -30
  36. package/models/AdPerformance.js +104 -104
  37. package/models/AdSet.js +295 -295
  38. package/models/AdSetHistory.js +30 -30
  39. package/models/AdsetPerformance.js +137 -137
  40. package/models/AiArticleRetryQueue.js +157 -157
  41. package/models/AiCreationRetryQueue.js +134 -134
  42. package/models/ApiAuditLog.js +127 -127
  43. package/models/ApiToken.js +67 -67
  44. package/models/Article.js +222 -222
  45. package/models/AutomationRule.js +179 -179
  46. package/models/BannerTemplate.js +129 -129
  47. package/models/Buyers.js +25 -25
  48. package/models/Campaign.js +168 -168
  49. package/models/CampaignActionHistory.js +101 -101
  50. package/models/CampaignCreationLog.js +340 -340
  51. package/models/CampaignCreationLogV2.js +392 -392
  52. package/models/CampaignHistory.js +33 -33
  53. package/models/CampaignTag.js +46 -46
  54. package/models/CampaignTagAssignment.js +48 -48
  55. package/models/CanonicalInsights.js +68 -68
  56. package/models/Channel.js +55 -55
  57. package/models/Domain.js +49 -44
  58. package/models/DynamicFeed.js +218 -218
  59. package/models/ExplorAdsChannel.js +61 -61
  60. package/models/FacebookRetryQueue.js +163 -163
  61. package/models/Feed.js +33 -33
  62. package/models/FeedArticleConfiguration.js +80 -80
  63. package/models/FrontStoryChannel.js +59 -59
  64. package/models/FrontStoryChannelV2.js +60 -60
  65. package/models/GenericFlowRequest.js +114 -114
  66. package/models/MidoWebChannel.js +47 -47
  67. package/models/MineBrandBlocklist.js +56 -56
  68. package/models/MineBrandConfig.js +26 -26
  69. package/models/MineChannel.js +47 -47
  70. package/models/MineRedirectDomain.js +42 -42
  71. package/models/MineWebhookEvent.js +53 -53
  72. package/models/Pages.js +117 -117
  73. package/models/PipelineExecution.js +59 -59
  74. package/models/PolicyDogsCreativeCache.js +50 -50
  75. package/models/PolicyDogsImageCache.js +30 -30
  76. package/models/Presets.js +40 -40
  77. package/models/PublicApiBatch.js +155 -155
  78. package/models/PublicApiBatchItem.js +166 -166
  79. package/models/PublicApiIdempotencyCache.js +135 -135
  80. package/models/RSOCFeedCampaign.js +387 -387
  81. package/models/RSOCFeedConfig.js +46 -46
  82. package/models/RSOCRedirectWsCode.js +22 -22
  83. package/models/RsocKeywordPerformance.js +110 -110
  84. package/models/RuleAction.js +90 -90
  85. package/models/RuleCondition.js +137 -137
  86. package/models/RuleExecution.js +107 -107
  87. package/models/RulesValues.js +56 -56
  88. package/models/SingularChannel.js +31 -31
  89. package/models/SnapchatAd.js +69 -69
  90. package/models/SnapchatAdSquad.js +92 -92
  91. package/models/SnapchatCampaign.js +69 -69
  92. package/models/SnapchatChannel.js +31 -31
  93. package/models/SnapchatPublicProfiles.js +67 -67
  94. package/models/SupportedLocale.js +23 -23
  95. package/models/SyncHistory.js +249 -249
  96. package/models/TTQChannel.js +42 -42
  97. package/models/Team.js +33 -43
  98. package/models/TemplateMetadata.js +260 -260
  99. package/models/Tier2_AdAccounts.js +110 -110
  100. package/models/Tier2_Assets.js +70 -70
  101. package/models/Tier2_BusinessManagers.js +105 -105
  102. package/models/Tier2_CreditLines.js +99 -99
  103. package/models/Tier2_Pages.js +91 -91
  104. package/models/Tier2_Pixels.js +82 -82
  105. package/models/Tier2_Tokens.js +64 -64
  106. package/models/Tier2_UserAdAccounts.js +83 -83
  107. package/models/TikTokAd.js +71 -71
  108. package/models/TikTokAdGroup.js +82 -82
  109. package/models/TikTokCampaign.js +71 -71
  110. package/models/TiktokChannel.js +31 -31
  111. package/models/TiktokIdentities.js +65 -65
  112. package/models/TokenRotationState.js +121 -121
  113. package/models/TonicRSOCKeywordPerformance.js +122 -122
  114. package/models/Users.js +204 -204
  115. package/models/Vertical.js +25 -25
  116. package/models/newFiles.js +137 -137
  117. package/package.json +21 -19
  118. package/run.sh +214 -214
  119. package/services/sequelizeService.js +110 -110
  120. package/tarzo-skalio-integration-docs.md +691 -691
@@ -1,46 +1,46 @@
1
- // agrs-sequelize/models/RSOCFeedConfig.js
2
- const { DataTypes } = require('sequelize');
3
-
4
- module.exports = (sequelize) => {
5
- const RSOCFeedConfig = sequelize.define('RSOCFeedConfig', {
6
- id: { type: DataTypes.UUID, primaryKey: true, defaultValue: DataTypes.UUIDV4 },
7
- feed_id: { type: DataTypes.TEXT, unique: true, allowNull: false },
8
- feed_name: { type: DataTypes.TEXT, allowNull: false },
9
- aliases: { type: DataTypes.ARRAY(DataTypes.TEXT), allowNull: false, defaultValue: [] }, // R7: rename-safety — historical/alternate spellings
10
- feed_code: { type: DataTypes.TEXT, allowNull: false },
11
- agrs_cid_prefix: { type: DataTypes.TEXT, allowNull: false },
12
- campaign_name_pattern: { type: DataTypes.TEXT, allowNull: false },
13
- partner_id: { type: DataTypes.TEXT, allowNull: false },
14
- partner_token: { type: DataTypes.TEXT, allowNull: false },
15
- campaign_partner_token: { type: DataTypes.TEXT }, // R5: campaign webhook token (differs from partner_token for Mine 1)
16
- article_api_base_url: { type: DataTypes.TEXT, allowNull: false },
17
- campaign_api_base_url: { type: DataTypes.TEXT, allowNull: false },
18
- perf_api_base_url: { type: DataTypes.TEXT, allowNull: false },
19
- pixel_id: { type: DataTypes.TEXT },
20
- ts_value: { type: DataTypes.TEXT },
21
- event_name: { type: DataTypes.TEXT },
22
- utm_medium: { type: DataTypes.TEXT },
23
- default_style: { type: DataTypes.TEXT },
24
- min_keyword_words: { type: DataTypes.INTEGER, defaultValue: 4 },
25
- default_domain: { type: DataTypes.TEXT },
26
- fallback_redirect_domain: { type: DataTypes.TEXT },
27
- channel_range_min: { type: DataTypes.INTEGER, allowNull: false },
28
- channel_range_max: { type: DataTypes.INTEGER, allowNull: false },
29
- rac_mode: { type: DataTypes.TEXT },
30
- always_redirect: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }, // Tsuf-confirmed: Mine 2 = everything through redirect
31
- is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
32
- }, {
33
- tableName: 'rsoc_feed_configs',
34
- underscored: true,
35
- });
36
-
37
- RSOCFeedConfig.associate = (models) => {
38
- RSOCFeedConfig.hasMany(models.RSOCRedirectWsCode, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
39
- RSOCFeedConfig.hasMany(models.MineChannel, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
40
- RSOCFeedConfig.hasMany(models.MineRedirectDomain, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
41
- RSOCFeedConfig.hasMany(models.MineBrandBlocklist, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
42
- RSOCFeedConfig.hasMany(models.MineBrandConfig, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
43
- };
44
-
45
- return RSOCFeedConfig;
46
- };
1
+ // agrs-sequelize/models/RSOCFeedConfig.js
2
+ const { DataTypes } = require('sequelize');
3
+
4
+ module.exports = (sequelize) => {
5
+ const RSOCFeedConfig = sequelize.define('RSOCFeedConfig', {
6
+ id: { type: DataTypes.UUID, primaryKey: true, defaultValue: DataTypes.UUIDV4 },
7
+ feed_id: { type: DataTypes.TEXT, unique: true, allowNull: false },
8
+ feed_name: { type: DataTypes.TEXT, allowNull: false },
9
+ aliases: { type: DataTypes.ARRAY(DataTypes.TEXT), allowNull: false, defaultValue: [] }, // R7: rename-safety — historical/alternate spellings
10
+ feed_code: { type: DataTypes.TEXT, allowNull: false },
11
+ agrs_cid_prefix: { type: DataTypes.TEXT, allowNull: false },
12
+ campaign_name_pattern: { type: DataTypes.TEXT, allowNull: false },
13
+ partner_id: { type: DataTypes.TEXT, allowNull: false },
14
+ partner_token: { type: DataTypes.TEXT, allowNull: false },
15
+ campaign_partner_token: { type: DataTypes.TEXT }, // R5: campaign webhook token (differs from partner_token for Mine 1)
16
+ article_api_base_url: { type: DataTypes.TEXT, allowNull: false },
17
+ campaign_api_base_url: { type: DataTypes.TEXT, allowNull: false },
18
+ perf_api_base_url: { type: DataTypes.TEXT, allowNull: false },
19
+ pixel_id: { type: DataTypes.TEXT },
20
+ ts_value: { type: DataTypes.TEXT },
21
+ event_name: { type: DataTypes.TEXT },
22
+ utm_medium: { type: DataTypes.TEXT },
23
+ default_style: { type: DataTypes.TEXT },
24
+ min_keyword_words: { type: DataTypes.INTEGER, defaultValue: 4 },
25
+ default_domain: { type: DataTypes.TEXT },
26
+ fallback_redirect_domain: { type: DataTypes.TEXT },
27
+ channel_range_min: { type: DataTypes.INTEGER, allowNull: false },
28
+ channel_range_max: { type: DataTypes.INTEGER, allowNull: false },
29
+ rac_mode: { type: DataTypes.TEXT },
30
+ always_redirect: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }, // Tsuf-confirmed: Mine 2 = everything through redirect
31
+ is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
32
+ }, {
33
+ tableName: 'rsoc_feed_configs',
34
+ underscored: true,
35
+ });
36
+
37
+ RSOCFeedConfig.associate = (models) => {
38
+ RSOCFeedConfig.hasMany(models.RSOCRedirectWsCode, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
39
+ RSOCFeedConfig.hasMany(models.MineChannel, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
40
+ RSOCFeedConfig.hasMany(models.MineRedirectDomain, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
41
+ RSOCFeedConfig.hasMany(models.MineBrandBlocklist, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
42
+ RSOCFeedConfig.hasMany(models.MineBrandConfig, { foreignKey: 'feed_id', sourceKey: 'feed_id' });
43
+ };
44
+
45
+ return RSOCFeedConfig;
46
+ };
@@ -1,22 +1,22 @@
1
- // agrs-sequelize/models/RSOCRedirectWsCode.js
2
- const { DataTypes } = require('sequelize');
3
-
4
- module.exports = (sequelize) => {
5
- return sequelize.define('RSOCRedirectWsCode', {
6
- id: { type: DataTypes.UUID, primaryKey: true, defaultValue: DataTypes.UUIDV4 },
7
- feed_id: { type: DataTypes.TEXT, allowNull: false },
8
- domain: { type: DataTypes.TEXT, allowNull: false },
9
- ws_code: { type: DataTypes.TEXT, allowNull: false },
10
- is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
11
- }, {
12
- tableName: 'rsoc_redirect_ws_codes',
13
- underscored: true,
14
- // R5: the Task 1 DDL for this table has NO created_at/updated_at columns.
15
- // Without timestamps:false, Sequelize adds them to every SELECT/INSERT →
16
- // "column created_at does not exist" on the brand-redirect hot path.
17
- timestamps: false,
18
- // R5: NO `indexes` declaration — sequelize.sync() creates missing declared
19
- // indexes even with alter:false, and the auto-generated name would duplicate
20
- // the DDL's UNIQUE constraint index. Constraints are migration-managed only.
21
- });
22
- };
1
+ // agrs-sequelize/models/RSOCRedirectWsCode.js
2
+ const { DataTypes } = require('sequelize');
3
+
4
+ module.exports = (sequelize) => {
5
+ return sequelize.define('RSOCRedirectWsCode', {
6
+ id: { type: DataTypes.UUID, primaryKey: true, defaultValue: DataTypes.UUIDV4 },
7
+ feed_id: { type: DataTypes.TEXT, allowNull: false },
8
+ domain: { type: DataTypes.TEXT, allowNull: false },
9
+ ws_code: { type: DataTypes.TEXT, allowNull: false },
10
+ is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
11
+ }, {
12
+ tableName: 'rsoc_redirect_ws_codes',
13
+ underscored: true,
14
+ // R5: the Task 1 DDL for this table has NO created_at/updated_at columns.
15
+ // Without timestamps:false, Sequelize adds them to every SELECT/INSERT →
16
+ // "column created_at does not exist" on the brand-redirect hot path.
17
+ timestamps: false,
18
+ // R5: NO `indexes` declaration — sequelize.sync() creates missing declared
19
+ // indexes even with alter:false, and the auto-generated name would duplicate
20
+ // the DDL's UNIQUE constraint index. Constraints are migration-managed only.
21
+ });
22
+ };
@@ -1,111 +1,111 @@
1
- module.exports = (sequelize, DataTypes) => {
2
- const RsocKeywordPerformance = sequelize.define('RsocKeywordPerformance', {
3
- id: {
4
- type: DataTypes.INTEGER,
5
- primaryKey: true,
6
- autoIncrement: true,
7
- allowNull: false
8
- },
9
- ts: {
10
- type: DataTypes.DATE,
11
- allowNull: false,
12
- comment: 'Timestamp of the record'
13
- },
14
- channel_id: {
15
- type: DataTypes.STRING,
16
- allowNull: false,
17
- comment: 'Channel identifier'
18
- },
19
- style_id: {
20
- type: DataTypes.STRING,
21
- allowNull: true,
22
- comment: 'Style identifier'
23
- },
24
- country_code: {
25
- type: DataTypes.STRING(2),
26
- allowNull: true,
27
- comment: 'Country code (ISO 2-letter)'
28
- },
29
- custom_query: {
30
- type: DataTypes.TEXT,
31
- allowNull: true,
32
- comment: 'Custom search query'
33
- },
34
- query: {
35
- type: DataTypes.TEXT,
36
- allowNull: true,
37
- comment: 'Standard search query'
38
- },
39
- funnel_page_views: {
40
- type: DataTypes.INTEGER,
41
- allowNull: true,
42
- defaultValue: 0,
43
- comment: 'Number of funnel page views'
44
- },
45
- funnel_impressions: {
46
- type: DataTypes.INTEGER,
47
- allowNull: true,
48
- defaultValue: 0,
49
- comment: 'Number of funnel impressions'
50
- },
51
- funnel_clicks: {
52
- type: DataTypes.INTEGER,
53
- allowNull: true,
54
- defaultValue: 0,
55
- comment: 'Number of funnel clicks'
56
- },
57
- page_views: {
58
- type: DataTypes.INTEGER,
59
- allowNull: true,
60
- defaultValue: 0,
61
- comment: 'Number of page views'
62
- },
63
- impressions: {
64
- type: DataTypes.INTEGER,
65
- allowNull: true,
66
- defaultValue: 0,
67
- comment: 'Number of impressions'
68
- },
69
- clicks: {
70
- type: DataTypes.INTEGER,
71
- allowNull: true,
72
- defaultValue: 0,
73
- comment: 'Number of clicks'
74
- },
75
- agrs_cid: {
76
- type: DataTypes.STRING,
77
- allowNull: true,
78
- comment: 'AGRS campaign identifier linking to campaign data'
79
- }
80
- }, {
81
- tableName: 'rsoc_keyword_performance',
82
- timestamps: true, // Adds createdAt and updatedAt columns
83
- indexes: [
84
- {
85
- fields: ['channel_id', 'ts'],
86
- name: 'idx_rsoc_keyword_channel_time'
87
- },
88
- {
89
- fields: ['style_id'],
90
- name: 'idx_rsoc_keyword_style'
91
- },
92
- {
93
- fields: ['country_code'],
94
- name: 'idx_rsoc_keyword_country'
95
- },
96
- {
97
- fields: ['agrs_cid'],
98
- name: 'idx_rsoc_keyword_agrs_cid'
99
- }
100
- ]
101
- });
102
-
103
- // Define associations if needed
104
- RsocKeywordPerformance.associate = (models) => {
105
- // Add associations here if your table needs to reference other tables
106
- // For example:
107
- // RsocKeywordPerformance.belongsTo(models.Channel, { foreignKey: 'channel_id' });
108
- };
109
-
110
- return RsocKeywordPerformance;
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const RsocKeywordPerformance = sequelize.define('RsocKeywordPerformance', {
3
+ id: {
4
+ type: DataTypes.INTEGER,
5
+ primaryKey: true,
6
+ autoIncrement: true,
7
+ allowNull: false
8
+ },
9
+ ts: {
10
+ type: DataTypes.DATE,
11
+ allowNull: false,
12
+ comment: 'Timestamp of the record'
13
+ },
14
+ channel_id: {
15
+ type: DataTypes.STRING,
16
+ allowNull: false,
17
+ comment: 'Channel identifier'
18
+ },
19
+ style_id: {
20
+ type: DataTypes.STRING,
21
+ allowNull: true,
22
+ comment: 'Style identifier'
23
+ },
24
+ country_code: {
25
+ type: DataTypes.STRING(2),
26
+ allowNull: true,
27
+ comment: 'Country code (ISO 2-letter)'
28
+ },
29
+ custom_query: {
30
+ type: DataTypes.TEXT,
31
+ allowNull: true,
32
+ comment: 'Custom search query'
33
+ },
34
+ query: {
35
+ type: DataTypes.TEXT,
36
+ allowNull: true,
37
+ comment: 'Standard search query'
38
+ },
39
+ funnel_page_views: {
40
+ type: DataTypes.INTEGER,
41
+ allowNull: true,
42
+ defaultValue: 0,
43
+ comment: 'Number of funnel page views'
44
+ },
45
+ funnel_impressions: {
46
+ type: DataTypes.INTEGER,
47
+ allowNull: true,
48
+ defaultValue: 0,
49
+ comment: 'Number of funnel impressions'
50
+ },
51
+ funnel_clicks: {
52
+ type: DataTypes.INTEGER,
53
+ allowNull: true,
54
+ defaultValue: 0,
55
+ comment: 'Number of funnel clicks'
56
+ },
57
+ page_views: {
58
+ type: DataTypes.INTEGER,
59
+ allowNull: true,
60
+ defaultValue: 0,
61
+ comment: 'Number of page views'
62
+ },
63
+ impressions: {
64
+ type: DataTypes.INTEGER,
65
+ allowNull: true,
66
+ defaultValue: 0,
67
+ comment: 'Number of impressions'
68
+ },
69
+ clicks: {
70
+ type: DataTypes.INTEGER,
71
+ allowNull: true,
72
+ defaultValue: 0,
73
+ comment: 'Number of clicks'
74
+ },
75
+ agrs_cid: {
76
+ type: DataTypes.STRING,
77
+ allowNull: true,
78
+ comment: 'AGRS campaign identifier linking to campaign data'
79
+ }
80
+ }, {
81
+ tableName: 'rsoc_keyword_performance',
82
+ timestamps: true, // Adds createdAt and updatedAt columns
83
+ indexes: [
84
+ {
85
+ fields: ['channel_id', 'ts'],
86
+ name: 'idx_rsoc_keyword_channel_time'
87
+ },
88
+ {
89
+ fields: ['style_id'],
90
+ name: 'idx_rsoc_keyword_style'
91
+ },
92
+ {
93
+ fields: ['country_code'],
94
+ name: 'idx_rsoc_keyword_country'
95
+ },
96
+ {
97
+ fields: ['agrs_cid'],
98
+ name: 'idx_rsoc_keyword_agrs_cid'
99
+ }
100
+ ]
101
+ });
102
+
103
+ // Define associations if needed
104
+ RsocKeywordPerformance.associate = (models) => {
105
+ // Add associations here if your table needs to reference other tables
106
+ // For example:
107
+ // RsocKeywordPerformance.belongsTo(models.Channel, { foreignKey: 'channel_id' });
108
+ };
109
+
110
+ return RsocKeywordPerformance;
111
111
  };
@@ -1,90 +1,90 @@
1
- const { DataTypes } = require("sequelize");
2
-
3
- module.exports = (sequelize) => {
4
- const RuleAction = sequelize.define(
5
- "RuleAction",
6
- {
7
- id: {
8
- type: DataTypes.UUID,
9
- defaultValue: DataTypes.UUIDV4,
10
- primaryKey: true,
11
- },
12
- ruleId: {
13
- type: DataTypes.UUID,
14
- allowNull: false,
15
- references: {
16
- model: "AutomationRule",
17
- key: "id",
18
- },
19
- comment: "Reference to the parent rule",
20
- },
21
- actionType: {
22
- type: DataTypes.ENUM(
23
- "PAUSE",
24
- "ACTIVATE",
25
- "CHANGE_BUDGET",
26
- "CHANGE_BID",
27
- "CHANGE_BID_STRATEGY",
28
- "CUSTOM_ACTION"
29
- ),
30
- allowNull: false,
31
- comment: "Type of action to perform",
32
- },
33
- targetLevel: {
34
- type: DataTypes.ENUM("CAMPAIGN", "ADSET", "AD"),
35
- allowNull: false,
36
- comment: "Level at which the action operates",
37
- },
38
- value: {
39
- type: DataTypes.STRING(255),
40
- allowNull: true,
41
- comment: "Value for the action (budget amount, bid amount, etc.)",
42
- },
43
- valueType: {
44
- type: DataTypes.ENUM("STRING", "NUMBER", "ARRAY"),
45
- allowNull: true,
46
- defaultValue: "STRING",
47
- comment: "Type of the value field",
48
- },
49
- actionConfig: {
50
- type: DataTypes.JSONB,
51
- allowNull: true,
52
- comment:
53
- "Configuration for the action (budget amount, bid strategy, etc.)",
54
- },
55
- order: {
56
- type: DataTypes.INTEGER,
57
- allowNull: false,
58
- defaultValue: 0,
59
- comment: "Order of this action within the rule",
60
- },
61
- isActive: {
62
- type: DataTypes.BOOLEAN,
63
- defaultValue: true,
64
- allowNull: false,
65
- comment: "Whether this action is active",
66
- },
67
- delayMinutes: {
68
- type: DataTypes.INTEGER,
69
- allowNull: true,
70
- defaultValue: 0,
71
- comment: "Delay in minutes before executing this action",
72
- },
73
- },
74
- {
75
- tableName: "RuleActions",
76
- timestamps: true,
77
- // Remove indexes from model definition - they will be created by migration
78
- }
79
- );
80
-
81
- RuleAction.associate = (models) => {
82
- // An action belongs to a rule
83
- RuleAction.belongsTo(models.AutomationRule, {
84
- foreignKey: "ruleId",
85
- as: "rule",
86
- });
87
- };
88
-
89
- return RuleAction;
90
- };
1
+ const { DataTypes } = require("sequelize");
2
+
3
+ module.exports = (sequelize) => {
4
+ const RuleAction = sequelize.define(
5
+ "RuleAction",
6
+ {
7
+ id: {
8
+ type: DataTypes.UUID,
9
+ defaultValue: DataTypes.UUIDV4,
10
+ primaryKey: true,
11
+ },
12
+ ruleId: {
13
+ type: DataTypes.UUID,
14
+ allowNull: false,
15
+ references: {
16
+ model: "AutomationRule",
17
+ key: "id",
18
+ },
19
+ comment: "Reference to the parent rule",
20
+ },
21
+ actionType: {
22
+ type: DataTypes.ENUM(
23
+ "PAUSE",
24
+ "ACTIVATE",
25
+ "CHANGE_BUDGET",
26
+ "CHANGE_BID",
27
+ "CHANGE_BID_STRATEGY",
28
+ "CUSTOM_ACTION"
29
+ ),
30
+ allowNull: false,
31
+ comment: "Type of action to perform",
32
+ },
33
+ targetLevel: {
34
+ type: DataTypes.ENUM("CAMPAIGN", "ADSET", "AD"),
35
+ allowNull: false,
36
+ comment: "Level at which the action operates",
37
+ },
38
+ value: {
39
+ type: DataTypes.STRING(255),
40
+ allowNull: true,
41
+ comment: "Value for the action (budget amount, bid amount, etc.)",
42
+ },
43
+ valueType: {
44
+ type: DataTypes.ENUM("STRING", "NUMBER", "ARRAY"),
45
+ allowNull: true,
46
+ defaultValue: "STRING",
47
+ comment: "Type of the value field",
48
+ },
49
+ actionConfig: {
50
+ type: DataTypes.JSONB,
51
+ allowNull: true,
52
+ comment:
53
+ "Configuration for the action (budget amount, bid strategy, etc.)",
54
+ },
55
+ order: {
56
+ type: DataTypes.INTEGER,
57
+ allowNull: false,
58
+ defaultValue: 0,
59
+ comment: "Order of this action within the rule",
60
+ },
61
+ isActive: {
62
+ type: DataTypes.BOOLEAN,
63
+ defaultValue: true,
64
+ allowNull: false,
65
+ comment: "Whether this action is active",
66
+ },
67
+ delayMinutes: {
68
+ type: DataTypes.INTEGER,
69
+ allowNull: true,
70
+ defaultValue: 0,
71
+ comment: "Delay in minutes before executing this action",
72
+ },
73
+ },
74
+ {
75
+ tableName: "RuleActions",
76
+ timestamps: true,
77
+ // Remove indexes from model definition - they will be created by migration
78
+ }
79
+ );
80
+
81
+ RuleAction.associate = (models) => {
82
+ // An action belongs to a rule
83
+ RuleAction.belongsTo(models.AutomationRule, {
84
+ foreignKey: "ruleId",
85
+ as: "rule",
86
+ });
87
+ };
88
+
89
+ return RuleAction;
90
+ };