Daglig ROAS och CAC per kanal. Anomaly-flag och budget-rekommendationer.
Modul-id: performance-tracker · Version: 1.0.0 · Röst: kapaciti · Modell: claude-haiku-4-5
Performance Tracker är en av sexton AI-moduler i Kapaciti-sviten. Den tar emot trettio dagars dagliga marknadsmetrics per kanal och returnerar en strukturerad svensk analys. Output består av en daglig bedömning, en anomalilista, trend-analys per kanal med rot-hypoteser, tre till fem insikter, två till fyra prioriterade rekommendationer, eventuella varningar och en kort sammanfattning som passar att posta i Slack eller Discord klockan 09:00. Hela kedjan signeras i ett audit-bundle som kan verifieras separat.
Modulen är analytisk och trend-fokuserad, vilket skiljer den från paid-ads-manager som är action-orienterad per snapshot. Där paid-ads-manager säger "pausa annonsen nu" säger performance-tracker "google-ads har en creative-fatigue-signal som byggts upp under två veckor och här är de tre mest sannolika rot-orsakerna".
Det primära användarscenariot är en daglig batch-körning vid arbetsdagens start. Pipeline drar gårdagens metrics från Google Ads, Meta Ads, TikTok Ads, programmatiska kanaler eller Stripe-attributering, samlar trettio dagars rolling window per kanal och passar det till modulen. Output blir den dagliga channel-postningen i marketing-teamets Slack. En andra användning är ad hoc, exempelvis när growth lead misstänker att en kanal underpresterar och vill ha en strukturerad bedömning innan de tar budgetbeslut.
Input är ett JSON-objekt med följande nycklar.
{
report_id: "string",
report_date: "ISO date",
channels: [{
name: "string",
daily_metrics: [{
date: "ISO date",
spend_sek: number,
revenue_sek: number,
conversions: number,
roas: number,
cac_sek: number
}]
}],
baseline_period: { start: "ISO date", end: "ISO date" },
alert_thresholds: {
roas_drop_pct: 20,
cac_spike_pct: 30,
conversion_drop_pct: 25
},
brand: { name: "string", voice_profile_id: "string" }
}
Tidsserien per kanal ska vara trettio dagar lång, sorterad stigande efter datum. baseline_period är typiskt sju dagar från för fyra veckor sedan och används som referenspunkt för procent-jämförelser. alert_thresholds styr känsligheten i anomalidetektionen och kan varieras per kund. Defaults motsvarar de tröskelvärden som typiskt används av e-handelsteam med stabil veckotrafik. För högvolyms-kanaler kan tröskelvärdena snävas in, exempelvis till 10-15 procent.
Output är ren text i fast struktur, parsbar utan JSON-tolkning. Modulen har en parsePerformanceOutput() som returnerar ett strukturerat JavaScript-objekt för dashboards och Slack-postare.
DAGENS_BEDOMNING: <stabil | forbattring | forsamring | kritisk>
ROAS_TREND_7D: <stigande | stabil | fallande>
ROAS_TREND_30D: <stigande | stabil | fallande>
ANOMALIER:
- KANAL: <name> | DATUM: <ISO> | TYP: <roas-drop | cac-spike | conversion-drop> | MAGNITUD: <pct change> | KONFIDENS: <lag | medel | hog>
KANAL_TRENDER:
- KANAL: <name>
TREND_30D: <% change in ROAS vs baseline>
RIKTNING: <upp | ner | flat>
ROT_HYPOTES: <1-2 meningar>
TOPP_INSIKTER:
- <3 till 5 punkter>
REKOMMENDATIONER_TILL_TEAM:
- <2 till 4 punkter>
VARNINGAR:
- <0 till 3 punkter>
DAGLIG_SAMMANFATTNING_SLACK:
<3 till 5 meningar svensk prosa>
Strukturen är medvetet rad-baserad för att vara robust mot små formuleringsavvikelser från modellen. Validatorn parsar block för block och kontrollerar att varje rubrik finns och att enum-värden ligger inom sin tillåtna mängd.
En av modulens viktigaste designprinciper är att skilja anomali från trend. En anomali är en enskild dag eller en kort serie där en metric faller eller stiger snabbare än kanalens normala volatilitet. En trend är en sustained förändring över sju till trettio dagar. En kanal kan ha fallande trend utan anomalier, en kanal kan ha en anomali mitt i en stigande trend. Modulen redovisar båda separat.
Anomali-detektion sker i två steg. Först kontrolleras om förändringen överskrider den tröskel som angivits i alert_thresholds. Sedan vägs det mot kanalens normala volatilitet, mätt som rolling standardavvikelse i ROAS. En kanal som normalt rör sig mellan 2.5 och 3.5 ROAS har högre toleranströskel än en kanal som ligger spikrak på 2.0. Konfidens-nivån i output speglar denna kombinerade bedömning, hog innebär minst två gånger tröskeln och tydlig outlier, lag innebär att signalen är nära tröskeln eller inom volatilitetsintervallet.
Rot-hypoteserna är modulens kärnvärde gentemot en ren dashboard. Varje trend och anomali kompletteras med en specifik hypotes, inte ett generiskt "kräver utredning". Typiska hypoteser inkluderar helgeffekt vid lördag-söndags-drop, helgdag som Valborg eller Kristi Himmelsfärd, creative-fatigue när samma annons körts i fjorton dagar eller mer, bud-konkurrens när CAC stiger på konstant budget, tracking-issue när conversions faller utan motsvarande spend-förändring, säsongs-effekt, kampanj-paus, marknadssegment-skifte och landing-page-fel.
Validatorn kontrollerar att rot-hypotesen är icke-tom men inte att den träffar rätt orsak. Det ansvaret ligger på det mänskliga teamet som läser rapporten. Modulen ger en kvalificerad startpunkt, inte ett facit.
Den dagliga sammanfattningen är skriven för 09:00-postningen i marketing-teamets Slack-kanal. Den är tre till fem meningar lång, börjar med dagens bedömning, ger en eller två konkreta siffror och avslutar med en aktion eller observation. Tonen är kollegial och direkt, inte rapport-tung. Inga emojis, inga tankstreck. Den ska kunna läsas i mobilen utan att kräva följdfrågor.
Varje körning producerar ett signerat audit-bundle med sju block i ordning. input_received med hela inputen, context_loaded med per-kanal sammanfattande statistik, agent_call med modell och prompt-längder, output_generated med rå modellsvar, voice_validated med banned-word-skan, output_validated med strukturparse, och audit_sealed.
Bundle-formatet är hash-kedjat och signerat med Ed25519. Verifiering kan ske med lib/audit-chain.mjs verifyBundle() eller med den fristående verifieraren i kapaciti-site/scripts/verify-audit-bundle.mjs. Tamper-resistens har testats genom att mutera ett block och köra verifieraren, som då returnerar ok: false. Detta gör bundlet juridiskt användbart för compliance-rapportering och för att backa upp budget-beslut mot ledningen i efterhand.
Output passeras genom två lager innan modulen returnerar. Voice-guarden skannar mot rost-profilen kapaciti och fångar förbjudna ord och tankstreck. Output-validatorn parsar strukturen och kontrollerar att enum-värden i DAGENS_BEDOMNING, ROAS_TREND_7D, ROAS_TREND_30D, anomali-typ och konfidens ligger inom sin tillåtna mängd. Om något block saknas eller är för kort flaggas det som missing_section. Vid violation loggas det i audit-bundlet, modulen retry inte automatiskt.
Modulen läser enbart vad som finns i input. Den har ingen kunskap om externa händelser, exempelvis algoritm-uppdateringar hos plattformarna, makro-händelser eller konkurrent-aktioner. Den kan inte verifiera om tracking-pipelinen faktiskt är trasig, den kan bara observera att mönstret matchar en tracking-issue-hypotes. Modulens output ska behandlas som en strukturerad första-bedömning, inte ett auktoritativt facit. Vid hög-magnitud-anomalier är manuell verifiering av rådatan obligatorisk innan budget-beslut tas.
Justera input-objektet eller använd starter-värdena. När du trycker på Kör modulen anropas samma agent som i produktion. Audit-kedjan byggs framför dig och hela sessionen signeras med Ed25519 i samma format som exempel-bundlen ovan.
JSON-payload som matchar modulens validateInput. Starter-värdena kommer från en riktig produktionskörning. Max 12 000 tecken.
Audit-kedjan visas här när scenariot körs
● Nyhetsbrev
En sammanfattning ungefär en gång i månaden. Vad förändrats i regelverket, vilka pilot-cases vi sett och vilka vendor-shifts som påverkar svenska bolag. Skickas av oss, inte av en automation som låtsas vara oss.