agrs-sequelize-sdk 1.4.27 → 1.4.29

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.
@@ -43,6 +43,10 @@ module.exports = (sequelize, DataTypes) => {
43
43
  type: DataTypes.STRING,
44
44
  allowNull: true,
45
45
  },
46
+ BusinessManagerName: {
47
+ type: DataTypes.STRING,
48
+ allowNull: true,
49
+ },
46
50
  Reporting: {
47
51
  type: DataTypes.BOOLEAN,
48
52
  defaultValue: true,
@@ -0,0 +1,31 @@
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const SingularChannel = sequelize.define(
3
+ "SingularChannel",
4
+ {
5
+ channelId: {
6
+ type: DataTypes.STRING,
7
+ allowNull: false,
8
+ unique: true,
9
+ },
10
+ status: {
11
+ type: DataTypes.STRING,
12
+ allowNull: false,
13
+ defaultValue: "free",
14
+ validate: {
15
+ isIn: [["free", "used", "archived"]],
16
+ },
17
+ },
18
+ connectedCampaigns: {
19
+ type: DataTypes.JSONB,
20
+ allowNull: false,
21
+ defaultValue: [],
22
+ },
23
+ },
24
+ {
25
+ tableName: "singular_rsoc_channels",
26
+ timestamps: true,
27
+ }
28
+ );
29
+
30
+ return SingularChannel;
31
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agrs-sequelize-sdk",
3
- "version": "1.4.27",
3
+ "version": "1.4.29",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "start": "node index.js",
@@ -0,0 +1,691 @@
1
+ # Tarzo ↔ Skalio Integration — Full Technical Documentation
2
+
3
+ ## 🎯 Goal & Introduction
4
+
5
+ The goal of this task is to integrate **Tarzo** (platform.tarzo.io) as a new feed provider inside our **Skalio** dashboard, allowing us to launch Facebook campaigns directly from Skalio into Tarzo without using any official API (since Tarzo does not have one). Instead, we reverse-engineered Tarzo's internal API endpoints and authentication mechanism to operate as a normal logged-in user.
6
+
7
+ **What we want to achieve:**
8
+ 1. **Campaign Creation** — Create Tarzo campaigns from Skalio the same way we do for other feed providers (Predicto, Mine, Compado, etc.), using the same Skalio form, naming conventions, and presets.
9
+ 2. **Policy Center Sync** — Fetch policy review statuses (approved, in_review, pending, rejected reasons, notes) from Tarzo and reflect them in Skalio's Campaign Logs page.
10
+ 3. **Performance Reporting** — Fetch revenue, ad clicks, conversions, and other feed-provider metrics from Tarzo by campaign ID, and merge them with the spend data we already pull from Facebook — exactly as we do for other RSOC feeds.
11
+ 4. **Ad Account & Page Sync** — Pull the list of Tarzo ad accounts and Facebook pages into Skalio so they are selectable when creating a Tarzo campaign.
12
+
13
+ **Technical approach:** All communication is server-to-server. The Tarzo user's JWT token (extracted from localStorage on login) is stored securely on our backend. Every API call to Tarzo uses this token in the `Authorization` header. The token auto-refreshes on every response. No browser scraping is needed — all endpoints are standard JSON REST calls.
14
+
15
+ > **Important:** When making requests to Tarzo's system, do not reference our system name, do not mention "API integration", and behave exactly as a regular logged-in Tarzo user would.
16
+
17
+ ---
18
+
19
+ ## Table of Contents
20
+ 1. Architecture Overview
21
+ 2. Tarzo Authentication
22
+ 3. Tarzo API Reference — Campaign Creation
23
+ 4. Tarzo API Reference — Policy Center
24
+ 5. Tarzo API Reference — Performance / Reporting
25
+ 6. Skalio System Overview
26
+ 7. Skalio Internal API Reference
27
+ 8. Field Mapping: Skalio → Tarzo
28
+ 9. Campaign Naming Convention Mapping
29
+ 10. New Skalio Feed Provider Entry ("Tarzo - RSOC")
30
+ 11. Performance Data Fetch Strategy
31
+ 12. Policy Center Integration Strategy
32
+ 13. Ad Accounts & Facebook Pages Sync
33
+ 14. Implementation Checklist
34
+
35
+ ---
36
+
37
+ ## 1. Architecture Overview
38
+
39
+ The integration works as follows: Skalio acts as the orchestrator. When a user creates a campaign in Skalio with "Tarzo - RSOC" selected as the feed provider, Skalio's backend must:
40
+
41
+ 1. Use the Tarzo user's JWT token (stored in a secure backend config, not exposed to the frontend) to authenticate against Tarzo's internal API at `https://prod.tarzo.click/api/v1`
42
+ 2. Pre-check channel availability via `GET /api/v1/channel-management/available`
43
+ 3. POST a campaign payload to `POST /api/v1/facebook/creator/campaign/create`
44
+ 4. Store the returned Tarzo campaign ID mapped to the Skalio campaign ID
45
+ 5. Periodically sync policy status via `GET /api/v1/compliance/feed`
46
+ 6. Periodically sync performance data via `GET /api/v1/facebook/hometalk/campaigns/report/campaign?campaignId=...`
47
+
48
+ No browser-side scraping is needed. All communication is server-to-server using the stored JWT token.
49
+
50
+ ---
51
+
52
+ ## 2. Tarzo Authentication
53
+
54
+ **Token source:** The JWT is stored in Tarzo's browser localStorage under the key "authorization". For your integration, a Tarzo account must be set up as a service account, and the token should be extracted once (at login time) and stored securely on your backend. The token auto-refreshes: every response from Tarzo's API includes a refreshed authorization header — your backend must update the stored token on every response.
55
+
56
+ **How to authenticate every request:**
57
+ ```
58
+ Authorization: <jwt_token>
59
+ Content-Type: application/json
60
+ Accept: application/json
61
+ ```
62
+
63
+ **All requests go to:** `https://prod.tarzo.click/api/v1/<endpoint>`
64
+
65
+ **Session validation:** `GET /api/v1/auth/iam` — call this to validate the token and get user info (firstName, id). These are used in campaign naming.
66
+
67
+ **Token refresh logic:**
68
+ - On each response, check if an `authorization` header is returned
69
+ - If yes, update the stored token with the new value
70
+ - If a `deauthorization` header is returned, the session has expired — re-login required
71
+
72
+ ---
73
+
74
+ ## 3. Tarzo API Reference — Campaign Creation
75
+
76
+ ### Pre-flight Checks
77
+
78
+ **Check available Tarzo channels:**
79
+ ```
80
+ GET /api/v1/channel-management/available?revenueSource=hometalk
81
+ GET /api/v1/channel-management/available?revenueSource=hometalk&integrationId=<integration_id>
82
+ ```
83
+ Returns remaining channel count. Abort if zero.
84
+
85
+ **Get ad accounts:**
86
+ ```
87
+ GET /api/v1/facebook/accounts?revenueSource=hometalk
88
+ ```
89
+ Returns the list of ad account objects. Each has an id and a display code (e.g. "D-1", "R-1920").
90
+
91
+ **Get integrations:**
92
+ ```
93
+ GET /api/v1/integration-management?revenueSource=hometalk&enabled=true&network=facebook
94
+ ```
95
+ Returns integration objects including integration ID (needed for domain filtering and the campaign payload).
96
+
97
+ **Get domains:**
98
+ ```
99
+ GET /api/v1/domain-management?revenueSource=hometalk&network=facebook
100
+ GET /api/v1/domain-management?revenueSource=hometalk&integrationId=<id>
101
+ ```
102
+ Returns available Tarzo domains (e.g. https://www.upgradedhome.com/dcg).
103
+
104
+ **Get topics / offers:**
105
+ ```
106
+ GET /api/v1/backoffice/offers
107
+ ```
108
+ Returns all topics/verticals (e.g. "internet-providers", "roof-replacement").
109
+
110
+ ### Initialize Article (Hometalk)
111
+
112
+ This must be done before campaign creation. It reserves a Tarzo channel and returns an article ID.
113
+
114
+ ```
115
+ POST /api/v1/hometalk/assets/initialize-article
116
+ Content-Type: application/json
117
+
118
+ {
119
+ "offer": "internet-providers",
120
+ "domain": "https://www.upgradedhome.com/dcg",
121
+ "language": "en",
122
+ "keyword": "<main keyword, max 80 chars, English only>",
123
+ "articleContent": "<optional comma-separated extra keywords>",
124
+ "terms": []
125
+ }
126
+ ```
127
+ Returns: An article/channel ID used in the campaign creation URL.
128
+
129
+ ### Create Campaign
130
+
131
+ ```
132
+ POST /api/v1/facebook/creator/campaign/create/<articleId>
133
+ Content-Type: application/json
134
+
135
+ {
136
+ "campaigns": [
137
+ {
138
+ "campaign": {
139
+ "name": "ww-en-fb-tz-tsuf-147-internet-providers-464-[5G Internet Guide]-488",
140
+ "freeText": "",
141
+ "accountId": "act_1234567890",
142
+ "objective": "OUTCOME_SALES",
143
+ "campaignType": "website",
144
+ "specialAdCategories": [],
145
+ "budget": 5,
146
+ "budgetType": "daily",
147
+ "isAdvantagePlus": false
148
+ },
149
+ "adSets": [
150
+ {
151
+ "budget": 5,
152
+ "countries": [],
153
+ "regions": [],
154
+ "language": "en",
155
+ "device": "",
156
+ "platforms": ["facebook", "instagram"],
157
+ "placements": [],
158
+ "os": "",
159
+ "pixelId": "<facebook_pixel_id>",
160
+ "bidStrategy": "LOWEST_COST_WITHOUT_CAP",
161
+ "bidAmount": "",
162
+ "pixelEvent": "PURCHASE",
163
+ "optimizationGoal": "OFFSITE_CONVERSIONS",
164
+ "adType": "SINGLE",
165
+ "startTime": null,
166
+ "attributionSpec": "",
167
+ "ageTargeting": { "min": 18, "max": 65 },
168
+ "genders": [],
169
+ "ads": [
170
+ {
171
+ "status": "ACTIVE",
172
+ "targetUrl": "https://...",
173
+ "urlTag": "",
174
+ "displayUrl": "",
175
+ "pageId": "<facebook_page_id>",
176
+ "pageCredentials": false,
177
+ "primaryText": "...",
178
+ "headlineText": "...",
179
+ "description": "",
180
+ "cta": "LEARN_MORE",
181
+ "selectedCreatives": ["<creative_id>"],
182
+ "translationLanguage": ""
183
+ }
184
+ ]
185
+ }
186
+ ],
187
+ "hometalk": {
188
+ "offer": "internet-providers",
189
+ "keyword": "<main keyword>",
190
+ "articleContent": "",
191
+ "domain": "https://www.upgradedhome.com/dcg",
192
+ "language": "en",
193
+ "terms": []
194
+ }
195
+ }
196
+ ]
197
+ }
198
+ ```
199
+
200
+ **If article was not pre-initialized:** Use `POST /api/v1/facebook/creator/campaign/create` (no trailing ID).
201
+
202
+ **Duplicate an existing campaign:**
203
+ ```
204
+ POST /api/v1/facebook/creator/campaign/duplicate/<baseCampaignId>
205
+ Body: { "campaigns": [...] }
206
+ ```
207
+
208
+ ### Tarzo Campaign Field Reference
209
+
210
+ **Campaign-level fields:**
211
+
212
+ | Field | Type | Allowed Values |
213
+ |---|---|---|
214
+ | objective | enum | OUTCOME_SALES, OUTCOME_TRAFFIC, OUTCOME_LEADS, OUTCOME_ENGAGEMENT, OUTCOME_AWARENESS, OUTCOME_APP_PROMOTION |
215
+ | campaignType | enum | website, app, website-and-app, messaging-app, calls |
216
+ | specialAdCategories | array | [], ["HOUSING"], ["EMPLOYMENT"], ["FINANCIAL_PRODUCTS_SERVICES"] |
217
+ | budgetType | enum | daily, lifetime |
218
+ | budget | number | Any positive number |
219
+ | isAdvantagePlus | boolean | false (default) |
220
+
221
+ **Ad Set-level fields:**
222
+
223
+ | Field | Type | Allowed Values / Notes |
224
+ |---|---|---|
225
+ | bidStrategy | enum | LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, LOWEST_COST_WITH_MIN_ROAS |
226
+ | optimizationGoal | enum | OFFSITE_CONVERSIONS (default), LINK_CLICKS, IMPRESSIONS, LANDING_PAGE_VIEWS |
227
+ | platforms | array | facebook, instagram, messenger, audience_network |
228
+ | adType | enum | SINGLE, FLEXIBLE — NO Carousel support |
229
+ | countries | array | ISO country codes, or empty array for Worldwide |
230
+ | genders | array | ["male"], ["female"], or [] for all |
231
+ | ageTargeting | object | { "min": 18, "max": 65 } |
232
+ | device | string | "desktop", "mobile", or "" for all |
233
+ | os | string | OS filter string or empty |
234
+ | pixelEvent | enum | PURCHASE (default) |
235
+
236
+ **Ad-level fields:**
237
+
238
+ | Field | Type | Notes |
239
+ |---|---|---|
240
+ | cta | enum | LEARN_MORE, WATCH_MORE, WATCH_VIDEO, SHOP_NOW, SIGN_UP, GET_OFFER, APPLY_NOW, GET_QUOTE, SEE_MORE, BOOK_NOW, CONTACT_US, CALLS |
241
+ | headlineText | string | Min 10, max 100 chars |
242
+ | description | string | Optional, min 20 max 250 chars |
243
+ | selectedCreatives | array | Creative IDs from Tarzo's library |
244
+
245
+ **Special categories constraint:** Cannot use HOUSING, EMPLOYMENT, or FINANCIAL_PRODUCTS_SERVICES when targeting Worldwide (empty countries). Enforce this in Skalio before sending.
246
+
247
+ ---
248
+
249
+ ## 4. Tarzo API Reference — Policy Center
250
+
251
+ ### Fetch policy data (paginated)
252
+ ```
253
+ GET /api/v1/compliance/feed
254
+ ?revenueSource=hometalk
255
+ &network=facebook
256
+ &search=
257
+ &status=<allowed|in_review|pending|unknown>
258
+ &integrationId=
259
+ &sortBy=
260
+ &offset=0
261
+ &limit=25
262
+ &users[]=<userId>
263
+ &createdAt.from=<ISO date>
264
+ &createdAt.to=<ISO date>
265
+ &lastCheckedAt.from=<ISO date>
266
+ &lastCheckedAt.to=<ISO date>
267
+ ```
268
+
269
+ ### Get policy totals
270
+ ```
271
+ GET /api/v1/compliance/feed/totals
272
+ ?revenueSource=hometalk
273
+ &network=facebook
274
+ &search=
275
+ &status=
276
+ &integrationId=
277
+ ```
278
+
279
+ ### Export policy data (up to 25,000 rows)
280
+ ```
281
+ POST /api/v1/compliance/feed/export
282
+ Body: same filters as the GET endpoint (JSON)
283
+ ```
284
+
285
+ ### Policy record fields returned:
286
+
287
+ | Field | Notes |
288
+ |---|---|
289
+ | adId | Tarzo's internal Ad ID |
290
+ | adStatus | Active/Paused status |
291
+ | status | allowed, approved, manual-approved, in_review, pending, unknown |
292
+ | campaignId | Tarzo campaign ID |
293
+ | campaignName | Full Tarzo campaign name |
294
+ | adAccountId | Facebook Ad Account ID |
295
+ | reason | Policy rejection reason |
296
+ | notes | Additional notes from reviewer |
297
+ | adName | Name of the ad |
298
+ | headline | Ad headline |
299
+ | adsManagerLink | Link to Facebook Ads Manager |
300
+ | lastCheck | Timestamp of last policy check |
301
+ | createdAt | Record creation timestamp |
302
+ | user | Which Tarzo user created this ad |
303
+
304
+ ---
305
+
306
+ ## 5. Tarzo API Reference — Performance / Reporting
307
+
308
+ All endpoints return: revenue, spend (cost), conversions, feedProviderConversions, feedProviderCpa, networkClicks, impressions, networkRpc, feedProviderSearches, netProfit, roi, roas, ctr, cpc, cpm, rpc, cr, facebookRpc, results.
309
+
310
+ ### All campaigns dashboard list
311
+ ```
312
+ GET /api/v1/facebook/hometalk/campaigns/report
313
+ ?from=YYYY-MM-DD&to=YYYY-MM-DD&limit=25&offset=0&search=&sortBy=&status=&ruleHits=&lastActivity=
314
+ ```
315
+
316
+ ### Dashboard totals (all campaigns)
317
+ ```
318
+ GET /api/v1/facebook/hometalk/campaigns/report/totals
319
+ ?from=YYYY-MM-DD&to=YYYY-MM-DD&search=&status=&ruleHits=&lastActivity=&bidStrategy=
320
+ ```
321
+
322
+ ### Single campaign performance by day
323
+ ```
324
+ GET /api/v1/facebook/hometalk/campaigns/report/campaign
325
+ ?campaignId=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD
326
+ ```
327
+
328
+ ### Totals for a specific campaign
329
+ ```
330
+ GET /api/v1/facebook/hometalk/campaigns/report/totals
331
+ ?campaignId=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD
332
+ ```
333
+
334
+ ### Ad set performance
335
+ ```
336
+ GET /api/v1/facebook/hometalk/adsets/report
337
+ ?campaignIds[]=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD&search=
338
+ ```
339
+
340
+ ### Ad-level performance
341
+ ```
342
+ GET /api/v1/facebook/hometalk/ads/report
343
+ ?campaignIds[]=<tarzo_campaign_id>&from=YYYY-MM-DD&to=YYYY-MM-DD&search=
344
+ ```
345
+
346
+ ### CSV export (max 25,000 rows)
347
+ ```
348
+ POST /api/v1/facebook/{entityType}s/export
349
+ entityType: campaign | adset | ad
350
+ Body: filter params as JSON
351
+ ```
352
+
353
+ ### Get single campaign details
354
+ ```
355
+ GET /api/v1/facebook/campaigns/campaign/<campaignId>
356
+ ```
357
+
358
+ ---
359
+
360
+ ## 6. Skalio System Overview
361
+
362
+ **Framework:** Next.js (React, Recoil state management, MUI components, Zod validation, Axios HTTP client)
363
+ **Base URL:** https://www.skalio.io
364
+ **Internal API base:** All frontend calls go to /api/... (Next.js API routes, server-side)
365
+ **Auth:** Cookie-based session (Next.js middleware)
366
+
367
+ ### Navigation structure:
368
+ - Performance — main campaign performance table
369
+ - Keywords Performance — keyword-level performance
370
+ - Country Breakdown — geo performance
371
+ - Create > Campaigns — general campaign creator
372
+ - Create > Facebook Campaigns — main Facebook creator at /dashboard/facebook
373
+ - Create > Articles — article management
374
+ - Create > Campaign Creation Logs — same as /dashboard/campaign-logs
375
+ - File Manager — media/creative assets
376
+ - Rules Automation — automated rules engine
377
+ - Research — research tools
378
+ - Assets — asset management
379
+ - Generate — AI generation tools
380
+ - Tier2 Business Manager — multi-account management
381
+
382
+ ### Campaign creation modes (3 tabs):
383
+ - **Use Existing** — re-use an existing campaign structure (adds Campaign Name search at top)
384
+ - **AI Campaign** — AI-assisted campaign creation
385
+ - **Create New** — manual creation (the primary flow)
386
+
387
+ ### Create New form fields:
388
+ | Field | Notes |
389
+ |---|---|
390
+ | Platform | Facebook (fixed for this page) |
391
+ | Media Buyer | Buyer code (e.g. "tsuf", "mark") |
392
+ | Feed Provider | Dropdown from Feed table |
393
+ | Vertical | Topic/vertical slug |
394
+ | Country | Single or multi country, or empty for WW |
395
+ | Language | ISO language code |
396
+ | Notes | Free text, maps to freeText in campaign |
397
+ | Ad Title | Maps to headlineText in ad |
398
+ | Keywords | Main keyword + additional keywords |
399
+ | Campaign Name Preview | Auto-generated: agrs-{feed}-fb-tp-{country}-{language}-{vertical}-{ddmm} |
400
+
401
+ ---
402
+
403
+ ## 7. Skalio Internal API Reference
404
+
405
+ ### Campaign Management
406
+ | Endpoint | Method | Description |
407
+ |---|---|---|
408
+ | /api/facebook/campaign/create | POST | Create campaign record in Skalio DB |
409
+ | /api/facebook/campaign/read | GET | Read campaign by ID |
410
+ | /api/facebook/campaign/readBatchCampaign | GET | Read multiple campaigns |
411
+ | /api/facebook/campaign/readcampaignHirarchi | GET | Full hierarchy (campaign+adsets+ads) |
412
+ | /api/facebook/campaign/update | PUT | Update campaign |
413
+ | /api/facebook/campaign/delete | DELETE | Delete campaign |
414
+ | /api/facebook/campaign/duplicate | POST | Duplicate campaign |
415
+ | /api/facebook/campaign/publish | POST | Publish to Facebook |
416
+ | /api/facebook/campaign/restore | POST | Restore deleted campaign |
417
+
418
+ ### Ad Set Management
419
+ | Endpoint | Method | Description |
420
+ |---|---|---|
421
+ | /api/facebook/adset/create | POST | Create ad set |
422
+ | /api/facebook/adset/read | GET | Read ad set |
423
+ | /api/facebook/adset/readAll | GET | Read all ad sets |
424
+ | /api/facebook/adset/readAllFromCampaignId | GET | Read by campaign ID |
425
+ | /api/facebook/adset/update | PUT | Update ad set |
426
+ | /api/facebook/adset/delete | DELETE | Delete ad set |
427
+ | /api/facebook/adset/duplicate | POST | Duplicate ad set |
428
+ | /api/facebook/adset/publish | POST | Publish to Facebook |
429
+ | /api/facebook/adset/restore | POST | Restore ad set |
430
+
431
+ ### Ad Management
432
+ | Endpoint | Method | Description |
433
+ |---|---|---|
434
+ | /api/facebook/ad/create | POST | Create ad |
435
+ | /api/facebook/ad/read | GET | Read ad |
436
+ | /api/facebook/ad/update | PUT | Update ad |
437
+ | /api/facebook/ad/delete | DELETE | Delete ad |
438
+ | /api/facebook/ad/duplicate | POST | Duplicate ad |
439
+ | /api/facebook/ad/publish | POST | Publish to Facebook |
440
+ | /api/newFiles/uploadToFacebook | POST | Upload media to Facebook |
441
+ | /api/newFiles/getAdMedia | GET | Get media for single ad |
442
+ | /api/newFiles/getAdsMedia | GET | Get media for multiple ads |
443
+
444
+ ### Feed Campaign Lifecycle
445
+ | Endpoint | Method | Description |
446
+ |---|---|---|
447
+ | /api/feedCampaign/publishDraftCampaign | POST | KEY: Publishes draft to feed provider. This is where Tarzo integration code goes. |
448
+ | /api/feedCampaign/duplicate | POST | Duplicate a feed campaign |
449
+
450
+ ### Performance
451
+ | Endpoint | Method | Params |
452
+ |---|---|---|
453
+ | /api/performance/campaign/bydate | GET | page, rowsPerPage, sort, date_range, ad_account, campaign_name, ad_status |
454
+ | /api/performance/campaign/byid | GET | feed, buyer, daterange, filterCampaignByIds, created_times, filterByDate, sortByIds, sortByDate, pageByIds, rowsPerPageByIds, adAccount, campaignName, createdTime, adStatus, country, vertical, roi_range, cost_range, ctr_range, rpc_range, cpa_range |
455
+ | /api/performance/campaign/totals | GET | dates, ad_account, campaign_name, ad_status |
456
+ | /api/performance/campaign/draftbyid | GET | Performance for draft campaigns |
457
+
458
+ ### Static / Reference Data
459
+ | Endpoint | Method | Description |
460
+ |---|---|---|
461
+ | /api/static/Feed/findAll | GET | All feed providers |
462
+ | /api/static/Feed/create | POST | Create new feed provider |
463
+ | /api/static/adAccount/findAll | GET | All ad accounts |
464
+ | /api/static/adAccount/create | POST | Create ad account |
465
+ | /api/static/adAccount/update | PUT | Update ad account |
466
+ | /api/static/adAccount/bulk-create | POST | Bulk create ad accounts |
467
+ | /api/static/Pages/findAll | GET | All Facebook pages |
468
+ | /api/static/Pages/create | POST | Create page |
469
+ | /api/static/Pages/update | PUT | Update page |
470
+ | /api/static/Pages/bulk-create | POST | Bulk create pages |
471
+ | /api/static/Buyers/findAll | GET | All media buyers |
472
+ | /api/static/channel/findAll | GET | All channels |
473
+ | /api/static/channel/create | POST | Create channel |
474
+ | /api/static/channel/update | PUT | Update channel |
475
+ | /api/static/channel/bulk-create | POST | Bulk create channels |
476
+ | /api/configuration/getAdConfiguration | GET | Ad-level config. Params: campaignIds, adSetId, adIds |
477
+ | /api/configuration/getAdsetsConfiguration | GET | Adset-level config. Params: campaignIds, adSetIds |
478
+
479
+ ---
480
+
481
+ ## 8. Field Mapping: Skalio → Tarzo
482
+
483
+ ### Campaign Creation Form
484
+
485
+ | Skalio Field | Skalio Value Example | Tarzo Field | Tarzo Value |
486
+ |---|---|---|---|
487
+ | platform | "Facebook" | network | "facebook" |
488
+ | feed | "Tarzo - RSOC" | revenueSource | "hometalk" |
489
+ | buyer | "tsuf" | Used in campaign name | Name segment |
490
+ | vertical | "internet-providers" | hometalk.offer | "internet-providers" |
491
+ | country | ["us"] or [] for WW | adSets[].countries | ["US"] or [] |
492
+ | language | ["en"] | hometalk.language | "en" |
493
+ | notes | "test campaign" | campaign.freeText | "test campaign" |
494
+ | adTitle | "5G Internet Guide" | headlineText + in name | "[5G Internet Guide]" |
495
+ | keywords[0] | "5g internet providers" | hometalk.keyword | "5g internet providers" |
496
+ | keywords[1..n] | Additional keywords | hometalk.articleContent | Comma-separated string |
497
+
498
+ ### Bid Strategy Mapping
499
+
500
+ | Skalio Preset Label | Tarzo bidStrategy value |
501
+ |---|---|
502
+ | "Lowest Cost" / "LC" | LOWEST_COST_WITHOUT_CAP |
503
+ | "Bid Cap" / "BC" | LOWEST_COST_WITH_BID_CAP |
504
+ | "Cost Cap" / "CC" | COST_CAP |
505
+ | "Target ROAS" / "TROAS" | LOWEST_COST_WITH_MIN_ROAS |
506
+
507
+ ### Objective Mapping
508
+
509
+ | Skalio Objective | Tarzo objective |
510
+ |---|---|
511
+ | Sales | OUTCOME_SALES |
512
+ | Traffic | OUTCOME_TRAFFIC |
513
+ | Leads | OUTCOME_LEADS |
514
+ | Engagement | OUTCOME_ENGAGEMENT |
515
+ | Awareness | OUTCOME_AWARENESS |
516
+ | App Promotion | OUTCOME_APP_PROMOTION |
517
+
518
+ ---
519
+
520
+ ## 9. Campaign Naming Convention Mapping
521
+
522
+ ### Skalio naming format:
523
+ ```
524
+ agrs-{feed}-fb-{buyer}-{country}-{language}-{vertical}-{ddmm}
525
+ ```
526
+ Example from live preview: agrs-{feed}-fb-tp-{country}-{language}-{vertical}-0604
527
+
528
+ Where:
529
+ - agrs = system prefix (always fixed)
530
+ - {feed} = feed provider code (propose "tz" for Tarzo)
531
+ - fb = platform
532
+ - {buyer} = media buyer short code (e.g. "tsuf")
533
+ - {country} = ISO code, "mix" (multi-country), or "ww" (worldwide)
534
+ - {language} = language code
535
+ - {vertical} = vertical slug
536
+ - {ddmm} = campaign creation date
537
+
538
+ ### Tarzo naming format:
539
+ ```
540
+ {country_prefix}-{language}-{platform}-{feed_code}-{buyer_code}-{account_last3}-{topic}-{channel_last3}-[{article_title}]-{user_last3}
541
+ ```
542
+ Example: ww-en-fb-tz-tsuf-147-internet-providers-464-[5G Internet Guide]-488
543
+
544
+ Where:
545
+ - ww-en = worldwide + English (0 countries = "ww-en", 1 country = country code, 2+ = "mc-en")
546
+ - fb = facebook
547
+ - tz = Tarzo feed code (fixed)
548
+ - tsuf = buyer/account prefix
549
+ - 147 = last 3 digits of Facebook ad account ID
550
+ - internet-providers = topic slug
551
+ - 464 = last 3 digits of article/channel ID (returned from initialize-article)
552
+ - [5G Internet Guide] = article title in square brackets
553
+ - 488 = last 3 digits of the Tarzo user ID (from /auth/iam)
554
+
555
+ **Rule:** Use Tarzo's naming format in the campaign.name field sent to Tarzo. Store Skalio's own campaign name separately and link both via the Tarzo campaign ID.
556
+
557
+ ---
558
+
559
+ ## 10. New Skalio Feed Provider Entry
560
+
561
+ To add Tarzo as a feed provider in Skalio:
562
+
563
+ ```
564
+ POST /api/static/Feed/create
565
+ Body:
566
+ {
567
+ "feedName": "Tarzo - RSOC",
568
+ "feedType": "rsoc",
569
+ "platform": "Facebook",
570
+ "feedCode": "tz",
571
+ "revenueSource": "hometalk",
572
+ "network": "facebook"
573
+ }
574
+ ```
575
+
576
+ The Feed Provider dropdown is populated from GET /api/static/Feed/findAll — once the record is created, it appears automatically.
577
+
578
+ When Tarzo is selected, the publishDraftCampaign handler must detect feedType: "rsoc" + revenueSource: "hometalk" and route to Tarzo's API.
579
+
580
+ ---
581
+
582
+ ## 11. Performance Data Fetch Strategy
583
+
584
+ **Approach:** Skalio fetches cost/spend from Facebook (existing flow). Tarzo provides revenue and feed-provider metrics only.
585
+
586
+ **Recommended sync:** Every 3 hours per campaign, or on-demand.
587
+
588
+ **Fetch per campaign:**
589
+ ```
590
+ GET /api/v1/facebook/hometalk/campaigns/report/campaign
591
+ ?campaignId=<tarzo_id>&from=<date>&to=<date>
592
+ ```
593
+
594
+ ### Performance Column Mapping
595
+
596
+ | Skalio Column | Tarzo Field | Notes |
597
+ |---|---|---|
598
+ | Revenue | revenue | From Tarzo |
599
+ | Cost | — | From Facebook (existing flow) |
600
+ | Ad Clicks | networkClicks | Tarzo's "ad clicks" metric |
601
+ | Conversions | feedProviderConversions | Feed-level conversions |
602
+ | RPC | networkRpc | Feed provider RPC |
603
+ | CPA | feedProviderCpa | Feed-level CPA |
604
+ | TS RPC | networkRpc | Same field |
605
+ | TS CPA | feedProviderCpa | Same field |
606
+ | CTR % | ctr | From Tarzo |
607
+ | CPC | cpc | From Tarzo |
608
+ | CR % | cr | Conversion rate |
609
+ | Net Profit | revenue - cost | Calculated |
610
+ | ROI | (revenue - cost) / cost * 100 | Calculated |
611
+
612
+ ---
613
+
614
+ ## 12. Policy Center Integration Strategy
615
+
616
+ **Approach:** Daily sync job fetches policy data from Tarzo and stores in Skalio campaign_logs table, keyed by Tarzo adId and campaignId.
617
+
618
+ **Fetch:**
619
+ ```
620
+ GET /api/v1/compliance/feed
621
+ ?revenueSource=hometalk&network=facebook&offset=0&limit=100
622
+ (paginate until all records fetched)
623
+ ```
624
+
625
+ ### Mapping to Skalio Campaign Logs
626
+
627
+ | Skalio Column | Tarzo Policy Field |
628
+ |---|---|
629
+ | Campaign Name | campaignName |
630
+ | Status | adStatus (Active/Paused) |
631
+ | Policy Status | status (allowed, in_review, pending, etc.) |
632
+ | Account | adAccountId |
633
+ | Feed | "Tarzo - RSOC" (hardcoded) |
634
+ | Ad | adId |
635
+ | Campaign Details | reason + notes |
636
+ | User | user |
637
+
638
+ Match records to Skalio campaigns using the campaignId stored at creation time.
639
+
640
+ ---
641
+
642
+ ## 13. Ad Accounts & Facebook Pages Sync
643
+
644
+ **Fetch Tarzo ad accounts:**
645
+ ```
646
+ GET /api/v1/facebook/accounts?revenueSource=hometalk
647
+ ```
648
+ Returns accounts with id (act_XXXXXXX format) and display name (e.g. "D-1").
649
+
650
+ **Store in Skalio:**
651
+ ```
652
+ POST /api/static/adAccount/bulk-create
653
+ Body: { accounts: [{accountId: "act_123...", name: "D-1", feedProvider: "tarzo"}, ...] }
654
+ ```
655
+
656
+ **Facebook Pages:** Page IDs are standard Facebook page IDs. Use Skalio's existing page list (GET /api/static/Pages/findAll). When Tarzo is selected as feed provider, show the page selector — the same page IDs work in both systems.
657
+
658
+ ---
659
+
660
+ ## 14. Implementation Checklist
661
+
662
+ ### Backend
663
+
664
+ - [ ] Create tarzo.service.ts with: base URL (https://prod.tarzo.click/api/v1), token management (read/refresh on every response), and all endpoint wrappers from sections 3–5
665
+ - [ ] Add Tarzo JWT token to secure env/secrets storage; implement auto-refresh logic on every response
666
+ - [ ] Create "Tarzo - RSOC" feed record via POST /api/static/Feed/create
667
+ - [ ] Extend /api/feedCampaign/publishDraftCampaign — add Tarzo branch: detect revenueSource "hometalk", call initialize-article first, then create campaign, save returned Tarzo campaign ID against Skalio campaign ID
668
+ - [ ] Sync Tarzo ad accounts via GET /api/v1/facebook/accounts?revenueSource=hometalk → store with feedProvider: "tarzo" tag
669
+ - [ ] Extend /api/performance/campaign/byid — when feed = "tarzo-rsoc", fetch revenue metrics from Tarzo and merge with Facebook cost data
670
+ - [ ] Create policy sync cron job: call GET /api/v1/compliance/feed paginated → write to campaign_logs table
671
+ - [ ] Fetch and cache Tarzo domain list (GET /api/v1/domain-management?revenueSource=hometalk)
672
+ - [ ] Enforce validation: block HOUSING/EMPLOYMENT/FINANCIAL special categories when countries is empty (Worldwide)
673
+ - [ ] Add tarzo_campaign_id column to Skalio campaigns table
674
+
675
+ ### Frontend
676
+
677
+ - [ ] "Tarzo - RSOC" will appear in Feed Provider dropdown automatically once DB record is created
678
+ - [ ] Show Tarzo-specific fields when Tarzo is selected: Domain selector, Article Content Query (max 80 chars, English), Terms (optional)
679
+ - [ ] Add Facebook Page selector when Tarzo is feed provider (required for ad creation)
680
+ - [ ] Show only Tarzo-tagged ad accounts when Tarzo is feed
681
+ - [ ] Show Tarzo channel availability count (from channel-management/available) before submit
682
+ - [ ] Update Campaign Name Preview to show Tarzo naming format alongside Skalio format
683
+ - [ ] Map Tarzo policy statuses in Campaign Logs: allowed = green, in_review = yellow, pending = orange, unknown = grey
684
+ - [ ] Add "Tarzo" filter option in Performance page Feed dropdown
685
+
686
+ ### Still to confirm
687
+
688
+ 1. **Creative upload to Tarzo** — The upload endpoint is likely POST /api/v1/creatives/library/save/v2 (multipart). Confirm exact field names by capturing a network request when clicking "Upload Media" in the Tarzo Creatives Library. Recommended approach: pre-upload creatives via Tarzo UI, store creative IDs in Skalio, expose a Tarzo Creative selector in the form.
689
+ 2. **Tarzo service account** — Confirm which Tarzo account to use as the service account for the integration.
690
+ 3. **tarzo_campaign_id storage** — Confirm schema changes to store Tarzo campaign ID linked to Skalio campaign ID.
691
+ 4. **Keywords sync** — Planned for a later phase. Tarzo has keyword-level data available via the ads/report endpoint.