agrs-sequelize-sdk 1.4.54 → 1.4.57

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.
@@ -1,48 +1,48 @@
1
- module.exports = (sequelize, DataTypes) => {
2
- const CampaignTagAssignment = sequelize.define(
3
- "CampaignTagAssignment",
4
- {
5
- id: {
6
- type: DataTypes.UUID,
7
- defaultValue: DataTypes.UUIDV4,
8
- primaryKey: true,
9
- },
10
- tag_id: {
11
- type: DataTypes.UUID,
12
- allowNull: false,
13
- field: "tag_id",
14
- references: { model: "campaign_tags", key: "id" },
15
- },
16
- campaign_id: {
17
- type: DataTypes.STRING,
18
- allowNull: false,
19
- field: "campaign_id",
20
- references: { model: "Campaign", key: "CampaignID" },
21
- comment: "Campaign.CampaignID (fb/tt/snp)",
22
- },
23
- },
24
- {
25
- tableName: "campaign_tag_assignments",
26
- underscored: true,
27
- indexes: [
28
- { unique: true, fields: ["tag_id", "campaign_id"] },
29
- { fields: ["campaign_id"] },
30
- { fields: ["tag_id"] },
31
- ],
32
- }
33
- );
34
-
35
- CampaignTagAssignment.associate = (models) => {
36
- CampaignTagAssignment.belongsTo(models.CampaignTag, {
37
- foreignKey: "tag_id",
38
- as: "tag",
39
- });
40
- CampaignTagAssignment.belongsTo(models.Campaign, {
41
- foreignKey: "campaign_id",
42
- targetKey: "CampaignID",
43
- as: "campaign",
44
- });
45
- };
46
-
47
- return CampaignTagAssignment;
48
- };
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const CampaignTagAssignment = sequelize.define(
3
+ "CampaignTagAssignment",
4
+ {
5
+ id: {
6
+ type: DataTypes.UUID,
7
+ defaultValue: DataTypes.UUIDV4,
8
+ primaryKey: true,
9
+ },
10
+ tag_id: {
11
+ type: DataTypes.UUID,
12
+ allowNull: false,
13
+ field: "tag_id",
14
+ references: { model: "campaign_tags", key: "id" },
15
+ },
16
+ campaign_id: {
17
+ type: DataTypes.STRING,
18
+ allowNull: false,
19
+ field: "campaign_id",
20
+ references: { model: "Campaign", key: "CampaignID" },
21
+ comment: "Campaign.CampaignID (fb/tt/snp)",
22
+ },
23
+ },
24
+ {
25
+ tableName: "campaign_tag_assignments",
26
+ underscored: true,
27
+ indexes: [
28
+ { unique: true, fields: ["tag_id", "campaign_id"] },
29
+ { fields: ["campaign_id"] },
30
+ { fields: ["tag_id"] },
31
+ ],
32
+ }
33
+ );
34
+
35
+ CampaignTagAssignment.associate = (models) => {
36
+ CampaignTagAssignment.belongsTo(models.CampaignTag, {
37
+ foreignKey: "tag_id",
38
+ as: "tag",
39
+ });
40
+ CampaignTagAssignment.belongsTo(models.Campaign, {
41
+ foreignKey: "campaign_id",
42
+ targetKey: "CampaignID",
43
+ as: "campaign",
44
+ });
45
+ };
46
+
47
+ return CampaignTagAssignment;
48
+ };
@@ -10,9 +10,25 @@ module.exports = (sequelize, DataTypes) => {
10
10
  keyword: {
11
11
  type: DataTypes.STRING(255),
12
12
  allowNull: false,
13
- unique: true,
13
+ // R7.1: attribute-level `unique` removed — Task 2 drops the single-column
14
+ // UNIQUE(keyword) and replaces it with composite UNIQUE(feed_id, keyword).
14
15
  comment: "Lowercase normalized keyword",
15
16
  },
17
+ feed_id: {
18
+ type: DataTypes.TEXT,
19
+ allowNull: false,
20
+ defaultValue: "mine-rsoc",
21
+ },
22
+ match_type: {
23
+ type: DataTypes.TEXT,
24
+ allowNull: false,
25
+ defaultValue: "contains", // R5: prod default
26
+ },
27
+ category: {
28
+ type: DataTypes.TEXT,
29
+ allowNull: false,
30
+ defaultValue: "Other", // R5: prod NOT NULL DEFAULT 'Other'
31
+ },
16
32
  is_blocked: {
17
33
  type: DataTypes.BOOLEAN,
18
34
  allowNull: false,
@@ -0,0 +1,26 @@
1
+ // agrs-sequelize/models/MineBrandConfig.js
2
+ const { DataTypes } = require('sequelize');
3
+
4
+ module.exports = (sequelize) => {
5
+ return sequelize.define('MineBrandConfig', {
6
+ // R5: verified prod columns are EXACTLY: key (PK), value (NOT NULL),
7
+ // updated_at (DEFAULT now()) — there is NO id column. Declaring an
8
+ // autoIncrement id makes every SELECT emit "id" → column does not exist.
9
+ feed_id: { type: DataTypes.TEXT, allowNull: false, primaryKey: true },
10
+ key: { type: DataTypes.TEXT, allowNull: false, primaryKey: true },
11
+ value: { type: DataTypes.TEXT, allowNull: false },
12
+ updated_at: { type: DataTypes.DATE },
13
+ }, {
14
+ tableName: 'mine_brand_config',
15
+ underscored: true,
16
+ // R4-K: the real table has updated_at but NO created_at (raw SQL manages
17
+ // updated_at manually). Sequelize defaults to timestamps:true which would
18
+ // add created_at to every SELECT → "column created_at does not exist".
19
+ timestamps: false,
20
+ // R5: NO `indexes` declaration — sync() would create a duplicate of the
21
+ // migration-managed uq_mine_brand_config_feed_key. Composite PK above is
22
+ // the end-state (after Task 2 Visit 2); during the interim window the DB PK
23
+ // is still (key) — model-based reads (findOne/findAll with where) are
24
+ // unaffected; mine_brand_config writes stay raw SQL throughout this plan.
25
+ });
26
+ };
@@ -20,6 +20,11 @@ module.exports = (sequelize, DataTypes) => {
20
20
  allowNull: false,
21
21
  defaultValue: [],
22
22
  },
23
+ feed_id: {
24
+ type: DataTypes.TEXT,
25
+ allowNull: false,
26
+ defaultValue: "mine-rsoc",
27
+ },
23
28
  },
24
29
  {
25
30
  tableName: "mine_channels",
@@ -10,9 +10,15 @@ module.exports = (sequelize, DataTypes) => {
10
10
  domain: {
11
11
  type: DataTypes.STRING(255),
12
12
  allowNull: false,
13
- unique: true,
13
+ // R7.1: attribute-level `unique` removed — Task 2 drops the single-column
14
+ // UNIQUE(domain) and replaces it with composite UNIQUE(feed_id, domain).
14
15
  comment: "Redirect domain, e.g. searchitallday.com",
15
16
  },
17
+ feed_id: {
18
+ type: DataTypes.TEXT,
19
+ allowNull: false,
20
+ defaultValue: "mine-rsoc",
21
+ },
16
22
  weight: {
17
23
  type: DataTypes.INTEGER,
18
24
  allowNull: false,
@@ -0,0 +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
+ };
@@ -0,0 +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
+ };
package/models/Team.js ADDED
@@ -0,0 +1,43 @@
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const Team = sequelize.define(
3
+ "Team",
4
+ {
5
+ id: {
6
+ type: DataTypes.UUID,
7
+ defaultValue: DataTypes.UUIDV4,
8
+ primaryKey: true,
9
+ },
10
+ name: {
11
+ type: DataTypes.STRING(255),
12
+ allowNull: false,
13
+ comment: "Display name for the team",
14
+ },
15
+ created_by: {
16
+ type: DataTypes.UUID,
17
+ allowNull: true,
18
+ field: "created_by",
19
+ references: { model: "Users", key: "id" },
20
+ comment: "Users.id of creator when known",
21
+ },
22
+ },
23
+ {
24
+ tableName: "teams",
25
+ underscored: true,
26
+ timestamps: true,
27
+ indexes: [{ fields: ["name"] }, { fields: ["created_by"] }],
28
+ }
29
+ );
30
+
31
+ Team.associate = (models) => {
32
+ Team.belongsTo(models.Users, {
33
+ foreignKey: "created_by",
34
+ as: "creator",
35
+ });
36
+ Team.hasMany(models.Users, {
37
+ foreignKey: "team_id",
38
+ as: "members",
39
+ });
40
+ };
41
+
42
+ return Team;
43
+ };
package/models/Users.js CHANGED
@@ -157,6 +157,15 @@ module.exports = (sequelize, DataTypes) => {
157
157
  key: "id",
158
158
  },
159
159
  },
160
+ team_id: {
161
+ type: DataTypes.UUID,
162
+ allowNull: true,
163
+ references: {
164
+ model: "teams",
165
+ key: "id",
166
+ },
167
+ comment: "Optional single team this user belongs to",
168
+ },
160
169
  },
161
170
  {
162
171
  tableName: "Users",
@@ -184,6 +193,11 @@ module.exports = (sequelize, DataTypes) => {
184
193
  foreignKey: "created_by",
185
194
  as: "createdCampaignTags",
186
195
  });
196
+
197
+ Users.belongsTo(models.Team, {
198
+ foreignKey: "team_id",
199
+ as: "team",
200
+ });
187
201
  };
188
202
 
189
203
  return Users;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agrs-sequelize-sdk",
3
- "version": "1.4.54",
3
+ "version": "1.4.57",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "start": "node index.js",