agrs-sequelize-sdk 1.4.52 → 1.4.53

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 (116) 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 +152 -152
  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 -163
  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 -0
  54. package/models/CampaignTagAssignment.js +48 -0
  55. package/models/CanonicalInsights.js +68 -68
  56. package/models/Channel.js +55 -55
  57. package/models/Domain.js +44 -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 +40 -40
  68. package/models/MineChannel.js +42 -42
  69. package/models/MineRedirectDomain.js +36 -36
  70. package/models/MineWebhookEvent.js +53 -53
  71. package/models/Pages.js +117 -117
  72. package/models/PipelineExecution.js +59 -59
  73. package/models/PolicyDogsCreativeCache.js +50 -50
  74. package/models/PolicyDogsImageCache.js +30 -30
  75. package/models/Presets.js +40 -40
  76. package/models/PublicApiBatch.js +155 -155
  77. package/models/PublicApiBatchItem.js +166 -166
  78. package/models/PublicApiIdempotencyCache.js +135 -135
  79. package/models/RSOCFeedCampaign.js +387 -387
  80. package/models/RsocKeywordPerformance.js +110 -110
  81. package/models/RuleAction.js +90 -90
  82. package/models/RuleCondition.js +137 -137
  83. package/models/RuleExecution.js +107 -107
  84. package/models/RulesValues.js +56 -56
  85. package/models/SingularChannel.js +31 -31
  86. package/models/SnapchatAd.js +69 -69
  87. package/models/SnapchatAdSquad.js +92 -92
  88. package/models/SnapchatCampaign.js +69 -69
  89. package/models/SnapchatChannel.js +31 -31
  90. package/models/SnapchatPublicProfiles.js +67 -67
  91. package/models/SupportedLocale.js +23 -23
  92. package/models/SyncHistory.js +249 -249
  93. package/models/TTQChannel.js +42 -42
  94. package/models/TemplateMetadata.js +260 -260
  95. package/models/Tier2_AdAccounts.js +110 -110
  96. package/models/Tier2_Assets.js +70 -70
  97. package/models/Tier2_BusinessManagers.js +105 -105
  98. package/models/Tier2_CreditLines.js +99 -99
  99. package/models/Tier2_Pages.js +91 -91
  100. package/models/Tier2_Pixels.js +82 -82
  101. package/models/Tier2_Tokens.js +64 -64
  102. package/models/Tier2_UserAdAccounts.js +83 -83
  103. package/models/TikTokAd.js +71 -71
  104. package/models/TikTokAdGroup.js +82 -82
  105. package/models/TikTokCampaign.js +71 -71
  106. package/models/TiktokChannel.js +31 -31
  107. package/models/TiktokIdentities.js +65 -65
  108. package/models/TokenRotationState.js +121 -121
  109. package/models/TonicRSOCKeywordPerformance.js +122 -122
  110. package/models/Users.js +190 -185
  111. package/models/Vertical.js +25 -25
  112. package/models/newFiles.js +137 -137
  113. package/package.json +21 -19
  114. package/run.sh +214 -214
  115. package/services/sequelizeService.js +110 -110
  116. package/tarzo-skalio-integration-docs.md +691 -691
@@ -1,99 +1,99 @@
1
- -- Platform column rollout — 14 tables (additive).
2
- -- Generated 2026-05-17. Run against staging first, verify, then production.
3
- -- All ops are additive. No data loss possible. Backfill happens automatically via DEFAULT 'fb'.
4
- --
5
- -- IMPORTANT — 4 tables intentionally OMITTED from this batch because they
6
- -- already have a `platform` column of type VARCHAR with capitalized values
7
- -- (e.g. "Facebook"). Adding an ENUM column with the same name would conflict.
8
- -- These require a separate normalization plan (see migrations/2026-05-17-PIXELS-FOLLOWUP.md):
9
- -- - CampaignCreationLogs (column platform varchar; values 'Facebook' / 'fb' / NULL)
10
- -- - CampaignCreationLogsV2 (column platform varchar; values 'Facebook' / 'fb' / NULL)
11
- -- - rsoc_feed_campaigns (column platform varchar; values 'Facebook' / 'fb')
12
- -- - Pixels (column platform varchar; values 'Facebook' / 'Tiktok' / 'Yahoo' / etc.)
13
- --
14
- -- Tables included in this rollout (14):
15
- -- 1 Campaign 6 ai_campaign_queue 11 articles
16
- -- 2 AdSet 7 facebook_retry_queue 12 dynamic_feeds
17
- -- 3 Ad 8 ai_article_retry_queue 13 CodefuelCampaigns
18
- -- 4 AdAccount 9 AdSetPerformance 14 Presets
19
- -- 5 Pages 10 AdPerformance
20
-
21
- BEGIN;
22
-
23
- DO $$
24
- DECLARE
25
- tbl text;
26
- BEGIN
27
- FOR tbl IN
28
- SELECT unnest(ARRAY[
29
- 'Campaign', 'AdSet', 'Ad', 'AdAccount', 'Pages',
30
- 'ai_campaign_queue', 'facebook_retry_queue', 'ai_article_retry_queue',
31
- 'AdSetPerformance', 'AdPerformance',
32
- 'articles', 'dynamic_feeds', 'CodefuelCampaigns',
33
- 'Presets'
34
- ])
35
- LOOP
36
- -- Create the per-table ENUM type if it doesn't already exist
37
- EXECUTE format(
38
- 'DO $inner$ BEGIN
39
- CREATE TYPE %I AS ENUM (''fb'', ''tt'', ''snp'');
40
- EXCEPTION
41
- WHEN duplicate_object THEN NULL;
42
- END $inner$;',
43
- 'enum_' || tbl || '_platform'
44
- );
45
-
46
- -- Add the column if it doesn't exist
47
- EXECUTE format(
48
- 'ALTER TABLE %I ADD COLUMN IF NOT EXISTS platform %I NOT NULL DEFAULT ''fb'';',
49
- tbl,
50
- 'enum_' || tbl || '_platform'
51
- );
52
-
53
- -- Comment
54
- EXECUTE format(
55
- 'COMMENT ON COLUMN %I.platform IS ''Ad platform identifier: fb=Facebook, tt=TikTok, snp=Snapchat'';',
56
- tbl
57
- );
58
- END LOOP;
59
- END $$;
60
-
61
- COMMIT;
62
-
63
- -- Verification queries — run after COMMIT to confirm:
64
- -- 1) Confirm 14 ENUM columns added (plus 4 pre-existing varchar columns = 18 total rows expected):
65
- -- SELECT table_name, column_name, data_type, udt_name, column_default
66
- -- FROM information_schema.columns
67
- -- WHERE column_name = 'platform'
68
- -- ORDER BY table_name;
69
- --
70
- -- 2) Confirm backfill: every row should have platform='fb':
71
- -- SELECT 'Campaign' AS tbl, platform, COUNT(*) FROM "Campaign" GROUP BY platform
72
- -- UNION ALL SELECT 'AdSet', platform, COUNT(*) FROM "AdSet" GROUP BY platform
73
- -- UNION ALL SELECT 'Ad', platform, COUNT(*) FROM "Ad" GROUP BY platform
74
- -- UNION ALL SELECT 'AdAccount', platform, COUNT(*) FROM "AdAccount" GROUP BY platform
75
- -- UNION ALL SELECT 'Pages', platform, COUNT(*) FROM "Pages" GROUP BY platform
76
- -- UNION ALL SELECT 'ai_campaign_queue', platform, COUNT(*) FROM ai_campaign_queue GROUP BY platform
77
- -- UNION ALL SELECT 'facebook_retry_queue', platform, COUNT(*) FROM facebook_retry_queue GROUP BY platform
78
- -- UNION ALL SELECT 'ai_article_retry_queue',platform, COUNT(*) FROM ai_article_retry_queue GROUP BY platform
79
- -- UNION ALL SELECT 'AdSetPerformance', platform, COUNT(*) FROM "AdSetPerformance" GROUP BY platform
80
- -- UNION ALL SELECT 'AdPerformance', platform, COUNT(*) FROM "AdPerformance" GROUP BY platform
81
- -- UNION ALL SELECT 'articles', platform, COUNT(*) FROM articles GROUP BY platform
82
- -- UNION ALL SELECT 'dynamic_feeds', platform, COUNT(*) FROM dynamic_feeds GROUP BY platform
83
- -- UNION ALL SELECT 'CodefuelCampaigns',platform, COUNT(*) FROM "CodefuelCampaigns" GROUP BY platform
84
- -- UNION ALL SELECT 'Presets', platform, COUNT(*) FROM "Presets" GROUP BY platform
85
- -- ORDER BY tbl, platform;
86
-
87
- -- ROLLBACK plan (separate transaction; only if needed):
88
- -- BEGIN;
89
- -- DO $$ DECLARE tbl text; BEGIN
90
- -- FOR tbl IN SELECT unnest(ARRAY['Campaign','AdSet','Ad','AdAccount','Pages',
91
- -- 'ai_campaign_queue','facebook_retry_queue','ai_article_retry_queue',
92
- -- 'AdSetPerformance','AdPerformance',
93
- -- 'articles','dynamic_feeds','CodefuelCampaigns','Presets'])
94
- -- LOOP
95
- -- EXECUTE format('ALTER TABLE %I DROP COLUMN IF EXISTS platform;', tbl);
96
- -- EXECUTE format('DROP TYPE IF EXISTS %I;', 'enum_' || tbl || '_platform');
97
- -- END LOOP;
98
- -- END $$;
99
- -- COMMIT;
1
+ -- Platform column rollout — 14 tables (additive).
2
+ -- Generated 2026-05-17. Run against staging first, verify, then production.
3
+ -- All ops are additive. No data loss possible. Backfill happens automatically via DEFAULT 'fb'.
4
+ --
5
+ -- IMPORTANT — 4 tables intentionally OMITTED from this batch because they
6
+ -- already have a `platform` column of type VARCHAR with capitalized values
7
+ -- (e.g. "Facebook"). Adding an ENUM column with the same name would conflict.
8
+ -- These require a separate normalization plan (see migrations/2026-05-17-PIXELS-FOLLOWUP.md):
9
+ -- - CampaignCreationLogs (column platform varchar; values 'Facebook' / 'fb' / NULL)
10
+ -- - CampaignCreationLogsV2 (column platform varchar; values 'Facebook' / 'fb' / NULL)
11
+ -- - rsoc_feed_campaigns (column platform varchar; values 'Facebook' / 'fb')
12
+ -- - Pixels (column platform varchar; values 'Facebook' / 'Tiktok' / 'Yahoo' / etc.)
13
+ --
14
+ -- Tables included in this rollout (14):
15
+ -- 1 Campaign 6 ai_campaign_queue 11 articles
16
+ -- 2 AdSet 7 facebook_retry_queue 12 dynamic_feeds
17
+ -- 3 Ad 8 ai_article_retry_queue 13 CodefuelCampaigns
18
+ -- 4 AdAccount 9 AdSetPerformance 14 Presets
19
+ -- 5 Pages 10 AdPerformance
20
+
21
+ BEGIN;
22
+
23
+ DO $$
24
+ DECLARE
25
+ tbl text;
26
+ BEGIN
27
+ FOR tbl IN
28
+ SELECT unnest(ARRAY[
29
+ 'Campaign', 'AdSet', 'Ad', 'AdAccount', 'Pages',
30
+ 'ai_campaign_queue', 'facebook_retry_queue', 'ai_article_retry_queue',
31
+ 'AdSetPerformance', 'AdPerformance',
32
+ 'articles', 'dynamic_feeds', 'CodefuelCampaigns',
33
+ 'Presets'
34
+ ])
35
+ LOOP
36
+ -- Create the per-table ENUM type if it doesn't already exist
37
+ EXECUTE format(
38
+ 'DO $inner$ BEGIN
39
+ CREATE TYPE %I AS ENUM (''fb'', ''tt'', ''snp'');
40
+ EXCEPTION
41
+ WHEN duplicate_object THEN NULL;
42
+ END $inner$;',
43
+ 'enum_' || tbl || '_platform'
44
+ );
45
+
46
+ -- Add the column if it doesn't exist
47
+ EXECUTE format(
48
+ 'ALTER TABLE %I ADD COLUMN IF NOT EXISTS platform %I NOT NULL DEFAULT ''fb'';',
49
+ tbl,
50
+ 'enum_' || tbl || '_platform'
51
+ );
52
+
53
+ -- Comment
54
+ EXECUTE format(
55
+ 'COMMENT ON COLUMN %I.platform IS ''Ad platform identifier: fb=Facebook, tt=TikTok, snp=Snapchat'';',
56
+ tbl
57
+ );
58
+ END LOOP;
59
+ END $$;
60
+
61
+ COMMIT;
62
+
63
+ -- Verification queries — run after COMMIT to confirm:
64
+ -- 1) Confirm 14 ENUM columns added (plus 4 pre-existing varchar columns = 18 total rows expected):
65
+ -- SELECT table_name, column_name, data_type, udt_name, column_default
66
+ -- FROM information_schema.columns
67
+ -- WHERE column_name = 'platform'
68
+ -- ORDER BY table_name;
69
+ --
70
+ -- 2) Confirm backfill: every row should have platform='fb':
71
+ -- SELECT 'Campaign' AS tbl, platform, COUNT(*) FROM "Campaign" GROUP BY platform
72
+ -- UNION ALL SELECT 'AdSet', platform, COUNT(*) FROM "AdSet" GROUP BY platform
73
+ -- UNION ALL SELECT 'Ad', platform, COUNT(*) FROM "Ad" GROUP BY platform
74
+ -- UNION ALL SELECT 'AdAccount', platform, COUNT(*) FROM "AdAccount" GROUP BY platform
75
+ -- UNION ALL SELECT 'Pages', platform, COUNT(*) FROM "Pages" GROUP BY platform
76
+ -- UNION ALL SELECT 'ai_campaign_queue', platform, COUNT(*) FROM ai_campaign_queue GROUP BY platform
77
+ -- UNION ALL SELECT 'facebook_retry_queue', platform, COUNT(*) FROM facebook_retry_queue GROUP BY platform
78
+ -- UNION ALL SELECT 'ai_article_retry_queue',platform, COUNT(*) FROM ai_article_retry_queue GROUP BY platform
79
+ -- UNION ALL SELECT 'AdSetPerformance', platform, COUNT(*) FROM "AdSetPerformance" GROUP BY platform
80
+ -- UNION ALL SELECT 'AdPerformance', platform, COUNT(*) FROM "AdPerformance" GROUP BY platform
81
+ -- UNION ALL SELECT 'articles', platform, COUNT(*) FROM articles GROUP BY platform
82
+ -- UNION ALL SELECT 'dynamic_feeds', platform, COUNT(*) FROM dynamic_feeds GROUP BY platform
83
+ -- UNION ALL SELECT 'CodefuelCampaigns',platform, COUNT(*) FROM "CodefuelCampaigns" GROUP BY platform
84
+ -- UNION ALL SELECT 'Presets', platform, COUNT(*) FROM "Presets" GROUP BY platform
85
+ -- ORDER BY tbl, platform;
86
+
87
+ -- ROLLBACK plan (separate transaction; only if needed):
88
+ -- BEGIN;
89
+ -- DO $$ DECLARE tbl text; BEGIN
90
+ -- FOR tbl IN SELECT unnest(ARRAY['Campaign','AdSet','Ad','AdAccount','Pages',
91
+ -- 'ai_campaign_queue','facebook_retry_queue','ai_article_retry_queue',
92
+ -- 'AdSetPerformance','AdPerformance',
93
+ -- 'articles','dynamic_feeds','CodefuelCampaigns','Presets'])
94
+ -- LOOP
95
+ -- EXECUTE format('ALTER TABLE %I DROP COLUMN IF EXISTS platform;', tbl);
96
+ -- EXECUTE format('DROP TYPE IF EXISTS %I;', 'enum_' || tbl || '_platform');
97
+ -- END LOOP;
98
+ -- END $$;
99
+ -- COMMIT;
@@ -1,17 +1,17 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- up: async (queryInterface, Sequelize) => {
5
- await queryInterface.addColumn("articles", "requestedFromDashboard", {
6
- type: Sequelize.BOOLEAN,
7
- allowNull: false,
8
- defaultValue: false,
9
- comment:
10
- "Indicates if the article was created through our dashboard (true) or imported from external sources (false)",
11
- });
12
- },
13
-
14
- down: async (queryInterface, Sequelize) => {
15
- await queryInterface.removeColumn("articles", "requestedFromDashboard");
16
- },
17
- };
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ up: async (queryInterface, Sequelize) => {
5
+ await queryInterface.addColumn("articles", "requestedFromDashboard", {
6
+ type: Sequelize.BOOLEAN,
7
+ allowNull: false,
8
+ defaultValue: false,
9
+ comment:
10
+ "Indicates if the article was created through our dashboard (true) or imported from external sources (false)",
11
+ });
12
+ },
13
+
14
+ down: async (queryInterface, Sequelize) => {
15
+ await queryInterface.removeColumn("articles", "requestedFromDashboard");
16
+ },
17
+ };
@@ -1,79 +1,79 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- up: async (queryInterface, Sequelize) => {
5
- // Change AdSetName column from VARCHAR(255) to TEXT
6
- // This is a SAFE operation - PostgreSQL can convert VARCHAR to TEXT without data loss
7
- // All existing data will be preserved
8
-
9
- // First, check if column exists and get its current type
10
- const [columns] = await queryInterface.sequelize.query(`
11
- SELECT column_name, data_type, character_maximum_length
12
- FROM information_schema.columns
13
- WHERE table_name = 'AdSet' AND column_name = 'AdSetName'
14
- `);
15
-
16
- if (columns.length === 0) {
17
- console.log("⚠️ AdSetName column not found, skipping migration");
18
- return;
19
- }
20
-
21
- const currentType = columns[0].data_type;
22
- const currentMaxLength = columns[0].character_maximum_length;
23
-
24
- console.log(
25
- `Current AdSetName type: ${currentType}(${
26
- currentMaxLength || "unlimited"
27
- })`
28
- );
29
-
30
- // Only change if it's currently VARCHAR with length limit
31
- if (currentType === "character varying" && currentMaxLength) {
32
- console.log("Converting AdSetName from VARCHAR to TEXT...");
33
-
34
- // Use direct SQL for more control
35
- await queryInterface.sequelize.query(`
36
- ALTER TABLE "AdSet"
37
- ALTER COLUMN "AdSetName" TYPE TEXT
38
- USING "AdSetName"::TEXT
39
- `);
40
-
41
- console.log("✅ AdSetName successfully converted to TEXT");
42
- } else if (currentType === "text") {
43
- console.log("✅ AdSetName is already TEXT, no change needed");
44
- } else {
45
- console.log(`⚠️ AdSetName is ${currentType}, not changing`);
46
- }
47
- },
48
-
49
- down: async (queryInterface, Sequelize) => {
50
- // Revert back to VARCHAR(255)
51
- // WARNING: This might truncate existing long values if any exist
52
- console.log(
53
- "⚠️ Reverting AdSetName to VARCHAR(255) - this may truncate long values!"
54
- );
55
-
56
- // Check for any values longer than 255 characters
57
- const [longValues] = await queryInterface.sequelize.query(`
58
- SELECT COUNT(*) as count
59
- FROM "AdSet"
60
- WHERE LENGTH("AdSetName") > 255
61
- `);
62
-
63
- if (longValues[0].count > 0) {
64
- console.log(
65
- `⚠️ WARNING: ${longValues[0].count} rows have AdSetName longer than 255 characters!`
66
- );
67
- console.log(
68
- "⚠️ These will be truncated if you proceed with the down migration."
69
- );
70
- }
71
-
72
- await queryInterface.changeColumn("AdSet", "AdSetName", {
73
- type: Sequelize.STRING(255),
74
- allowNull: true,
75
- });
76
-
77
- console.log("✅ AdSetName reverted to VARCHAR(255)");
78
- },
79
- };
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ up: async (queryInterface, Sequelize) => {
5
+ // Change AdSetName column from VARCHAR(255) to TEXT
6
+ // This is a SAFE operation - PostgreSQL can convert VARCHAR to TEXT without data loss
7
+ // All existing data will be preserved
8
+
9
+ // First, check if column exists and get its current type
10
+ const [columns] = await queryInterface.sequelize.query(`
11
+ SELECT column_name, data_type, character_maximum_length
12
+ FROM information_schema.columns
13
+ WHERE table_name = 'AdSet' AND column_name = 'AdSetName'
14
+ `);
15
+
16
+ if (columns.length === 0) {
17
+ console.log("⚠️ AdSetName column not found, skipping migration");
18
+ return;
19
+ }
20
+
21
+ const currentType = columns[0].data_type;
22
+ const currentMaxLength = columns[0].character_maximum_length;
23
+
24
+ console.log(
25
+ `Current AdSetName type: ${currentType}(${
26
+ currentMaxLength || "unlimited"
27
+ })`
28
+ );
29
+
30
+ // Only change if it's currently VARCHAR with length limit
31
+ if (currentType === "character varying" && currentMaxLength) {
32
+ console.log("Converting AdSetName from VARCHAR to TEXT...");
33
+
34
+ // Use direct SQL for more control
35
+ await queryInterface.sequelize.query(`
36
+ ALTER TABLE "AdSet"
37
+ ALTER COLUMN "AdSetName" TYPE TEXT
38
+ USING "AdSetName"::TEXT
39
+ `);
40
+
41
+ console.log("✅ AdSetName successfully converted to TEXT");
42
+ } else if (currentType === "text") {
43
+ console.log("✅ AdSetName is already TEXT, no change needed");
44
+ } else {
45
+ console.log(`⚠️ AdSetName is ${currentType}, not changing`);
46
+ }
47
+ },
48
+
49
+ down: async (queryInterface, Sequelize) => {
50
+ // Revert back to VARCHAR(255)
51
+ // WARNING: This might truncate existing long values if any exist
52
+ console.log(
53
+ "⚠️ Reverting AdSetName to VARCHAR(255) - this may truncate long values!"
54
+ );
55
+
56
+ // Check for any values longer than 255 characters
57
+ const [longValues] = await queryInterface.sequelize.query(`
58
+ SELECT COUNT(*) as count
59
+ FROM "AdSet"
60
+ WHERE LENGTH("AdSetName") > 255
61
+ `);
62
+
63
+ if (longValues[0].count > 0) {
64
+ console.log(
65
+ `⚠️ WARNING: ${longValues[0].count} rows have AdSetName longer than 255 characters!`
66
+ );
67
+ console.log(
68
+ "⚠️ These will be truncated if you proceed with the down migration."
69
+ );
70
+ }
71
+
72
+ await queryInterface.changeColumn("AdSet", "AdSetName", {
73
+ type: Sequelize.STRING(255),
74
+ allowNull: true,
75
+ });
76
+
77
+ console.log("✅ AdSetName reverted to VARCHAR(255)");
78
+ },
79
+ };