agrs-sequelize-sdk 1.0.0
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/LICENSE +21 -0
- package/README.md +1 -0
- package/config/config.json +24 -0
- package/index.js +69 -0
- package/models/ActivityHistory.js +73 -0
- package/models/Ad.js +140 -0
- package/models/AdAccount.js +90 -0
- package/models/AdCreative.js +57 -0
- package/models/AdPerformance.js +65 -0
- package/models/AdPerformanceHourly.js +51 -0
- package/models/AdSet.js +69 -0
- package/models/Campaign.js +112 -0
- package/models/CodefuelCampaign.js +112 -0
- package/models/CodefuelCampaignKWHistory.js +41 -0
- package/models/CodefuelKeywords.js +35 -0
- package/models/CurrencyRate.js +27 -0
- package/models/Files.js +64 -0
- package/models/Folders.js +37 -0
- package/models/KeywordPerformance.js +65 -0
- package/models/KeywordRotationState.js +46 -0
- package/models/Rule.js +39 -0
- package/models/TonicCampaign.js +97 -0
- package/models/Users.js +41 -0
- package/models/pixel.js +33 -0
- package/models/pixels.js +33 -0
- package/package.json +19 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// module.exports = (sequelize, DataTypes) => {
|
|
2
|
+
// const Campaign = sequelize.define(
|
|
3
|
+
// "Campaign",
|
|
4
|
+
// {
|
|
5
|
+
// CampaignID: {
|
|
6
|
+
// type: DataTypes.STRING,
|
|
7
|
+
// primaryKey: true,
|
|
8
|
+
// },
|
|
9
|
+
// CampaignName: {
|
|
10
|
+
// type: DataTypes.STRING,
|
|
11
|
+
// allowNull: true,
|
|
12
|
+
// },
|
|
13
|
+
// AdAccountID: {
|
|
14
|
+
// type: DataTypes.STRING,
|
|
15
|
+
// allowNull: false,
|
|
16
|
+
// references: {
|
|
17
|
+
// model: "AdAccount",
|
|
18
|
+
// key: "AdAccountID",
|
|
19
|
+
// },
|
|
20
|
+
// },
|
|
21
|
+
// CreatedTime: {
|
|
22
|
+
// type: DataTypes.DATE,
|
|
23
|
+
// allowNull: false,
|
|
24
|
+
// },
|
|
25
|
+
// CampaignDelivery: {
|
|
26
|
+
// type: DataTypes.STRING,
|
|
27
|
+
// allowNull: false,
|
|
28
|
+
// },
|
|
29
|
+
// },
|
|
30
|
+
// {
|
|
31
|
+
// tableName: "Campaign",
|
|
32
|
+
// }
|
|
33
|
+
// );
|
|
34
|
+
|
|
35
|
+
// Campaign.associate = (models) => {
|
|
36
|
+
// Campaign.belongsTo(models.AdAccount, { foreignKey: "AdAccountID" });
|
|
37
|
+
// Campaign.hasMany(models.AdSet, { foreignKey: "CampaignID" }); // Association to AdSet
|
|
38
|
+
// };
|
|
39
|
+
|
|
40
|
+
// return Campaign;
|
|
41
|
+
// };
|
|
42
|
+
|
|
43
|
+
module.exports = (sequelize, DataTypes) => {
|
|
44
|
+
const Campaign = sequelize.define(
|
|
45
|
+
"Campaign",
|
|
46
|
+
{
|
|
47
|
+
CampaignID: {
|
|
48
|
+
type: DataTypes.STRING,
|
|
49
|
+
primaryKey: true,
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
CampaignName: {
|
|
53
|
+
type: DataTypes.STRING,
|
|
54
|
+
allowNull: true,
|
|
55
|
+
},
|
|
56
|
+
pixelId: {
|
|
57
|
+
type: DataTypes.STRING,
|
|
58
|
+
allowNull: true,
|
|
59
|
+
},
|
|
60
|
+
customEventType: {
|
|
61
|
+
type: DataTypes.STRING,
|
|
62
|
+
allowNull: false,
|
|
63
|
+
defaultValue: "PURCHASE", // Default value is 'PURCHASE'
|
|
64
|
+
},
|
|
65
|
+
objective: {
|
|
66
|
+
type: DataTypes.STRING,
|
|
67
|
+
allowNull: false,
|
|
68
|
+
defaultValue: "OUTCOME_SALES", // Default value is 'OUTCOME_SALES'
|
|
69
|
+
},
|
|
70
|
+
status: {
|
|
71
|
+
type: DataTypes.STRING,
|
|
72
|
+
allowNull: true,
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
AdAccountID: {
|
|
76
|
+
type: DataTypes.STRING,
|
|
77
|
+
allowNull: false,
|
|
78
|
+
references: {
|
|
79
|
+
model: "AdAccount",
|
|
80
|
+
key: "AdAccountID",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
CreatedTime: {
|
|
84
|
+
type: DataTypes.DATE,
|
|
85
|
+
allowNull: false,
|
|
86
|
+
},
|
|
87
|
+
CampaignDelivery: {
|
|
88
|
+
type: DataTypes.STRING,
|
|
89
|
+
allowNull: false,
|
|
90
|
+
},
|
|
91
|
+
DailyBudget: {
|
|
92
|
+
type: DataTypes.INTEGER,
|
|
93
|
+
allowNull: true,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
tableName: "Campaign",
|
|
98
|
+
indexes: [
|
|
99
|
+
{
|
|
100
|
+
fields: ["AdAccountID"], // Index on AdAccountID for faster join
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
Campaign.associate = (models) => {
|
|
107
|
+
Campaign.belongsTo(models.AdAccount, { foreignKey: "AdAccountID" });
|
|
108
|
+
Campaign.hasMany(models.AdSet, { foreignKey: "CampaignID" });
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return Campaign;
|
|
112
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const { DataTypes } = require("sequelize");
|
|
2
|
+
module.exports = (sequelize, DataTypes) => {
|
|
3
|
+
const CodefuelCampaign = sequelize.define("CodefuelCampaign", {
|
|
4
|
+
AGRSCID: {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
allowNull: true,
|
|
7
|
+
unique: true,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
},
|
|
10
|
+
Assignee: {
|
|
11
|
+
type: DataTypes.STRING,
|
|
12
|
+
allowNull: false,
|
|
13
|
+
},
|
|
14
|
+
Status: {
|
|
15
|
+
type: DataTypes.STRING,
|
|
16
|
+
allowNull: false,
|
|
17
|
+
},
|
|
18
|
+
Country: {
|
|
19
|
+
type: DataTypes.STRING,
|
|
20
|
+
allowNull: false,
|
|
21
|
+
},
|
|
22
|
+
Vertical: {
|
|
23
|
+
type: DataTypes.STRING,
|
|
24
|
+
allowNull: false,
|
|
25
|
+
},
|
|
26
|
+
FreeText: {
|
|
27
|
+
type: DataTypes.TEXT,
|
|
28
|
+
allowNull: true,
|
|
29
|
+
},
|
|
30
|
+
CampaignName: {
|
|
31
|
+
type: DataTypes.STRING,
|
|
32
|
+
allowNull: false,
|
|
33
|
+
},
|
|
34
|
+
CampaignID: {
|
|
35
|
+
type: DataTypes.STRING,
|
|
36
|
+
allowNull: true,
|
|
37
|
+
},
|
|
38
|
+
KW: {
|
|
39
|
+
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
40
|
+
allowNull: true,
|
|
41
|
+
},
|
|
42
|
+
FinalLink: {
|
|
43
|
+
type: DataTypes.STRING(1024),
|
|
44
|
+
allowNull: true,
|
|
45
|
+
},
|
|
46
|
+
PixelID: {
|
|
47
|
+
type: DataTypes.STRING(1024),
|
|
48
|
+
allowNull: true,
|
|
49
|
+
},
|
|
50
|
+
Token: {
|
|
51
|
+
type: DataTypes.STRING(1024),
|
|
52
|
+
allowNull: true,
|
|
53
|
+
},
|
|
54
|
+
AccountID: {
|
|
55
|
+
type: DataTypes.STRING,
|
|
56
|
+
allowNull: false,
|
|
57
|
+
},
|
|
58
|
+
FeedName: {
|
|
59
|
+
type: DataTypes.STRING,
|
|
60
|
+
allowNull: true,
|
|
61
|
+
},
|
|
62
|
+
AdTitle: {
|
|
63
|
+
type: DataTypes.STRING,
|
|
64
|
+
allowNull: true,
|
|
65
|
+
},
|
|
66
|
+
Domain: {
|
|
67
|
+
type: DataTypes.STRING,
|
|
68
|
+
allowNull: true,
|
|
69
|
+
},
|
|
70
|
+
feedProvider: {
|
|
71
|
+
type: DataTypes.STRING,
|
|
72
|
+
allowNull: false,
|
|
73
|
+
defaultValue: "CodeFuel",
|
|
74
|
+
},
|
|
75
|
+
lastUpdateKw: {
|
|
76
|
+
type: DataTypes.DATE,
|
|
77
|
+
allowNull: true,
|
|
78
|
+
},
|
|
79
|
+
createdCampaignAt: {
|
|
80
|
+
type: DataTypes.DATE,
|
|
81
|
+
allowNull: true, // Ensure this is allowed to be null if necessary
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
CodefuelCampaign.associate = (models) => {
|
|
85
|
+
CodefuelCampaign.hasMany(models.Ad, {
|
|
86
|
+
foreignKey: "AGRS_CID",
|
|
87
|
+
sourceKey: "AGRSCID",
|
|
88
|
+
as: "Ads",
|
|
89
|
+
constraints: false,
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
// Hook to save the previous KW version to history before updating
|
|
93
|
+
CodefuelCampaign.beforeUpdate(async (campaign, options) => {
|
|
94
|
+
if (campaign.changed("KW")) {
|
|
95
|
+
const previousKW = campaign.previous("KW");
|
|
96
|
+
const currentHistory =
|
|
97
|
+
await sequelize.models.CodefuelCampaignKWHistory.findAll({
|
|
98
|
+
where: { campaignId: campaign.AGRSCID },
|
|
99
|
+
order: [["version", "DESC"]],
|
|
100
|
+
});
|
|
101
|
+
const nextVersion = currentHistory.length
|
|
102
|
+
? currentHistory[0].version + 1
|
|
103
|
+
: 1;
|
|
104
|
+
await sequelize.models.CodefuelCampaignKWHistory.create({
|
|
105
|
+
campaignId: campaign.AGRSCID,
|
|
106
|
+
kw: previousKW,
|
|
107
|
+
version: nextVersion,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return CodefuelCampaign;
|
|
112
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const { DataTypes } = require("sequelize");
|
|
2
|
+
|
|
3
|
+
module.exports = (sequelize, DataTypes) => {
|
|
4
|
+
const CodefuelCampaignKWHistory = sequelize.define(
|
|
5
|
+
"CodefuelCampaignKWHistory",
|
|
6
|
+
{
|
|
7
|
+
id: {
|
|
8
|
+
type: DataTypes.INTEGER,
|
|
9
|
+
autoIncrement: true,
|
|
10
|
+
primaryKey: true,
|
|
11
|
+
},
|
|
12
|
+
campaignId: {
|
|
13
|
+
type: DataTypes.STRING,
|
|
14
|
+
allowNull: false,
|
|
15
|
+
},
|
|
16
|
+
kw: {
|
|
17
|
+
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
18
|
+
allowNull: false,
|
|
19
|
+
},
|
|
20
|
+
version: {
|
|
21
|
+
type: DataTypes.INTEGER,
|
|
22
|
+
allowNull: false,
|
|
23
|
+
},
|
|
24
|
+
createdAt: {
|
|
25
|
+
type: DataTypes.DATE,
|
|
26
|
+
allowNull: false,
|
|
27
|
+
defaultValue: DataTypes.NOW,
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CodefuelCampaignKWHistory.associate = (models) => {
|
|
33
|
+
CodefuelCampaignKWHistory.belongsTo(models.CodefuelCampaign, {
|
|
34
|
+
foreignKey: "campaignId",
|
|
35
|
+
targetKey: "AGRSCID",
|
|
36
|
+
onDelete: "CASCADE",
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return CodefuelCampaignKWHistory;
|
|
41
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
};
|
package/models/Files.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize, DataTypes) => {
|
|
3
|
+
const Files = sequelize.define("Files", {
|
|
4
|
+
id: {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
primaryKey: true,
|
|
7
|
+
},
|
|
8
|
+
name: {
|
|
9
|
+
type: DataTypes.STRING,
|
|
10
|
+
allowNull: false,
|
|
11
|
+
},
|
|
12
|
+
type: {
|
|
13
|
+
type: DataTypes.STRING, // Can be "image" or "video"
|
|
14
|
+
allowNull: false,
|
|
15
|
+
},
|
|
16
|
+
adAccountId: {
|
|
17
|
+
type: DataTypes.STRING,
|
|
18
|
+
allowNull: false,
|
|
19
|
+
},
|
|
20
|
+
URL: {
|
|
21
|
+
type: DataTypes.STRING, // URL for the file
|
|
22
|
+
allowNull: false,
|
|
23
|
+
},
|
|
24
|
+
ParentFolder: {
|
|
25
|
+
type: DataTypes.STRING, // Folder ID for the parent folder
|
|
26
|
+
allowNull: true, // This allows the file to exist without a folder
|
|
27
|
+
},
|
|
28
|
+
ParentFolders: {
|
|
29
|
+
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
30
|
+
allowNull: true,
|
|
31
|
+
},
|
|
32
|
+
FileType: {
|
|
33
|
+
type: DataTypes.STRING,
|
|
34
|
+
allowNull: true,
|
|
35
|
+
defaultValue: "txt",
|
|
36
|
+
},
|
|
37
|
+
Size: {
|
|
38
|
+
type: DataTypes.STRING,
|
|
39
|
+
allowNull: true,
|
|
40
|
+
},
|
|
41
|
+
Language: {
|
|
42
|
+
type: DataTypes.STRING,
|
|
43
|
+
allowNull: true,
|
|
44
|
+
},
|
|
45
|
+
Vertical: {
|
|
46
|
+
type: DataTypes.STRING,
|
|
47
|
+
allowNull: true,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
Files.associate = function (models) {
|
|
52
|
+
// Optional relationship: Each file may belong to a folder (ParentFolder), but it can be null
|
|
53
|
+
/*Files.belongsTo(models.Folders, {
|
|
54
|
+
foreignKey: "ParentFolders",
|
|
55
|
+
targetKey: "id",
|
|
56
|
+
allowNull: true,
|
|
57
|
+
});*/
|
|
58
|
+
|
|
59
|
+
// Each file belongs to an AdCreative (assuming this is a separate model)
|
|
60
|
+
Files.belongsTo(models.AdCreative, { foreignKey: "id", targetKey: "id" });
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return Files;
|
|
64
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
return Folders;
|
|
36
|
+
};
|
|
37
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tableName: "KeywordPerformance",
|
|
34
|
+
indexes: [
|
|
35
|
+
{
|
|
36
|
+
unique: true,
|
|
37
|
+
fields: ["adID", "Date", "Keyword"], // Composite unique index for fast lookups
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
fields: ["Date"], // Index for date filtering
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
fields: ["adID"], // Index for faster joins on adID
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
fields: ["Keyword"], // Index for faster searches on Keyword
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
fields: ["Revenue"], // Index to optimize sorting/filtering on Revenue
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
fields: ["Clicks"], // Index to optimize sorting/filtering on Clicks
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
KeywordPerformance.associate = (models) => {
|
|
59
|
+
KeywordPerformance.belongsTo(models.Ad, {
|
|
60
|
+
foreignKey: "adID",
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return KeywordPerformance;
|
|
65
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
offset: {
|
|
22
|
+
type: DataTypes.INTEGER,
|
|
23
|
+
allowNull: false,
|
|
24
|
+
defaultValue: 0,
|
|
25
|
+
},
|
|
26
|
+
rotationTime: {
|
|
27
|
+
type: DataTypes.INTEGER, // in minutes
|
|
28
|
+
allowNull: false,
|
|
29
|
+
},
|
|
30
|
+
rotatingKeywordSlots: {
|
|
31
|
+
type: DataTypes.INTEGER, // Number of keyword slots assigned to rotation
|
|
32
|
+
allowNull: false,
|
|
33
|
+
},
|
|
34
|
+
lastRotationTime: {
|
|
35
|
+
type: DataTypes.DATE,
|
|
36
|
+
allowNull: true,
|
|
37
|
+
},
|
|
38
|
+
status: {
|
|
39
|
+
type: DataTypes.STRING,
|
|
40
|
+
allowNull: false,
|
|
41
|
+
defaultValue: "Not Set", // Default to started when first created
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return KeywordRotationState;
|
|
46
|
+
};
|
package/models/Rule.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module.exports = (sequelize, DataTypes) => {
|
|
2
|
+
const Rule = sequelize.define("Rule", {
|
|
3
|
+
ruleName: {
|
|
4
|
+
type: DataTypes.STRING,
|
|
5
|
+
allowNull: false,
|
|
6
|
+
},
|
|
7
|
+
timeUnit: {
|
|
8
|
+
type: DataTypes.ENUM("minutes", "hours", "days"),
|
|
9
|
+
allowNull: false,
|
|
10
|
+
},
|
|
11
|
+
timeValue: {
|
|
12
|
+
type: DataTypes.INTEGER,
|
|
13
|
+
allowNull: false,
|
|
14
|
+
},
|
|
15
|
+
daysAndTimes: {
|
|
16
|
+
type: DataTypes.JSONB, // Store days, time ranges, and conditions as a JSON object
|
|
17
|
+
allowNull: true,
|
|
18
|
+
},
|
|
19
|
+
filters: {
|
|
20
|
+
type: DataTypes.JSONB,
|
|
21
|
+
allowNull: true,
|
|
22
|
+
},
|
|
23
|
+
triggers: {
|
|
24
|
+
type: DataTypes.JSONB,
|
|
25
|
+
allowNull: false,
|
|
26
|
+
},
|
|
27
|
+
actions: {
|
|
28
|
+
type: DataTypes.JSONB,
|
|
29
|
+
allowNull: false,
|
|
30
|
+
},
|
|
31
|
+
status: {
|
|
32
|
+
type: DataTypes.ENUM("active", "paused"),
|
|
33
|
+
allowNull: false,
|
|
34
|
+
defaultValue: "active",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return Rule;
|
|
39
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const { DataTypes } = require("sequelize");
|
|
2
|
+
|
|
3
|
+
module.exports = (sequelize, DataTypes) => {
|
|
4
|
+
const TonicCampaign = sequelize.define("TonicCampaign", {
|
|
5
|
+
AGRSCID: {
|
|
6
|
+
type: DataTypes.STRING,
|
|
7
|
+
allowNull: false,
|
|
8
|
+
unique: true,
|
|
9
|
+
primaryKey: true,
|
|
10
|
+
},
|
|
11
|
+
CampaignName: {
|
|
12
|
+
type: DataTypes.STRING,
|
|
13
|
+
allowNull: false,
|
|
14
|
+
},
|
|
15
|
+
CampaignID: {
|
|
16
|
+
type: DataTypes.STRING,
|
|
17
|
+
allowNull: true,
|
|
18
|
+
},
|
|
19
|
+
Vertical: {
|
|
20
|
+
type: DataTypes.STRING,
|
|
21
|
+
allowNull: true,
|
|
22
|
+
},
|
|
23
|
+
Offer: {
|
|
24
|
+
type: DataTypes.STRING,
|
|
25
|
+
allowNull: true,
|
|
26
|
+
},
|
|
27
|
+
OfferID: {
|
|
28
|
+
type: DataTypes.STRING,
|
|
29
|
+
allowNull: true,
|
|
30
|
+
},
|
|
31
|
+
Country: {
|
|
32
|
+
type: DataTypes.STRING,
|
|
33
|
+
allowNull: false,
|
|
34
|
+
},
|
|
35
|
+
Domain: {
|
|
36
|
+
type: DataTypes.STRING,
|
|
37
|
+
allowNull: true,
|
|
38
|
+
},
|
|
39
|
+
Imprint: {
|
|
40
|
+
type: DataTypes.STRING,
|
|
41
|
+
allowNull: true,
|
|
42
|
+
defaultValue: "no",
|
|
43
|
+
},
|
|
44
|
+
Status: {
|
|
45
|
+
type: DataTypes.STRING,
|
|
46
|
+
allowNull: false,
|
|
47
|
+
defaultValue: "inactive",
|
|
48
|
+
},
|
|
49
|
+
FinalLink: {
|
|
50
|
+
type: DataTypes.STRING(1024),
|
|
51
|
+
allowNull: true,
|
|
52
|
+
},
|
|
53
|
+
Assignee: {
|
|
54
|
+
type: DataTypes.STRING,
|
|
55
|
+
allowNull: false,
|
|
56
|
+
},
|
|
57
|
+
KW: {
|
|
58
|
+
type: DataTypes.ARRAY(DataTypes.STRING),
|
|
59
|
+
allowNull: true,
|
|
60
|
+
},
|
|
61
|
+
PixelID: {
|
|
62
|
+
type: DataTypes.STRING(1024),
|
|
63
|
+
allowNull: true,
|
|
64
|
+
},
|
|
65
|
+
Token: {
|
|
66
|
+
type: DataTypes.STRING(1024),
|
|
67
|
+
allowNull: true,
|
|
68
|
+
},
|
|
69
|
+
AccountID: {
|
|
70
|
+
type: DataTypes.STRING,
|
|
71
|
+
allowNull: false,
|
|
72
|
+
},
|
|
73
|
+
FeedName: {
|
|
74
|
+
type: DataTypes.STRING,
|
|
75
|
+
allowNull: true,
|
|
76
|
+
},
|
|
77
|
+
AdTitle: {
|
|
78
|
+
type: DataTypes.STRING,
|
|
79
|
+
allowNull: true,
|
|
80
|
+
},
|
|
81
|
+
Target: {
|
|
82
|
+
type: DataTypes.STRING,
|
|
83
|
+
allowNull: true,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
TonicCampaign.associate = (models) => {
|
|
88
|
+
TonicCampaign.hasMany(models.Ad, {
|
|
89
|
+
foreignKey: "AGRS_CID",
|
|
90
|
+
sourceKey: "AGRSCID",
|
|
91
|
+
constraints: false, // Disable the strict foreign key constraint
|
|
92
|
+
as: "Ads",
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return TonicCampaign;
|
|
97
|
+
};
|