agrs-sequelize-sdk 1.2.9 → 1.2.11
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/package.json +1 -1
- package/agrs-sequelize/LICENSE +0 -21
- package/agrs-sequelize/README.md +0 -179
- package/agrs-sequelize/index.js +0 -169
- package/agrs-sequelize/jq.exe +0 -0
- package/agrs-sequelize/models/ActivityHistory.js +0 -73
- package/agrs-sequelize/models/Ad.js +0 -209
- package/agrs-sequelize/models/AdAccount.js +0 -91
- package/agrs-sequelize/models/AdAccountValues.js +0 -26
- package/agrs-sequelize/models/AdHistory.js +0 -30
- package/agrs-sequelize/models/AdPerformance.js +0 -84
- package/agrs-sequelize/models/AdPerformanceHourly.js +0 -66
- package/agrs-sequelize/models/AdSet.js +0 -140
- package/agrs-sequelize/models/AdSetHistory.js +0 -30
- package/agrs-sequelize/models/AdsetPerformance.js +0 -116
- package/agrs-sequelize/models/Article.js +0 -156
- package/agrs-sequelize/models/Buyers.js +0 -26
- package/agrs-sequelize/models/Campaign.js +0 -136
- package/agrs-sequelize/models/CampaignCreationLog.js +0 -86
- package/agrs-sequelize/models/CampaignHistory.js +0 -33
- package/agrs-sequelize/models/Channel.js +0 -55
- package/agrs-sequelize/models/CodefuelCampaign.js +0 -159
- package/agrs-sequelize/models/CodefuelCampaignKWHistory.js +0 -41
- package/agrs-sequelize/models/CodefuelKeywords.js +0 -35
- package/agrs-sequelize/models/CurrencyRate.js +0 -27
- package/agrs-sequelize/models/Domain.js +0 -26
- package/agrs-sequelize/models/ExplorAdsChannel.js +0 -62
- package/agrs-sequelize/models/Feed.js +0 -34
- package/agrs-sequelize/models/Files.js +0 -73
- package/agrs-sequelize/models/Folders.js +0 -133
- package/agrs-sequelize/models/KeywordPerformance.js +0 -99
- package/agrs-sequelize/models/KeywordRotationState.js +0 -51
- package/agrs-sequelize/models/Pages.js +0 -74
- package/agrs-sequelize/models/PipelineExecution.js +0 -46
- package/agrs-sequelize/models/RSOCFeedCampaign.js +0 -307
- package/agrs-sequelize/models/RsocKeywordPerformance.js +0 -111
- package/agrs-sequelize/models/Rule.js +0 -39
- package/agrs-sequelize/models/RulesValues.js +0 -56
- package/agrs-sequelize/models/SupportedLocale.js +0 -24
- package/agrs-sequelize/models/TonicCampaign.js +0 -97
- package/agrs-sequelize/models/Users.js +0 -111
- package/agrs-sequelize/models/Vertical.js +0 -26
- package/agrs-sequelize/models/newFiles.js +0 -68
- package/agrs-sequelize/models/pixels.js +0 -33
- package/agrs-sequelize/package-lock.json +0 -405
- package/agrs-sequelize/package.json +0 -19
- package/agrs-sequelize/run.ps1 +0 -98
- package/agrs-sequelize/run.sh +0 -214
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// CodefuelKeywords.js
|
|
2
|
-
|
|
3
|
-
module.exports = (sequelize, DataTypes) => {
|
|
4
|
-
const CodefuelKeywords = sequelize.define("CodefuelKeywords", {
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.INTEGER,
|
|
7
|
-
autoIncrement: true,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
campaignId: {
|
|
11
|
-
type: DataTypes.STRING,
|
|
12
|
-
references: {
|
|
13
|
-
model: "CodefuelCampaigns",
|
|
14
|
-
key: "AGRSCID",
|
|
15
|
-
},
|
|
16
|
-
onDelete: "CASCADE",
|
|
17
|
-
},
|
|
18
|
-
keywords: {
|
|
19
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
20
|
-
allowNull: true,
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
CodefuelKeywords.associate = (models) => {
|
|
25
|
-
CodefuelKeywords.belongsTo(models.CodefuelCampaign, {
|
|
26
|
-
foreignKey: "campaignId",
|
|
27
|
-
onDelete: "CASCADE",
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Ensure Paper Trail is initialized here
|
|
32
|
-
// CodefuelKeywords.hasPaperTrail();
|
|
33
|
-
|
|
34
|
-
return CodefuelKeywords;
|
|
35
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const { DataTypes } = require("sequelize");
|
|
2
|
-
|
|
3
|
-
module.exports = (sequelize) => {
|
|
4
|
-
const CurrencyRate = sequelize.define("CurrencyRate", {
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
currency: {
|
|
11
|
-
type: DataTypes.STRING,
|
|
12
|
-
allowNull: false,
|
|
13
|
-
defaultValue: "ARS",
|
|
14
|
-
},
|
|
15
|
-
rate: {
|
|
16
|
-
type: DataTypes.FLOAT,
|
|
17
|
-
allowNull: false,
|
|
18
|
-
},
|
|
19
|
-
date: {
|
|
20
|
-
type: DataTypes.DATEONLY,
|
|
21
|
-
allowNull: false,
|
|
22
|
-
defaultValue: DataTypes.NOW,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return CurrencyRate;
|
|
27
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const Domain = sequelize.define(
|
|
3
|
-
"Domain",
|
|
4
|
-
{
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
name: {
|
|
11
|
-
type: DataTypes.STRING,
|
|
12
|
-
allowNull: false,
|
|
13
|
-
},
|
|
14
|
-
code: {
|
|
15
|
-
type: DataTypes.STRING,
|
|
16
|
-
allowNull: false,
|
|
17
|
-
unique: true,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
tableName: "Domain",
|
|
22
|
-
}
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
return Domain;
|
|
26
|
-
};
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const ExplorAdsChannel = sequelize.define(
|
|
3
|
-
"ExplorAdsChannel",
|
|
4
|
-
{
|
|
5
|
-
channelId: {
|
|
6
|
-
type: DataTypes.STRING,
|
|
7
|
-
allowNull: false,
|
|
8
|
-
validate: {
|
|
9
|
-
// Validate channel format (br_vt_ch1401 to br_vt_ch1500)
|
|
10
|
-
is: /^br_vt_ch(14[0-9][0-9]|1500)$/
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
status: {
|
|
14
|
-
type: DataTypes.STRING,
|
|
15
|
-
allowNull: false,
|
|
16
|
-
defaultValue: "free",
|
|
17
|
-
validate: {
|
|
18
|
-
isIn: [["free", "used", "archived"]],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
domain: {
|
|
22
|
-
type: DataTypes.STRING,
|
|
23
|
-
allowNull: false,
|
|
24
|
-
defaultValue: "nexoreach.com"
|
|
25
|
-
},
|
|
26
|
-
connectedCampaigns: {
|
|
27
|
-
type: DataTypes.JSONB,
|
|
28
|
-
allowNull: false,
|
|
29
|
-
defaultValue: [],
|
|
30
|
-
},
|
|
31
|
-
lastUsed: {
|
|
32
|
-
type: DataTypes.DATE,
|
|
33
|
-
allowNull: true
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
tableName: "explorads_channels",
|
|
38
|
-
timestamps: true,
|
|
39
|
-
indexes: [
|
|
40
|
-
{
|
|
41
|
-
unique: true,
|
|
42
|
-
fields: ["channelId"],
|
|
43
|
-
name: "unique_explorads_channel"
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
// Define associations
|
|
50
|
-
ExplorAdsChannel.associate = (models) => {
|
|
51
|
-
if (models.RSOCFeedCampaign) {
|
|
52
|
-
ExplorAdsChannel.hasMany(models.RSOCFeedCampaign, {
|
|
53
|
-
foreignKey: "channelId",
|
|
54
|
-
sourceKey: "channelId",
|
|
55
|
-
as: "RSOCFeedCampaigns",
|
|
56
|
-
constraints: false, // Disable FK constraint
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return ExplorAdsChannel;
|
|
62
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const Feed = sequelize.define(
|
|
3
|
-
"Feed",
|
|
4
|
-
{
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
label: {
|
|
11
|
-
type: DataTypes.STRING,
|
|
12
|
-
allowNull: false,
|
|
13
|
-
},
|
|
14
|
-
code: {
|
|
15
|
-
type: DataTypes.STRING,
|
|
16
|
-
allowNull: false,
|
|
17
|
-
unique: true,
|
|
18
|
-
},
|
|
19
|
-
sheet: {
|
|
20
|
-
type: DataTypes.STRING,
|
|
21
|
-
allowNull: false,
|
|
22
|
-
},
|
|
23
|
-
feedProvider: {
|
|
24
|
-
type: DataTypes.STRING,
|
|
25
|
-
allowNull: false,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
tableName: "Feed",
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
return Feed;
|
|
34
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const Files = sequelize.define("Files", {
|
|
3
|
-
id: {
|
|
4
|
-
type: DataTypes.STRING,
|
|
5
|
-
primaryKey: true,
|
|
6
|
-
},
|
|
7
|
-
accounts: {
|
|
8
|
-
type: DataTypes.JSONB(),
|
|
9
|
-
allowNull: true,
|
|
10
|
-
},
|
|
11
|
-
name: {
|
|
12
|
-
type: DataTypes.STRING,
|
|
13
|
-
allowNull: false,
|
|
14
|
-
},
|
|
15
|
-
type: {
|
|
16
|
-
type: DataTypes.STRING, // Can be "image" or "video"
|
|
17
|
-
allowNull: false,
|
|
18
|
-
},
|
|
19
|
-
adAccountId: {
|
|
20
|
-
type: DataTypes.STRING,
|
|
21
|
-
allowNull: true,
|
|
22
|
-
},
|
|
23
|
-
adId: {
|
|
24
|
-
type: DataTypes.STRING,
|
|
25
|
-
allowNull: true,
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
URL: {
|
|
29
|
-
type: DataTypes.STRING, // URL for the file
|
|
30
|
-
allowNull: false,
|
|
31
|
-
},
|
|
32
|
-
ParentFolder: {
|
|
33
|
-
type: DataTypes.STRING, // Folder ID for the parent folder
|
|
34
|
-
allowNull: true, // This allows the file to exist without a folder
|
|
35
|
-
},
|
|
36
|
-
ParentFolders: {
|
|
37
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
38
|
-
allowNull: true,
|
|
39
|
-
},
|
|
40
|
-
FileType: {
|
|
41
|
-
type: DataTypes.STRING,
|
|
42
|
-
allowNull: true,
|
|
43
|
-
defaultValue: "txt",
|
|
44
|
-
},
|
|
45
|
-
Size: {
|
|
46
|
-
type: DataTypes.STRING,
|
|
47
|
-
allowNull: true,
|
|
48
|
-
},
|
|
49
|
-
Language: {
|
|
50
|
-
type: DataTypes.STRING,
|
|
51
|
-
allowNull: true,
|
|
52
|
-
},
|
|
53
|
-
Vertical: {
|
|
54
|
-
type: DataTypes.STRING,
|
|
55
|
-
allowNull: true,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
return Files;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/*
|
|
63
|
-
[
|
|
64
|
-
{
|
|
65
|
-
accountId: kkelks,
|
|
66
|
-
id: klflf
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
accountId: kkejkjklks,
|
|
70
|
-
id: klflhhkf
|
|
71
|
-
},
|
|
72
|
-
]
|
|
73
|
-
*/
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const Folders = sequelize.define("Folders", {
|
|
3
|
-
id: {
|
|
4
|
-
type: DataTypes.STRING,
|
|
5
|
-
primaryKey: true,
|
|
6
|
-
},
|
|
7
|
-
ParentFolder: {
|
|
8
|
-
type: DataTypes.STRING, // Self-referencing folder ID
|
|
9
|
-
allowNull: true,
|
|
10
|
-
},
|
|
11
|
-
ParentFolders: {
|
|
12
|
-
type: DataTypes.ARRAY(DataTypes.STRING), // Array of folder IDs
|
|
13
|
-
allowNull: true,
|
|
14
|
-
},
|
|
15
|
-
name: {
|
|
16
|
-
type: DataTypes.STRING,
|
|
17
|
-
allowNull: false,
|
|
18
|
-
},
|
|
19
|
-
FilesCount: {
|
|
20
|
-
type: DataTypes.INTEGER,
|
|
21
|
-
allowNull: true,
|
|
22
|
-
defaultValue: 0,
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
Folders.associate = function (models) {
|
|
27
|
-
// One-to-many: A folder can have many files
|
|
28
|
-
Folders.hasMany(models.Files, { foreignKey: "ParentFolder", sourceKey: "id" });
|
|
29
|
-
|
|
30
|
-
// Self-referencing: A folder can have subfolders
|
|
31
|
-
Folders.hasMany(models.Folders, { foreignKey: "ParentFolder", sourceKey: "id" });
|
|
32
|
-
Folders.belongsTo(models.Folders, { foreignKey: "ParentFolder", targetKey: "id" });
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// Function to count files and subfolders for each parent folder in ParentFolders array
|
|
36
|
-
Folders.countFilesAndSubfolders = async function (parentFolderIds) {
|
|
37
|
-
try {
|
|
38
|
-
const { Files } = sequelize.models; // Move the reference inside the function
|
|
39
|
-
|
|
40
|
-
// Loop through each parent folder ID
|
|
41
|
-
for (const parentFolderId of parentFolderIds) {
|
|
42
|
-
// Find the parent folder by ID
|
|
43
|
-
const parentFolder = await Folders.findOne({ where: { id: parentFolderId } });
|
|
44
|
-
|
|
45
|
-
if (!parentFolder) {
|
|
46
|
-
console.warn(`Folder with ID ${parentFolderId} not found.`);
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Count the number of files directly under this folder
|
|
51
|
-
const fileCount = await Files.count({
|
|
52
|
-
where: { ParentFolder: parentFolder.id }
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Count the number of subfolders directly under this folder
|
|
56
|
-
const subfolderCount = await Folders.count({
|
|
57
|
-
where: { ParentFolder: parentFolder.id }
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Total count is files + subfolders
|
|
61
|
-
const totalFilesCount = fileCount + subfolderCount;
|
|
62
|
-
|
|
63
|
-
// Update the FilesCount field in the parent folder
|
|
64
|
-
await parentFolder.update({ FilesCount: totalFilesCount });
|
|
65
|
-
}
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error(error);
|
|
68
|
-
throw error;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// Add a hook that triggers after a folder is created, updated, or deleted
|
|
73
|
-
Folders.addHook('afterCreate', async (folder, options) => {
|
|
74
|
-
if (folder.ParentFolders && folder.ParentFolders.length > 0) {
|
|
75
|
-
await Folders.countFilesAndSubfolders(folder.ParentFolders);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
Folders.addHook('afterDestroy', async (folder, options) => {
|
|
80
|
-
if (folder.ParentFolders && folder.ParentFolders.length > 0) {
|
|
81
|
-
await Folders.countFilesAndSubfolders(folder.ParentFolders);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
Folders.addHook('afterUpdate', async (folder, options) => {
|
|
86
|
-
if (folder.ParentFolders && folder.ParentFolders.length > 0) {
|
|
87
|
-
await Folders.countFilesAndSubfolders(folder.ParentFolders);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Add hooks for Files
|
|
92
|
-
sequelize.models.Files.addHook('afterCreate', async (file, options) => {
|
|
93
|
-
if (file.ParentFolders && file.ParentFolders.length > 0) {
|
|
94
|
-
await Folders.countFilesAndSubfolders(file.ParentFolders);
|
|
95
|
-
} else if (file.ParentFolder) {
|
|
96
|
-
await Folders.countFilesAndSubfolders([file.ParentFolder]);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
sequelize.models.Files.addHook('afterDestroy', async (file, options) => {
|
|
101
|
-
if (file.ParentFolders && file.ParentFolders.length > 0) {
|
|
102
|
-
await Folders.countFilesAndSubfolders(file.ParentFolders);
|
|
103
|
-
} else if (file.ParentFolder) {
|
|
104
|
-
await Folders.countFilesAndSubfolders([file.ParentFolder]);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
sequelize.models.Files.addHook('afterUpdate', async (file, options) => {
|
|
109
|
-
if (file.ParentFolders && file.ParentFolders.length > 0) {
|
|
110
|
-
await Folders.countFilesAndSubfolders(file.ParentFolders);
|
|
111
|
-
} else if (file.ParentFolder) {
|
|
112
|
-
await Folders.countFilesAndSubfolders([file.ParentFolder]);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Add a hook before saving the folder to check ParentFolders
|
|
117
|
-
Folders.addHook('beforeSave', (folder, options) => {
|
|
118
|
-
// If ParentFolders is an empty array or contains only nulls, set it to null
|
|
119
|
-
if (folder.ParentFolders && (folder.ParentFolders.length === 0 || folder.ParentFolders.every(f => f === null))) {
|
|
120
|
-
folder.ParentFolders = null;
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// You can also add this hook for files
|
|
125
|
-
sequelize.models.Files.addHook('beforeSave', (file, options) => {
|
|
126
|
-
// If ParentFolders is an empty array or contains only nulls, set it to null
|
|
127
|
-
if (file.ParentFolders && (file.ParentFolders.length === 0 || file.ParentFolders.every(f => f === null))) {
|
|
128
|
-
file.ParentFolders = null;
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
return Folders;
|
|
133
|
-
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const KeywordPerformance = sequelize.define(
|
|
3
|
-
"KeywordPerformance",
|
|
4
|
-
{
|
|
5
|
-
Date: {
|
|
6
|
-
type: DataTypes.DATEONLY,
|
|
7
|
-
primaryKey: true,
|
|
8
|
-
},
|
|
9
|
-
adID: {
|
|
10
|
-
type: DataTypes.STRING,
|
|
11
|
-
references: {
|
|
12
|
-
model: "Ad",
|
|
13
|
-
key: "AdID",
|
|
14
|
-
},
|
|
15
|
-
foreignKey: true,
|
|
16
|
-
primaryKey: true,
|
|
17
|
-
},
|
|
18
|
-
Keyword: {
|
|
19
|
-
type: DataTypes.STRING,
|
|
20
|
-
allowNull: false,
|
|
21
|
-
primaryKey: true,
|
|
22
|
-
},
|
|
23
|
-
Revenue: {
|
|
24
|
-
type: DataTypes.FLOAT,
|
|
25
|
-
allowNull: false,
|
|
26
|
-
},
|
|
27
|
-
Clicks: {
|
|
28
|
-
type: DataTypes.INTEGER,
|
|
29
|
-
allowNull: false,
|
|
30
|
-
},
|
|
31
|
-
TemplatedKeyword: {
|
|
32
|
-
type: DataTypes.STRING,
|
|
33
|
-
allowNull: true,
|
|
34
|
-
},
|
|
35
|
-
FirstAppearanceDate: {
|
|
36
|
-
type: DataTypes.DATEONLY,
|
|
37
|
-
allowNull: true,
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
tableName: "KeywordPerformance",
|
|
43
|
-
indexes: [
|
|
44
|
-
{
|
|
45
|
-
unique: true,
|
|
46
|
-
fields: ["adID", "Date", "Keyword"], // Composite unique index for fast lookups
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
fields: ["Date"], // Index for date filtering
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
fields: ["adID"], // Index for faster joins on adID
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
fields: ["Keyword"], // Index for faster searches on Keyword
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
fields: ["Revenue"], // Index to optimize sorting/filtering on Revenue
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
fields: ["Clicks"], // Index to optimize sorting/filtering on Clicks
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
hooks: {
|
|
65
|
-
beforeCreate: async (record, options) => {
|
|
66
|
-
try {
|
|
67
|
-
const existingKeyword =
|
|
68
|
-
await sequelize.models.KeywordPerformance.findOne({
|
|
69
|
-
where: {
|
|
70
|
-
Keyword: sequelize.where(
|
|
71
|
-
sequelize.fn("LOWER", sequelize.col("Keyword")),
|
|
72
|
-
sequelize.fn("LOWER", record.Keyword)
|
|
73
|
-
),
|
|
74
|
-
},
|
|
75
|
-
attributes: ["FirstAppearanceDate"],
|
|
76
|
-
transaction: options.transaction,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// If keyword exists, use its FirstAppearanceDate
|
|
80
|
-
// If not, use the current record's Date
|
|
81
|
-
record.FirstAppearanceDate =
|
|
82
|
-
existingKeyword?.FirstAppearanceDate || record.Date;
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error("Error in FirstAppearanceDate hook:", error);
|
|
85
|
-
throw error;
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
KeywordPerformance.associate = (models) => {
|
|
93
|
-
KeywordPerformance.belongsTo(models.Ad, {
|
|
94
|
-
foreignKey: "adID",
|
|
95
|
-
});
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
return KeywordPerformance;
|
|
99
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// models/KeywordRotationState.js
|
|
2
|
-
const { DataTypes } = require("sequelize");
|
|
3
|
-
|
|
4
|
-
module.exports = (sequelize) => {
|
|
5
|
-
const KeywordRotationState = sequelize.define("KeywordRotationState", {
|
|
6
|
-
campaignId: {
|
|
7
|
-
type: DataTypes.STRING,
|
|
8
|
-
allowNull: false,
|
|
9
|
-
primaryKey: true,
|
|
10
|
-
},
|
|
11
|
-
staticKeywords: {
|
|
12
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
13
|
-
allowNull: false,
|
|
14
|
-
defaultValue: [], // Default to empty array if no static keywords are provided
|
|
15
|
-
},
|
|
16
|
-
rotatingKeywords: {
|
|
17
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
18
|
-
allowNull: false,
|
|
19
|
-
defaultValue: [], // Default to empty array if no rotating keywords are provided
|
|
20
|
-
},
|
|
21
|
-
dynamic: {
|
|
22
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
23
|
-
allowNull: false,
|
|
24
|
-
defaultValue: [], // Default to empty array if no dynamic keywords are provided
|
|
25
|
-
},
|
|
26
|
-
offset: {
|
|
27
|
-
type: DataTypes.INTEGER,
|
|
28
|
-
allowNull: false,
|
|
29
|
-
defaultValue: 0,
|
|
30
|
-
},
|
|
31
|
-
rotationTime: {
|
|
32
|
-
type: DataTypes.STRING, // in minutes
|
|
33
|
-
allowNull: false,
|
|
34
|
-
},
|
|
35
|
-
rotatingKeywordSlots: {
|
|
36
|
-
type: DataTypes.INTEGER, // Number of keyword slots assigned to rotation
|
|
37
|
-
allowNull: false,
|
|
38
|
-
},
|
|
39
|
-
lastRotationTime: {
|
|
40
|
-
type: DataTypes.DATE,
|
|
41
|
-
allowNull: true,
|
|
42
|
-
},
|
|
43
|
-
status: {
|
|
44
|
-
type: DataTypes.STRING,
|
|
45
|
-
allowNull: false,
|
|
46
|
-
defaultValue: "Not Set", // Default to started when first created
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return KeywordRotationState;
|
|
51
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const Pages = sequelize.define(
|
|
3
|
-
"Pages",
|
|
4
|
-
{
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
name: {
|
|
11
|
-
type: DataTypes.STRING,
|
|
12
|
-
allowNull: false,
|
|
13
|
-
},
|
|
14
|
-
code: {
|
|
15
|
-
type: DataTypes.STRING,
|
|
16
|
-
allowNull: false,
|
|
17
|
-
unique: true,
|
|
18
|
-
},
|
|
19
|
-
link: {
|
|
20
|
-
type: DataTypes.STRING,
|
|
21
|
-
allowNull: true,
|
|
22
|
-
},
|
|
23
|
-
feedProvider: {
|
|
24
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
25
|
-
allowNull: false,
|
|
26
|
-
defaultValue: [], // Default value is an empty array
|
|
27
|
-
},
|
|
28
|
-
tasks: {
|
|
29
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
30
|
-
allowNull: false,
|
|
31
|
-
defaultValue: [], // Default value is an empty array
|
|
32
|
-
},
|
|
33
|
-
is_published:{
|
|
34
|
-
type: DataTypes.BOOLEAN,
|
|
35
|
-
allowNull: false,
|
|
36
|
-
defaultValue: true,
|
|
37
|
-
},
|
|
38
|
-
Category: {
|
|
39
|
-
type: DataTypes.STRING,
|
|
40
|
-
allowNull: true,
|
|
41
|
-
},
|
|
42
|
-
Owner: {
|
|
43
|
-
type: DataTypes.STRING,
|
|
44
|
-
allowNull: true,
|
|
45
|
-
},
|
|
46
|
-
Status:{
|
|
47
|
-
type: DataTypes.STRING,
|
|
48
|
-
allowNull: true,
|
|
49
|
-
},
|
|
50
|
-
AdLibrary:{
|
|
51
|
-
type: DataTypes.STRING,
|
|
52
|
-
allowNull: true,
|
|
53
|
-
},
|
|
54
|
-
BusinessManager: {
|
|
55
|
-
type: DataTypes.STRING,
|
|
56
|
-
allowNull: true,
|
|
57
|
-
},
|
|
58
|
-
Users: {
|
|
59
|
-
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
60
|
-
allowNull: false,
|
|
61
|
-
defaultValue: [],
|
|
62
|
-
},
|
|
63
|
-
Archived: {
|
|
64
|
-
type: DataTypes.BOOLEAN,
|
|
65
|
-
allowNull: true,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
tableName: "Pages",
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return Pages;
|
|
74
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
module.exports = (sequelize, DataTypes) => {
|
|
2
|
-
const PipelineExecution = sequelize.define(
|
|
3
|
-
"PipelineExecution",
|
|
4
|
-
{
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
startTime: {
|
|
11
|
-
type: DataTypes.DATE,
|
|
12
|
-
allowNull: false,
|
|
13
|
-
},
|
|
14
|
-
endTime: {
|
|
15
|
-
type: DataTypes.DATE,
|
|
16
|
-
allowNull: false,
|
|
17
|
-
},
|
|
18
|
-
status: {
|
|
19
|
-
type: DataTypes.ENUM("success", "failed"),
|
|
20
|
-
allowNull: false,
|
|
21
|
-
},
|
|
22
|
-
fbDaysBack: {
|
|
23
|
-
type: DataTypes.INTEGER,
|
|
24
|
-
allowNull: true,
|
|
25
|
-
},
|
|
26
|
-
codeFuelDaysBack: {
|
|
27
|
-
type: DataTypes.INTEGER,
|
|
28
|
-
allowNull: true,
|
|
29
|
-
},
|
|
30
|
-
tonicDaysBack: {
|
|
31
|
-
type: DataTypes.INTEGER,
|
|
32
|
-
allowNull: true,
|
|
33
|
-
},
|
|
34
|
-
error: {
|
|
35
|
-
type: DataTypes.TEXT,
|
|
36
|
-
allowNull: true,
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
tableName: "pipeline_executions",
|
|
41
|
-
timestamps: true,
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
return PipelineExecution;
|
|
46
|
-
};
|