Campaigns
Une campagne, c'est l'unité atomique de Trackily : tout (clic, conversion, coût, ROI) est attaché à une campagne. Les sources, flows, landings et offres ne servent à rien sans une campagne qui les orchestre.

Concept
Dans Trackily, une campagne = une URL trackable qui reçoit du trafic d'UNE source (Kadam, Meta, TikTok…) et le dispatche vers UNE ou plusieurs landings, puis vers UNE ou plusieurs offres. Sans campagne, pas de slug /c/<slug>, donc pas de tracking.
Une campagne, c'est aussi le scope par défaut de presque toutes les règles métier : la fréquence de cap, le bot filter, le cloaking workflow, les pixels de retargeting, les règles automizer, les A/B tests — tout se branche au niveau campagne.
Le modèle de données est volontairement linéaire : source → campaign → flow → landing → offer. Un visiteur traverse cette chaîne à chaque clic ; un postback affiliate la remonte en sens inverse pour attribuer la conversion.
┌─────────────────────────────────────────────────────┐
│ FLOW DU CLIC TRACKILY │
└─────────────────────────────────────────────────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Source │ ────▶ │ Campaign │ ────▶ │ Flow │ ────▶ │ Landing │
│ (Kadam, │ │ (slug, │ │ (forced/ │ │ (HTML / │
│ Meta…) │ │ cost, │ │ regular/ │ │ redirect │
│ │ │ cloaking)│ │ default) │ │ / AI) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │
│ ▼ ▼
│ ┌──────────┐ ┌──────────┐
│ │ Visitor │ │ Offer │
│ │ binding │ │ (Everflow│
│ │ (cookie/ │ │ /custom)│
│ │ ip+ua) │ │ │
│ └──────────┘ └──────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Bot filter │ │ Postback │
│ + freq cap │ │ /conversion/ │
│ + cloaking │ │ attribuée │
└──────────────┘ └──────────────┘
Le rôle d'ancre
Toutes les autres entités existent en orbite autour d'une campagne :
- Source : une campagne pointe une
traffic_sources.idpour savoir quel ad network appeler côté API et quels macros remplacer dans l'URL de tracking. - Cloaking workflow :
campaigns.cloaking_workflow_iddétermine quels visiteurs voient la safe page vs la real page. - Bot filter / freq cap : stockés en JSONB sur la campagne (
bot_filter,freq_cap). - Retargeting pixels : array JSONB
retargeting_pixelssur la campagne — chaque pixel est injecté sur les landings servies via/c/<slug>. - Automizer rules : un
automation_rules.campaign_idnon-NULL scope la règle à cette campagne (NULL = globale). - Flow :
flows.campaign_idlie un flow à exactement une campagne — un flow ne vit JAMAIS sans campagne parente.
La routine du clic
- Un clic arrive sur
https://todayoffer.store/c/mon-slug?click_id=xxx&cost=0.12. - Trackily charge la
campaignpar slug, refuse l'accès siis_active=falseou si le bot filter / freq cap rejettent. - Si
cloaking_workflow_idest non-NULL, le workflow visuel s'exécute : safe page → fin du flow, real page → on continue. - Le moteur de flows évalue dans l'ordre
forced → regular → default. Le PREMIER flow dont les filtres matchent gagne. - Le flow choisi tire une
landingau sort (rotation pondérée surschema.landings[]), puis uneoffer(rotation pondérée surschema.offers[]). - Le visiteur est redirigé vers
/lp/<landing-slug>(ou l'URL externe selon le type), avec les paramètres click/cost forwardés. - Le clic est inscrit dans
clicks(avecclick_idexterne,cost, geo, device, landing_id, offer_id, flow_id retenus). - Quand une conversion se produit, le postback
/postback?cid=<click_id>inscrit la ligne dansconversions, qui est jointe aux clicks pour le reporting.
Quoi faire ensuite
- Créer une campagne (UI + MCP)
- Comprendre les flows — comment les landings et offres tournent
- Brancher du cloaking sur une campagne live
- Scoper de l'automizer à une campagne
- Configurer une source de trafic
- A/B-tester deux variantes de landing
Anatomie de la table campaigns
Pour les curieux qui veulent voir ce qui se cache derrière le concept :
| Colonne | Type | Rôle |
|---|---|---|
id |
int (PK) | identifiant interne |
name, slug |
text | identifiants humains et URL |
offer_id |
int (FK) | offer par défaut |
source_id |
int (FK) | traffic source |
cloaking_workflow_id |
int (FK) | si non-NULL, le workflow s'exécute avant le flow engine |
domain |
text | domaine de tracking pour construire l'URL |
cost_model, cost_value |
text / num | CPC / CPM / CPA / revshare / manual + valeur |
bot_filter |
jsonb | configuration filtre bots {enabled, rules} |
freq_cap |
jsonb | freq cap {enabled, max_per_24h, key} |
tracking |
jsonb | meta tracking custom (postback shape, etc.) |
sticky_cta |
jsonb | sticky CTA bar config |
retargeting_pixels |
jsonb (array) | pixels injectés dans les landings servies |
external_campaign_ids |
jsonb | mapping campagne Trackily ↔ campagne sous-jacente source |
audience_passback |
jsonb | config passback (envoyer audience à la source) |
is_active |
boolean | pause / play |
created_at, updated_at, deleted_at |
timestamps |
Voir database.js (table campaigns) pour la migration source-of-truth.
Voir aussi
- Landings — les pages servies via
/c/<slug> - Cloaking — workflows visuels (Drawflow)
- Automizer — règles auto qui pause / boost / dédupliquent
- MCP — concept — pourquoi chaque action UI a un équivalent MCP