Migrating from cpi-website2
3x generalizes the engine that was built into the cpi-website2 Next.js site (tracker, ingest,
relevance score, lead archive dashboard, conversions, MCP server). The **cpi preset** reproduces
its behaviour 1:1: same event names and props, cm_test / notrack parameters, cpi_* storage
keys, CPI relevance model v1, legacy data-track-* attributes, plaintext lead storage, and
conversion sources quiz, booking, whatsapp_manual.
1. Ad platforms (before deploying)
Composio connections of the CLI "consumer" project cannot be moved. Reconnect inside the 3x Composio project (Composio setup):
- Google Ads with the MCC id,
- Meta in API-key mode with a system-user token (
ads_read+ pixel access), - TikTok with Composio-managed OAuth,
- LinkedIn through the own LinkedIn app (Advertising API + Conversions API products – start the review early; until it is approved LinkedIn shows not connected).
2. Deploy and create the project
- Deploy API and dashboard (Vercel + Neon), including
X3_DASHBOARD_KEY. - Create organization "CPI" and project
cpiwith preset **cpi**. - Destinations: Meta pixel + CAPI token, LinkedIn conversion rules, Google Ads customer and actions
(or the CSV feed) – mirror the previous
META_*,LINKEDIN_*,GOOGLE_ADS_*variables (Conversions). The preset sends Meta event names like cpi-website2:quiz/manual/whatsapp_manual→Lead(WhatsApp withaction_source: chat),booking→Schedule. Projects created before this mapping changed (WhatsApp wasContact) are updated by migration0919_whatsapp_meta_lead.sql; check withGET /v1/projects/cpi/conversion-definitions. - Select the ad accounts; let the 90-day backfill run.
3. Import history
# tracking database (read-only URL) → project "cpi"
npx tsx apps/api/scripts/import-cpi.ts --source-url "$CPI_TRACKING_DB_URL" --dry-run
npx tsx apps/api/scripts/import-cpi.ts --source-url "$CPI_TRACKING_DB_URL"
# lead archive (read-only Vercel Blob token)
CPI_BLOB_READ_TOKEN=… npx tsx apps/api/scripts/import-cpi.ts --blob --dry-run
CPI_BLOB_READ_TOKEN=… npx tsx apps/api/scripts/import-cpi.ts --blobThe import maps video formats quer/hoch → landscape/portrait, gives legacy conversions
legacy:<id> event ids (origin import), re-scores sessions, marks all imported days for rollup
and is idempotent (upsert by id). Lead answers are mapped to questionnaire ids; unmapped answers are
reported, not stored. Compare the dry-run counts with the old dashboard before the real run.
4. Swap the tracker in cpi-website2 (separate change)
| Before | After |
|---|---|
<SiteTracker /> | <X3Analytics host="/n3" /> from @3x-engine/sdk/next |
/api/t ingest route | app/n3/[...path]/route.ts with createX3ProxyHandler from @3x-engine/sdk/next/proxy and a proxy key (Next.js proxy) |
funnelBeacon hooks | bridgeFunnelStage / bridgeQuizAnswer / bridgeFunnelEvent and listenQuizSubmitted() from @3x-engine/sdk/presets |
| quiz, contact, checklist routes writing the Blob archive | x3.leads.create({…, summary, message, spam, conversion: {definition}}) via @3x-engine/sdk/server |
booking beacon /api/conversions/booking | reportBooking(contact) from @3x-engine/sdk/presets (beacon /v1/cb; ad cookies only after consent) |
MCP connector …/api/mcp | https://api…/mcp (OAuth or secret key) |
Google Ads schedule …/api/conversions/google-ads.csv | https://api…/v1/projects/<id>/feeds/google-ads.csv |
Keep the cpi_* storage keys (the preset uses them), so consent and opt-outs survive the switch.
5. Dual-run, then remove the old engine
Run both engines for a week. Compare per day: sessions, pageviews, engaged sessions, quiz submits,
bookings, and the paid split (traffic=paid). Differences within a few percent are expected (bot
filtering and stitching are identical, but the cutover day splits sessions). Then remove the old
tracker, ingest route, cron, MCP route and the Blob archive writes.
Mapping of old concepts
| cpi-website2 | 3x |
|---|---|
| Lead-Archiv tabs (Traffic, Sessions, Relevance, Videos, Scroll, Sections, Flow, Campaigns, Anfragen) | dashboard views with the same names and filters |
track_relevance v1 (SQL) | relevance model cpi-v1 (identical scores, verified by a property test) |
MCP tools overview, breakdown, list_sessions, get_session, page_stats, video_retention, quiz_answers, events, leads, sql_query, mark_conversion, … | analytics_overview, analytics_breakdown, sessions_list, sessions_get, analytics_pages, analytics_video_retention, analytics_answers, events_query, leads_list, sql_query, conversions_mark, … (MCP tools) |
TRACKING_*, META_*, LINKEDIN_*, GOOGLE_ADS_* env vars | per-project settings and destinations in the database |