1// Acquisition link: ties the vo_acq visitor cookie to the signed-in account so 2// the growth dashboard can classify the visit (new vs returning) and stamp the 3// account with its first copy. Every pre-check that can be free is client-side: 4// no cookie -> nothing happens (no HTTP, no queries); no user -> nothing; fires 5// at most once per page load. The server answers 204 unconditionally and both 6// of its UPDATEs are write-once, so repeat fires across page loads are the 7// single redundancy, not a failure mode. Callers: dashboard.html (after auth 8// resolves), builder.js (after initializeSession), pricing.html (after the 9// checkout API responds). 10(function () { 11 let fired = false; 12 window.voAcquisitionLink = function (user) { 13 if (fired || !user) return; 14 const match = document.cookie.match(/(?:^|; )vo_acq=([0-9a-f-]{36})\.[A-Za-z0-9_-]{1,40}/); 15 if (!match) return; 16 const created = user.metadata && user.metadata.creationTime; 17 if (!created) return; 18 fired = true; 19 user.getIdToken().then(function (token) { 20 const apiUrl = window.APP_CONFIG ? window.APP_CONFIG.getApiUrl() : 'http://localhost:3000'; 21 // keepalive so the pricing fire survives the redirect to Stripe 22 return fetch(apiUrl + '/api/acquisition/link', { 23 method: 'POST', 24 keepalive: true, 25 headers: { 26 'Content-Type': 'application/json', 27 'Authorization': 'Bearer ' + token 28 }, 29 body: JSON.stringify({ visitorId: match[1], accountCreatedAt: created }) 30 }); 31 }).catch(function () {}); 32 }; 33})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.