cdp-edge 2.5.9 → 2.6.1
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.
- package/README.md +247 -211
- package/bin/cdp-edge.js +1 -0
- package/contracts/agent-versions.json +2 -2
- package/dist/commands/infra.js +1 -1
- package/dist/commands/server.js +38 -33
- package/dist/commands/setup.js +3 -0
- package/dist/commands/validate.js +251 -236
- package/dist/sdk/cdpTrack.js +6 -4
- package/dist/sdk/cdpTrack.min.js +4 -4
- package/dist/sdk/install-snippet.html +1 -1
- package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +4 -4
- package/extracted-skill/tracking-events-generator/Premium-Tracking-Intelligence-Resumo.md +3 -3
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +78 -33
- package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +562 -93
- package/extracted-skill/tracking-events-generator/integration-test.js +3 -3
- package/extracted-skill/tracking-events-generator/knowledge-base.md +12 -12
- package/extracted-skill/tracking-events-generator/models/checkout-proprio.md +1 -1
- package/extracted-skill/tracking-events-generator/models/multi-step-checkout.md +4 -4
- package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +1 -1
- package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +1 -1
- package/extracted-skill/tracking-events-generator/models/scenarios/sales-page-logic.md +1 -1
- package/extracted-skill/tracking-events-generator/models/trafego-direto.md +7 -7
- package/package.json +2 -2
- package/server-edge-tracker/.client.env.example +5 -0
- package/server-edge-tracker/deploy-client.cjs +47 -31
- package/server-edge-tracker/index.ts +1267 -1204
- package/server-edge-tracker/modules/db.ts +2 -2
- package/server-edge-tracker/modules/dispatch/meta.ts +3 -0
- package/server-edge-tracker/modules/dispatch/tiktok.ts +1 -0
- package/server-edge-tracker/modules/dispatch/whatsapp.ts +5 -2
- package/server-edge-tracker/modules/utils.ts +1 -1
- package/server-edge-tracker/types.ts +3 -0
- package/server-edge-tracker/wrangler.toml +2 -0
- package/templates/checkout-proprio.md +1 -1
- package/templates/install/CLAUDE.md +1 -1
- package/templates/multi-step-checkout.md +4 -4
- package/templates/reddit/conversions-api-template.js +1 -1
- package/templates/scenarios/behavior-engine.js +1 -1
- package/templates/scenarios/sales-page-logic.md +1 -1
- package/templates/trafego-direto.md +7 -7
- package/templates/vsl-page.md +2 -2
- package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +0 -707
- package/extracted-skill/tracking-events-generator/agents/zapman-agent.md +0 -189
- package/server-edge-tracker/.client.env +0 -5
- package/server-edge-tracker/dist-check/README.md +0 -1
- package/server-edge-tracker/dist-check/index.js +0 -5164
- package/server-edge-tracker/dist-check/index.js.map +0 -8
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/_internal/utils.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/perf_hooks/performance.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/@cloudflare/unenv-preset/dist/runtime/polyfill/performance.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/console.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/mock/noop.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/@cloudflare/unenv-preset/dist/runtime/node/console.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-console", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/process/hrtime.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/process/process.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/tty/read-stream.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/tty/write-stream.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/unenv/dist/runtime/node/internal/process/node-version.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/node_modules/@cloudflare/unenv-preset/dist/runtime/node/process.mjs", "../../../../../AppData/Roaming/npm/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-process", "../modules/utils.ts", "../modules/db.ts", "../modules/dispatch/whatsapp.ts", "../modules/ml/matchquality.ts", "../modules/dispatch/meta.ts", "../modules/dispatch/ga4.ts", "../modules/dispatch/tiktok.ts", "../modules/dispatch/platforms.ts", "../modules/ml/logistic.ts", "../modules/ml/ltv.ts", "../modules/ml/segmentation.ts", "../modules/ml/bidding.ts", "../modules/ml/fraud.ts", "../modules/intelligence.ts", "../index.ts"],
|
|
4
|
-
"sourceRoot": "dist-check",
|
|
5
|
-
"sourcesContent": ["/* @__NO_SIDE_EFFECTS__ */\nexport function rawHeaders(headers) {\n\tconst rawHeaders = [];\n\tfor (const key in headers) {\n\t\tif (Array.isArray(headers[key])) {\n\t\t\tfor (const h of headers[key]) {\n\t\t\t\trawHeaders.push(key, h);\n\t\t\t}\n\t\t} else {\n\t\t\trawHeaders.push(key, headers[key]);\n\t\t}\n\t}\n\treturn rawHeaders;\n}\n/* @__NO_SIDE_EFFECTS__ */\nexport function mergeFns(...functions) {\n\treturn function(...args) {\n\t\tfor (const fn of functions) {\n\t\t\tfn(...args);\n\t\t}\n\t};\n}\n/* @__NO_SIDE_EFFECTS__ */\nexport function createNotImplementedError(name) {\n\treturn new Error(`[unenv] ${name} is not implemented yet!`);\n}\n/* @__NO_SIDE_EFFECTS__ */\nexport function notImplemented(name) {\n\tconst fn = () => {\n\t\tthrow createNotImplementedError(name);\n\t};\n\treturn Object.assign(fn, { __unenv__: true });\n}\n/* @__NO_SIDE_EFFECTS__ */\nexport function notImplementedAsync(name) {\n\tconst fn = notImplemented(name);\n\tfn.__promisify__ = () => notImplemented(name + \".__promisify__\");\n\tfn.native = fn;\n\treturn fn;\n}\n/* @__NO_SIDE_EFFECTS__ */\nexport function notImplementedClass(name) {\n\treturn class {\n\t\t__unenv__ = true;\n\t\tconstructor() {\n\t\t\tthrow new Error(`[unenv] ${name} is not implemented yet!`);\n\t\t}\n\t};\n}\n", "import { createNotImplementedError } from \"../../../_internal/utils.mjs\";\nconst _timeOrigin = globalThis.performance?.timeOrigin ?? Date.now();\nconst _performanceNow = globalThis.performance?.now ? globalThis.performance.now.bind(globalThis.performance) : () => Date.now() - _timeOrigin;\nconst nodeTiming = {\n\tname: \"node\",\n\tentryType: \"node\",\n\tstartTime: 0,\n\tduration: 0,\n\tnodeStart: 0,\n\tv8Start: 0,\n\tbootstrapComplete: 0,\n\tenvironment: 0,\n\tloopStart: 0,\n\tloopExit: 0,\n\tidleTime: 0,\n\tuvMetricsInfo: {\n\t\tloopCount: 0,\n\t\tevents: 0,\n\t\teventsWaiting: 0\n\t},\n\tdetail: undefined,\n\ttoJSON() {\n\t\treturn this;\n\t}\n};\n// PerformanceEntry\nexport class PerformanceEntry {\n\t__unenv__ = true;\n\tdetail;\n\tentryType = \"event\";\n\tname;\n\tstartTime;\n\tconstructor(name, options) {\n\t\tthis.name = name;\n\t\tthis.startTime = options?.startTime || _performanceNow();\n\t\tthis.detail = options?.detail;\n\t}\n\tget duration() {\n\t\treturn _performanceNow() - this.startTime;\n\t}\n\ttoJSON() {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tentryType: this.entryType,\n\t\t\tstartTime: this.startTime,\n\t\t\tduration: this.duration,\n\t\t\tdetail: this.detail\n\t\t};\n\t}\n}\n// PerformanceMark\nexport const PerformanceMark = class PerformanceMark extends PerformanceEntry {\n\tentryType = \"mark\";\n\tconstructor() {\n\t\t// @ts-ignore\n\t\tsuper(...arguments);\n\t}\n\tget duration() {\n\t\treturn 0;\n\t}\n};\n// PerformanceMark\nexport class PerformanceMeasure extends PerformanceEntry {\n\tentryType = \"measure\";\n}\n// PerformanceResourceTiming\nexport class PerformanceResourceTiming extends PerformanceEntry {\n\tentryType = \"resource\";\n\tserverTiming = [];\n\tconnectEnd = 0;\n\tconnectStart = 0;\n\tdecodedBodySize = 0;\n\tdomainLookupEnd = 0;\n\tdomainLookupStart = 0;\n\tencodedBodySize = 0;\n\tfetchStart = 0;\n\tinitiatorType = \"\";\n\tname = \"\";\n\tnextHopProtocol = \"\";\n\tredirectEnd = 0;\n\tredirectStart = 0;\n\trequestStart = 0;\n\tresponseEnd = 0;\n\tresponseStart = 0;\n\tsecureConnectionStart = 0;\n\tstartTime = 0;\n\ttransferSize = 0;\n\tworkerStart = 0;\n\tresponseStatus = 0;\n}\n// PerformanceObserverEntryList\nexport class PerformanceObserverEntryList {\n\t__unenv__ = true;\n\tgetEntries() {\n\t\treturn [];\n\t}\n\tgetEntriesByName(_name, _type) {\n\t\treturn [];\n\t}\n\tgetEntriesByType(type) {\n\t\treturn [];\n\t}\n}\n// Performance\nexport class Performance {\n\t__unenv__ = true;\n\ttimeOrigin = _timeOrigin;\n\teventCounts = new Map();\n\t_entries = [];\n\t_resourceTimingBufferSize = 0;\n\tnavigation = undefined;\n\ttiming = undefined;\n\ttimerify(_fn, _options) {\n\t\tthrow createNotImplementedError(\"Performance.timerify\");\n\t}\n\tget nodeTiming() {\n\t\treturn nodeTiming;\n\t}\n\teventLoopUtilization() {\n\t\treturn {};\n\t}\n\tmarkResourceTiming() {\n\t\t// TODO: create a new PerformanceResourceTiming entry\n\t\t// so that performance.getEntries, getEntriesByName, and getEntriesByType return it\n\t\t// see: https://nodejs.org/api/perf_hooks.html#performancemarkresourcetimingtiminginfo-requestedurl-initiatortype-global-cachemode-bodyinfo-responsestatus-deliverytype\n\t\treturn new PerformanceResourceTiming(\"\");\n\t}\n\tonresourcetimingbufferfull = null;\n\tnow() {\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Performance/now\n\t\tif (this.timeOrigin === _timeOrigin) {\n\t\t\treturn _performanceNow();\n\t\t}\n\t\treturn Date.now() - this.timeOrigin;\n\t}\n\tclearMarks(markName) {\n\t\tthis._entries = markName ? this._entries.filter((e) => e.name !== markName) : this._entries.filter((e) => e.entryType !== \"mark\");\n\t}\n\tclearMeasures(measureName) {\n\t\tthis._entries = measureName ? this._entries.filter((e) => e.name !== measureName) : this._entries.filter((e) => e.entryType !== \"measure\");\n\t}\n\tclearResourceTimings() {\n\t\tthis._entries = this._entries.filter((e) => e.entryType !== \"resource\" || e.entryType !== \"navigation\");\n\t}\n\tgetEntries() {\n\t\treturn this._entries;\n\t}\n\tgetEntriesByName(name, type) {\n\t\treturn this._entries.filter((e) => e.name === name && (!type || e.entryType === type));\n\t}\n\tgetEntriesByType(type) {\n\t\treturn this._entries.filter((e) => e.entryType === type);\n\t}\n\tmark(name, options) {\n\t\t// @ts-expect-error constructor is not protected\n\t\tconst entry = new PerformanceMark(name, options);\n\t\tthis._entries.push(entry);\n\t\treturn entry;\n\t}\n\tmeasure(measureName, startOrMeasureOptions, endMark) {\n\t\tlet start;\n\t\tlet end;\n\t\tif (typeof startOrMeasureOptions === \"string\") {\n\t\t\tstart = this.getEntriesByName(startOrMeasureOptions, \"mark\")[0]?.startTime;\n\t\t\tend = this.getEntriesByName(endMark, \"mark\")[0]?.startTime;\n\t\t} else {\n\t\t\tstart = Number.parseFloat(startOrMeasureOptions?.start) || this.now();\n\t\t\tend = Number.parseFloat(startOrMeasureOptions?.end) || this.now();\n\t\t}\n\t\tconst entry = new PerformanceMeasure(measureName, {\n\t\t\tstartTime: start,\n\t\t\tdetail: {\n\t\t\t\tstart,\n\t\t\t\tend\n\t\t\t}\n\t\t});\n\t\tthis._entries.push(entry);\n\t\treturn entry;\n\t}\n\tsetResourceTimingBufferSize(maxSize) {\n\t\tthis._resourceTimingBufferSize = maxSize;\n\t}\n\taddEventListener(type, listener, options) {\n\t\tthrow createNotImplementedError(\"Performance.addEventListener\");\n\t}\n\tremoveEventListener(type, listener, options) {\n\t\tthrow createNotImplementedError(\"Performance.removeEventListener\");\n\t}\n\tdispatchEvent(event) {\n\t\tthrow createNotImplementedError(\"Performance.dispatchEvent\");\n\t}\n\ttoJSON() {\n\t\treturn this;\n\t}\n}\n// PerformanceObserver\nexport class PerformanceObserver {\n\t__unenv__ = true;\n\tstatic supportedEntryTypes = [];\n\t_callback = null;\n\tconstructor(callback) {\n\t\tthis._callback = callback;\n\t}\n\ttakeRecords() {\n\t\treturn [];\n\t}\n\tdisconnect() {\n\t\tthrow createNotImplementedError(\"PerformanceObserver.disconnect\");\n\t}\n\tobserve(options) {\n\t\tthrow createNotImplementedError(\"PerformanceObserver.observe\");\n\t}\n\tbind(fn) {\n\t\treturn fn;\n\t}\n\trunInAsyncScope(fn, thisArg, ...args) {\n\t\treturn fn.call(thisArg, ...args);\n\t}\n\tasyncId() {\n\t\treturn 0;\n\t}\n\ttriggerAsyncId() {\n\t\treturn 0;\n\t}\n\temitDestroy() {\n\t\treturn this;\n\t}\n}\n// workerd implements a subset of globalThis.performance (as of last check, only timeOrigin set to 0 + now() implemented)\n// We already use performance.now() from globalThis.performance, if provided (see top of this file)\n// If we detect this condition, we can just use polyfill instead.\nexport const performance = globalThis.performance && \"addEventListener\" in globalThis.performance ? globalThis.performance : new Performance();\n", "import {\n performance,\n Performance,\n PerformanceEntry,\n PerformanceMark,\n PerformanceMeasure,\n PerformanceObserver,\n PerformanceObserverEntryList,\n PerformanceResourceTiming\n} from \"node:perf_hooks\";\nif (!(\"__unenv__\" in performance)) {\n const proto = Performance.prototype;\n for (const key of Object.getOwnPropertyNames(proto)) {\n if (key !== \"constructor\" && !(key in performance)) {\n const desc = Object.getOwnPropertyDescriptor(proto, key);\n if (desc) {\n Object.defineProperty(performance, key, desc);\n }\n }\n }\n}\nglobalThis.performance = performance;\nglobalThis.Performance = Performance;\nglobalThis.PerformanceEntry = PerformanceEntry;\nglobalThis.PerformanceMark = PerformanceMark;\nglobalThis.PerformanceMeasure = PerformanceMeasure;\nglobalThis.PerformanceObserver = PerformanceObserver;\nglobalThis.PerformanceObserverEntryList = PerformanceObserverEntryList;\nglobalThis.PerformanceResourceTiming = PerformanceResourceTiming;\n", "import { Writable } from \"node:stream\";\nimport noop from \"../mock/noop.mjs\";\nimport { notImplemented, notImplementedClass } from \"../_internal/utils.mjs\";\nconst _console = globalThis.console;\n// undocumented public APIs\nexport const _ignoreErrors = true;\nexport const _stderr = new Writable();\nexport const _stdout = new Writable();\nexport const log = _console?.log ?? noop;\nexport const info = _console?.info ?? log;\nexport const trace = _console?.trace ?? info;\nexport const debug = _console?.debug ?? log;\nexport const table = _console?.table ?? log;\nexport const error = _console?.error ?? log;\nexport const warn = _console?.warn ?? error;\n// https://developer.chrome.com/docs/devtools/console/api#createtask\nexport const createTask = _console?.createTask ?? /* @__PURE__ */ notImplemented(\"console.createTask\");\nexport const assert = /* @__PURE__ */ notImplemented(\"console.assert\");\n// noop\nexport const clear = _console?.clear ?? noop;\nexport const count = _console?.count ?? noop;\nexport const countReset = _console?.countReset ?? noop;\nexport const dir = _console?.dir ?? noop;\nexport const dirxml = _console?.dirxml ?? noop;\nexport const group = _console?.group ?? noop;\nexport const groupEnd = _console?.groupEnd ?? noop;\nexport const groupCollapsed = _console?.groupCollapsed ?? noop;\nexport const profile = _console?.profile ?? noop;\nexport const profileEnd = _console?.profileEnd ?? noop;\nexport const time = _console?.time ?? noop;\nexport const timeEnd = _console?.timeEnd ?? noop;\nexport const timeLog = _console?.timeLog ?? noop;\nexport const timeStamp = _console?.timeStamp ?? noop;\nexport const Console = _console?.Console ?? /* @__PURE__ */ notImplementedClass(\"console.Console\");\nexport const _times = /* @__PURE__ */ new Map();\nexport function context() {\n\t// TODO: Should be Console with all the methods\n\treturn _console;\n}\nexport const _stdoutErrorHandler = noop;\nexport const _stderrErrorHandler = noop;\nexport default {\n\t_times,\n\t_ignoreErrors,\n\t_stdoutErrorHandler,\n\t_stderrErrorHandler,\n\t_stdout,\n\t_stderr,\n\tassert,\n\tclear,\n\tConsole,\n\tcount,\n\tcountReset,\n\tdebug,\n\tdir,\n\tdirxml,\n\terror,\n\tcontext,\n\tcreateTask,\n\tgroup,\n\tgroupEnd,\n\tgroupCollapsed,\n\tinfo,\n\tlog,\n\tprofile,\n\tprofileEnd,\n\ttable,\n\ttime,\n\ttimeEnd,\n\ttimeLog,\n\ttimeStamp,\n\ttrace,\n\twarn\n};\n", "export default Object.assign(() => {}, { __unenv__: true });\n", "import {\n _ignoreErrors,\n _stderr,\n _stderrErrorHandler,\n _stdout,\n _stdoutErrorHandler,\n _times,\n Console\n} from \"unenv/node/console\";\nexport {\n Console,\n _ignoreErrors,\n _stderr,\n _stderrErrorHandler,\n _stdout,\n _stdoutErrorHandler,\n _times\n} from \"unenv/node/console\";\nconst workerdConsole = globalThis[\"console\"];\nexport const {\n assert,\n clear,\n // @ts-expect-error undocumented public API\n context,\n count,\n countReset,\n // @ts-expect-error undocumented public API\n createTask,\n debug,\n dir,\n dirxml,\n error,\n group,\n groupCollapsed,\n groupEnd,\n info,\n log,\n profile,\n profileEnd,\n table,\n time,\n timeEnd,\n timeLog,\n timeStamp,\n trace,\n warn\n} = workerdConsole;\nObject.assign(workerdConsole, {\n Console,\n _ignoreErrors,\n _stderr,\n _stderrErrorHandler,\n _stdout,\n _stdoutErrorHandler,\n _times\n});\nexport default workerdConsole;\n", "import { default as defaultExport } from \"@cloudflare/unenv-preset/node/console\";\nglobalThis.console = defaultExport;", "// https://nodejs.org/api/process.html#processhrtime\nexport const hrtime = /* @__PURE__ */ Object.assign(function hrtime(startTime) {\n\tconst now = Date.now();\n\t// millis to seconds\n\tconst seconds = Math.trunc(now / 1e3);\n\t// convert millis to nanos\n\tconst nanos = now % 1e3 * 1e6;\n\tif (startTime) {\n\t\tlet diffSeconds = seconds - startTime[0];\n\t\tlet diffNanos = nanos - startTime[0];\n\t\tif (diffNanos < 0) {\n\t\t\tdiffSeconds = diffSeconds - 1;\n\t\t\tdiffNanos = 1e9 + diffNanos;\n\t\t}\n\t\treturn [diffSeconds, diffNanos];\n\t}\n\treturn [seconds, nanos];\n}, { bigint: function bigint() {\n\t// Convert milliseconds to nanoseconds\n\treturn BigInt(Date.now() * 1e6);\n} });\n", "import { EventEmitter } from \"node:events\";\nimport { ReadStream, WriteStream } from \"node:tty\";\nimport { notImplemented, createNotImplementedError } from \"../../../_internal/utils.mjs\";\n// node-version.ts is generated at build time\nimport { NODE_VERSION } from \"./node-version.mjs\";\nexport class Process extends EventEmitter {\n\tenv;\n\thrtime;\n\tnextTick;\n\tconstructor(impl) {\n\t\tsuper();\n\t\tthis.env = impl.env;\n\t\tthis.hrtime = impl.hrtime;\n\t\tthis.nextTick = impl.nextTick;\n\t\tfor (const prop of [...Object.getOwnPropertyNames(Process.prototype), ...Object.getOwnPropertyNames(EventEmitter.prototype)]) {\n\t\t\tconst value = this[prop];\n\t\t\tif (typeof value === \"function\") {\n\t\t\t\tthis[prop] = value.bind(this);\n\t\t\t}\n\t\t}\n\t}\n\t// --- event emitter ---\n\temitWarning(warning, type, code) {\n\t\tconsole.warn(`${code ? `[${code}] ` : \"\"}${type ? `${type}: ` : \"\"}${warning}`);\n\t}\n\temit(...args) {\n\t\t// @ts-ignore\n\t\treturn super.emit(...args);\n\t}\n\tlisteners(eventName) {\n\t\treturn super.listeners(eventName);\n\t}\n\t// --- stdio (lazy initializers) ---\n\t#stdin;\n\t#stdout;\n\t#stderr;\n\tget stdin() {\n\t\treturn this.#stdin ??= new ReadStream(0);\n\t}\n\tget stdout() {\n\t\treturn this.#stdout ??= new WriteStream(1);\n\t}\n\tget stderr() {\n\t\treturn this.#stderr ??= new WriteStream(2);\n\t}\n\t// --- cwd ---\n\t#cwd = \"/\";\n\tchdir(cwd) {\n\t\tthis.#cwd = cwd;\n\t}\n\tcwd() {\n\t\treturn this.#cwd;\n\t}\n\t// --- dummy props and getters ---\n\tarch = \"\";\n\tplatform = \"\";\n\targv = [];\n\targv0 = \"\";\n\texecArgv = [];\n\texecPath = \"\";\n\ttitle = \"\";\n\tpid = 200;\n\tppid = 100;\n\tget version() {\n\t\treturn `v${NODE_VERSION}`;\n\t}\n\tget versions() {\n\t\treturn { node: NODE_VERSION };\n\t}\n\tget allowedNodeEnvironmentFlags() {\n\t\treturn new Set();\n\t}\n\tget sourceMapsEnabled() {\n\t\treturn false;\n\t}\n\tget debugPort() {\n\t\treturn 0;\n\t}\n\tget throwDeprecation() {\n\t\treturn false;\n\t}\n\tget traceDeprecation() {\n\t\treturn false;\n\t}\n\tget features() {\n\t\treturn {};\n\t}\n\tget release() {\n\t\treturn {};\n\t}\n\tget connected() {\n\t\treturn false;\n\t}\n\tget config() {\n\t\treturn {};\n\t}\n\tget moduleLoadList() {\n\t\treturn [];\n\t}\n\tconstrainedMemory() {\n\t\treturn 0;\n\t}\n\tavailableMemory() {\n\t\treturn 0;\n\t}\n\tuptime() {\n\t\treturn 0;\n\t}\n\tresourceUsage() {\n\t\treturn {};\n\t}\n\t// --- noop methods ---\n\tref() {\n\t\t// noop\n\t}\n\tunref() {\n\t\t// noop\n\t}\n\t// --- unimplemented methods ---\n\tumask() {\n\t\tthrow createNotImplementedError(\"process.umask\");\n\t}\n\tgetBuiltinModule() {\n\t\treturn undefined;\n\t}\n\tgetActiveResourcesInfo() {\n\t\tthrow createNotImplementedError(\"process.getActiveResourcesInfo\");\n\t}\n\texit() {\n\t\tthrow createNotImplementedError(\"process.exit\");\n\t}\n\treallyExit() {\n\t\tthrow createNotImplementedError(\"process.reallyExit\");\n\t}\n\tkill() {\n\t\tthrow createNotImplementedError(\"process.kill\");\n\t}\n\tabort() {\n\t\tthrow createNotImplementedError(\"process.abort\");\n\t}\n\tdlopen() {\n\t\tthrow createNotImplementedError(\"process.dlopen\");\n\t}\n\tsetSourceMapsEnabled() {\n\t\tthrow createNotImplementedError(\"process.setSourceMapsEnabled\");\n\t}\n\tloadEnvFile() {\n\t\tthrow createNotImplementedError(\"process.loadEnvFile\");\n\t}\n\tdisconnect() {\n\t\tthrow createNotImplementedError(\"process.disconnect\");\n\t}\n\tcpuUsage() {\n\t\tthrow createNotImplementedError(\"process.cpuUsage\");\n\t}\n\tsetUncaughtExceptionCaptureCallback() {\n\t\tthrow createNotImplementedError(\"process.setUncaughtExceptionCaptureCallback\");\n\t}\n\thasUncaughtExceptionCaptureCallback() {\n\t\tthrow createNotImplementedError(\"process.hasUncaughtExceptionCaptureCallback\");\n\t}\n\tinitgroups() {\n\t\tthrow createNotImplementedError(\"process.initgroups\");\n\t}\n\topenStdin() {\n\t\tthrow createNotImplementedError(\"process.openStdin\");\n\t}\n\tassert() {\n\t\tthrow createNotImplementedError(\"process.assert\");\n\t}\n\tbinding() {\n\t\tthrow createNotImplementedError(\"process.binding\");\n\t}\n\t// --- attached interfaces ---\n\tpermission = { has: /* @__PURE__ */ notImplemented(\"process.permission.has\") };\n\treport = {\n\t\tdirectory: \"\",\n\t\tfilename: \"\",\n\t\tsignal: \"SIGUSR2\",\n\t\tcompact: false,\n\t\treportOnFatalError: false,\n\t\treportOnSignal: false,\n\t\treportOnUncaughtException: false,\n\t\tgetReport: /* @__PURE__ */ notImplemented(\"process.report.getReport\"),\n\t\twriteReport: /* @__PURE__ */ notImplemented(\"process.report.writeReport\")\n\t};\n\tfinalization = {\n\t\tregister: /* @__PURE__ */ notImplemented(\"process.finalization.register\"),\n\t\tunregister: /* @__PURE__ */ notImplemented(\"process.finalization.unregister\"),\n\t\tregisterBeforeExit: /* @__PURE__ */ notImplemented(\"process.finalization.registerBeforeExit\")\n\t};\n\tmemoryUsage = Object.assign(() => ({\n\t\tarrayBuffers: 0,\n\t\trss: 0,\n\t\texternal: 0,\n\t\theapTotal: 0,\n\t\theapUsed: 0\n\t}), { rss: () => 0 });\n\t// --- undefined props ---\n\tmainModule = undefined;\n\tdomain = undefined;\n\t// optional\n\tsend = undefined;\n\texitCode = undefined;\n\tchannel = undefined;\n\tgetegid = undefined;\n\tgeteuid = undefined;\n\tgetgid = undefined;\n\tgetgroups = undefined;\n\tgetuid = undefined;\n\tsetegid = undefined;\n\tseteuid = undefined;\n\tsetgid = undefined;\n\tsetgroups = undefined;\n\tsetuid = undefined;\n\t// internals\n\t_events = undefined;\n\t_eventsCount = undefined;\n\t_exiting = undefined;\n\t_maxListeners = undefined;\n\t_debugEnd = undefined;\n\t_debugProcess = undefined;\n\t_fatalException = undefined;\n\t_getActiveHandles = undefined;\n\t_getActiveRequests = undefined;\n\t_kill = undefined;\n\t_preload_modules = undefined;\n\t_rawDebug = undefined;\n\t_startProfilerIdleNotifier = undefined;\n\t_stopProfilerIdleNotifier = undefined;\n\t_tickCallback = undefined;\n\t_disconnect = undefined;\n\t_handleQueue = undefined;\n\t_pendingMessage = undefined;\n\t_channel = undefined;\n\t_send = undefined;\n\t_linkedBinding = undefined;\n}\n", "export class ReadStream {\n\tfd;\n\tisRaw = false;\n\tisTTY = false;\n\tconstructor(fd) {\n\t\tthis.fd = fd;\n\t}\n\tsetRawMode(mode) {\n\t\tthis.isRaw = mode;\n\t\treturn this;\n\t}\n}\n", "export class WriteStream {\n\tfd;\n\tcolumns = 80;\n\trows = 24;\n\tisTTY = false;\n\tconstructor(fd) {\n\t\tthis.fd = fd;\n\t}\n\tclearLine(dir, callback) {\n\t\tcallback && callback();\n\t\treturn false;\n\t}\n\tclearScreenDown(callback) {\n\t\tcallback && callback();\n\t\treturn false;\n\t}\n\tcursorTo(x, y, callback) {\n\t\tcallback && typeof callback === \"function\" && callback();\n\t\treturn false;\n\t}\n\tmoveCursor(dx, dy, callback) {\n\t\tcallback && callback();\n\t\treturn false;\n\t}\n\tgetColorDepth(env) {\n\t\treturn 1;\n\t}\n\thasColors(count, env) {\n\t\treturn false;\n\t}\n\tgetWindowSize() {\n\t\treturn [this.columns, this.rows];\n\t}\n\twrite(str, encoding, cb) {\n\t\tif (str instanceof Uint8Array) {\n\t\t\tstr = new TextDecoder().decode(str);\n\t\t}\n\t\ttry {\n\t\t\tconsole.log(str);\n\t\t} catch {}\n\t\tcb && typeof cb === \"function\" && cb();\n\t\treturn false;\n\t}\n}\n", "// Extracted from .nvmrc\nexport const NODE_VERSION = \"22.14.0\";\n", "import { hrtime as UnenvHrTime } from \"unenv/node/internal/process/hrtime\";\nimport { Process as UnenvProcess } from \"unenv/node/internal/process/process\";\nconst globalProcess = globalThis[\"process\"];\nexport const getBuiltinModule = globalProcess.getBuiltinModule;\nconst workerdProcess = getBuiltinModule(\"node:process\");\nconst unenvProcess = new UnenvProcess({\n env: globalProcess.env,\n hrtime: UnenvHrTime,\n // `nextTick` is available from workerd process v1\n nextTick: workerdProcess.nextTick\n});\nexport const { exit, features, platform } = workerdProcess;\nexport const {\n _channel,\n _debugEnd,\n _debugProcess,\n _disconnect,\n _events,\n _eventsCount,\n _exiting,\n _fatalException,\n _getActiveHandles,\n _getActiveRequests,\n _handleQueue,\n _kill,\n _linkedBinding,\n _maxListeners,\n _pendingMessage,\n _preload_modules,\n _rawDebug,\n _send,\n _startProfilerIdleNotifier,\n _stopProfilerIdleNotifier,\n _tickCallback,\n abort,\n addListener,\n allowedNodeEnvironmentFlags,\n arch,\n argv,\n argv0,\n assert,\n availableMemory,\n binding,\n channel,\n chdir,\n config,\n connected,\n constrainedMemory,\n cpuUsage,\n cwd,\n debugPort,\n disconnect,\n dlopen,\n domain,\n emit,\n emitWarning,\n env,\n eventNames,\n execArgv,\n execPath,\n exitCode,\n finalization,\n getActiveResourcesInfo,\n getegid,\n geteuid,\n getgid,\n getgroups,\n getMaxListeners,\n getuid,\n hasUncaughtExceptionCaptureCallback,\n hrtime,\n initgroups,\n kill,\n listenerCount,\n listeners,\n loadEnvFile,\n mainModule,\n memoryUsage,\n moduleLoadList,\n nextTick,\n off,\n on,\n once,\n openStdin,\n permission,\n pid,\n ppid,\n prependListener,\n prependOnceListener,\n rawListeners,\n reallyExit,\n ref,\n release,\n removeAllListeners,\n removeListener,\n report,\n resourceUsage,\n send,\n setegid,\n seteuid,\n setgid,\n setgroups,\n setMaxListeners,\n setSourceMapsEnabled,\n setuid,\n setUncaughtExceptionCaptureCallback,\n sourceMapsEnabled,\n stderr,\n stdin,\n stdout,\n throwDeprecation,\n title,\n traceDeprecation,\n umask,\n unref,\n uptime,\n version,\n versions\n} = unenvProcess;\nconst _process = {\n abort,\n addListener,\n allowedNodeEnvironmentFlags,\n hasUncaughtExceptionCaptureCallback,\n setUncaughtExceptionCaptureCallback,\n loadEnvFile,\n sourceMapsEnabled,\n arch,\n argv,\n argv0,\n chdir,\n config,\n connected,\n constrainedMemory,\n availableMemory,\n cpuUsage,\n cwd,\n debugPort,\n dlopen,\n disconnect,\n emit,\n emitWarning,\n env,\n eventNames,\n execArgv,\n execPath,\n exit,\n finalization,\n features,\n getBuiltinModule,\n getActiveResourcesInfo,\n getMaxListeners,\n hrtime,\n kill,\n listeners,\n listenerCount,\n memoryUsage,\n nextTick,\n on,\n off,\n once,\n pid,\n platform,\n ppid,\n prependListener,\n prependOnceListener,\n rawListeners,\n release,\n removeAllListeners,\n removeListener,\n report,\n resourceUsage,\n setMaxListeners,\n setSourceMapsEnabled,\n stderr,\n stdin,\n stdout,\n title,\n throwDeprecation,\n traceDeprecation,\n umask,\n uptime,\n version,\n versions,\n // @ts-expect-error old API\n domain,\n initgroups,\n moduleLoadList,\n reallyExit,\n openStdin,\n assert,\n binding,\n send,\n exitCode,\n channel,\n getegid,\n geteuid,\n getgid,\n getgroups,\n getuid,\n setegid,\n seteuid,\n setgid,\n setgroups,\n setuid,\n permission,\n mainModule,\n _events,\n _eventsCount,\n _exiting,\n _maxListeners,\n _debugEnd,\n _debugProcess,\n _fatalException,\n _getActiveHandles,\n _getActiveRequests,\n _kill,\n _preload_modules,\n _rawDebug,\n _startProfilerIdleNotifier,\n _stopProfilerIdleNotifier,\n _tickCallback,\n _disconnect,\n _handleQueue,\n _pendingMessage,\n _channel,\n _send,\n _linkedBinding\n};\nexport default _process;\n", "import { default as defaultExport } from \"@cloudflare/unenv-preset/node/process\";\nglobalThis.process = defaultExport;", "/**\n * CDP Edge \u2014 Utilities\n * Fun\u00E7\u00F5es puras sem depend\u00EAncias externas.\n * Importadas por todos os outros m\u00F3dulos.\n */\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface FunnelStageResult {\n depth: string;\n funnelDepth: string;\n}\n\nexport interface MetaSignalWeights {\n intent: number;\n ltv: number;\n dist: number;\n}\n\nexport type DistanceBucket = 'very_close' | 'close' | 'nearby' | 'moderate' | 'far';\n\nexport type FunnelLevel = 'top' | 'mid' | 'bottom' | 'conversion' | 'unknown';\n\nexport type MetaSignalBucket = 'hot' | 'warm' | 'cold';\n\n// \u2500\u2500 CORS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function isAllowedOrigin(origin: string | null, siteDomain: string | null): boolean {\n if (!origin || !siteDomain) return false;\n return origin === `https://${siteDomain}`\n || origin.endsWith(`.${siteDomain}`)\n || origin === 'http://localhost:3000'\n || origin === 'http://localhost:5173';\n}\n\nexport function corsHeaders(origin: string | null, siteDomain: string | null): Record<string, string> {\n const allowed = isAllowedOrigin(origin, siteDomain) ? origin : (siteDomain ? `https://${siteDomain}` : '*');\n return {\n 'Access-Control-Allow-Origin': allowed || '*',\n 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With',\n 'Access-Control-Max-Age': '86400',\n };\n}\n\n// \u2500\u2500 SHA-256 via WebCrypto (obrigat\u00F3rio no Cloudflare Workers) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sha256(value: string | null | undefined): Promise<string | undefined> {\n if (!value) return undefined;\n const clean = String(value).toLowerCase().trim();\n if (!clean) return undefined;\n const buf = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(clean)\n );\n return Array.from(new Uint8Array(buf))\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n// \u2500\u2500 Normaliza\u00E7\u00E3o de telefone \u2192 somente d\u00EDgitos + DDI 55 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function normalizePhone(phone: string | null | undefined): string | undefined {\n if (!phone) return undefined;\n let digits = String(phone).replace(/\\D/g, '');\n if (digits.length === 11 && !digits.startsWith('55')) digits = '55' + digits;\n if (digits.length === 10 && !digits.startsWith('55')) digits = '55' + digits;\n return digits.length >= 10 ? digits : undefined;\n}\n\n// \u2500\u2500 Normaliza\u00E7\u00E3o de cidade \u2192 lowercase sem acentos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function normalizeCity(city: string | null | undefined): string | undefined {\n if (!city) return undefined;\n return String(city)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]/g, '');\n}\n\n// \u2500\u2500 Parse seguro de JSON armazenado como TEXT no D1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function tryParseJson<T = any>(str: string | null, fallback?: T): T | null {\n if (!str) return fallback !== undefined ? fallback : null;\n try { return JSON.parse(str); } catch { return fallback !== undefined ? fallback : null; }\n}\n\n// \u2500\u2500 Mapa Meta \u2192 GA4 event names \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const META_TO_GA4: Record<string, string> = {\n PageView: 'page_view',\n ViewContent: 'view_item',\n Lead: 'generate_lead',\n Contact: 'generate_lead',\n Schedule: 'generate_lead',\n InitiateCheckout: 'begin_checkout',\n AddToCart: 'add_to_cart',\n AddPaymentInfo: 'add_payment_info',\n Purchase: 'purchase',\n CompleteRegistration: 'sign_up',\n Subscribe: 'subscribe',\n StartTrial: 'start_trial',\n Search: 'search',\n AddToWishlist: 'add_to_wishlist',\n};\n\n// \u2500\u2500 Lista can\u00F4nica de eventos v\u00E1lidos (19 eventos) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const VALID_EVENT_NAMES = new Set([\n 'PageView','ViewContent','Lead','Purchase','InitiateCheckout',\n 'AddToCart','CompleteRegistration','Contact','Schedule',\n 'StartTrial','Subscribe','SubmitApplication','Search',\n 'video_start','video_25','video_50','video_75','video_complete',\n // Im\u00F3veis \u2014 inten\u00E7\u00E3o de visita f\u00EDsica, financiamento e favoritar\n 'FindLocation','CustomizeProduct','AddToWishlist',\n]);\n\n// \u2500\u2500 Taxonomia de funil (funnel_stage \u2192 profundidade sem\u00E2ntica) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Fonte de verdade para interpretar funnel_stage em qualquer ponto do sistema.\nexport const FUNNEL_TAXONOMY = {\n top: ['scroll_50', 'time_30s', 'page_view', 'gallery_view', 'AddToWishlist'],\n mid: ['map_view', 'gallery_click', 'price_hover', 'time_3min', 'FindLocation'],\n bottom: ['route_click', 'whatsapp_click', 'cta_hover', 'CustomizeProduct'],\n conversion: ['schedule_confirmed', 'lead_form', 'purchase', 'visit_booked'],\n};\n\n// \u00CDndice invertido: funnel_stage \u2192 depth (constru\u00EDdo uma vez, zero custo em runtime)\nconst _STAGE_TO_DEPTH: Record<string, FunnelLevel> = Object.entries(FUNNEL_TAXONOMY).reduce((acc, [depth, stages]) => {\n stages.forEach(s => { acc[s] = depth as FunnelLevel; });\n return acc;\n}, {} as Record<string, FunnelLevel>);\n\n/**\n * Resolve funnel_stage em funnelDepth sem\u00E2ntico.\n * bottom_intent = inten\u00E7\u00E3o forte (route_click, whatsapp_click)\n * bottom_conversion = a\u00E7\u00E3o confirmada (schedule_confirmed, lead_form)\n */\nexport function resolveFunnelStage(funnel_stage: string | null | undefined): FunnelStageResult {\n const depth = _STAGE_TO_DEPTH[funnel_stage || ''] || 'unknown';\n const funnelDepth = depth === 'conversion' ? 'bottom_conversion'\n : depth === 'bottom' ? 'bottom_intent'\n : depth;\n return { depth, funnelDepth };\n}\n\n// \u2500\u2500 Normaliza\u00E7\u00E3o de intent_score \u2192 0.0\u20131.0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Aceita: string ('high'/'medium'/'low'), num\u00E9rico 0-1 ou num\u00E9rico 0-100\nconst _INTENT_STRING_MAP: Record<string, number> = { high: 0.92, medium: 0.65, low: 0.30 };\n\nexport function resolveIntentScore(value: string | number | null | undefined): number | null {\n if (value === null || value === undefined) return null;\n if (typeof value === 'string') return _INTENT_STRING_MAP[value.toLowerCase()] ?? null;\n const num = parseFloat(String(value));\n if (isNaN(num)) return null;\n const normalized = num > 1 ? num / 100 : num; // escala 0-100 \u2192 0-1\n return Math.min(1, Math.max(0, Math.round(normalized * 100) / 100));\n}\n\n/**\n * Dist\u00E2ncia (distanceBucket) \u2192 peso num\u00E9rico para meta_signal.\n * very_close=1.0 ... far=0.1 ... sem dado=0.3 (neutro)\n */\nexport function distanceBucketWeight(bucket: string | null | undefined): number {\n const map: Record<DistanceBucket, number> = { very_close: 1.0, close: 0.75, nearby: 0.5, moderate: 0.25, far: 0.1 };\n return map[bucket as DistanceBucket] ?? 0.3;\n}\n\n/**\n * Pesos din\u00E2micos do meta_signal por profundidade de funil.\n * Fundo: comportamento pesa mais (intent + dist).\n * Topo: perfil pesa mais (ltv).\n * Default (mid/unknown): balanceado.\n */\nexport function computeMetaSignalWeights(funnelLevel: FunnelLevel | string | null | undefined): MetaSignalWeights {\n if (funnelLevel === 'bottom' || funnelLevel === 'conversion') {\n return { intent: 0.5, ltv: 0.2, dist: 0.3 };\n }\n if (funnelLevel === 'top') {\n return { intent: 0.2, ltv: 0.6, dist: 0.2 };\n }\n return { intent: 0.4, ltv: 0.4, dist: 0.2 };\n}\n\n/**\n * Quantiza meta_signal cont\u00EDnuo em bucket leg\u00EDvel.\n * Usado em cria\u00E7\u00E3o de p\u00FAblicos e leitura de BI.\n */\nexport function metaSignalBucket(score: number | null | undefined): MetaSignalBucket {\n if (!score) return 'cold';\n if (score >= 0.8) return 'hot';\n if (score >= 0.6) return 'warm';\n return 'cold';\n}\n\n// \u2500\u2500 Input Validation & Sanitization \u2014 Seguran\u00E7a contra XSS/Injection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Valida formato de email (basic RFC-compliant)\n */\nexport function isValidEmail(email: string | null | undefined): boolean {\n if (!email || typeof email !== 'string') return false;\n const trimmed = email.trim();\n if (trimmed.length > 256) return false; // Limite razo\u00E1vel\n const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n return emailRegex.test(trimmed);\n}\n\n/**\n * Sanitiza string contra XSS/HTML injection\n * Remove tags HTML, scripts, e caracteres perigosos\n */\nexport function sanitizeString(input: string | null | undefined, maxLength: number = 512): string | null {\n if (!input || typeof input !== 'string') return null;\n let sanitized = String(input).trim();\n\n // Remove HTML tags\n sanitized = sanitized.replace(/<[^>]*>/g, '');\n\n // Remove JavaScript event handlers\n sanitized = sanitized.replace(/on\\w+\\s*=/gi, '');\n\n // Remove javascript: protocol\n sanitized = sanitized.replace(/javascript:/gi, '');\n\n // Remove caracteres perigosos\n sanitized = sanitized.replace(/[<>\\\"'`]/g, '');\n\n // Remove caracteres Unicode perigosos\n sanitized = sanitized.replace(/[\\x00-\\x1F\\x7F]/g, '');\n\n // Limita comprimento\n if (sanitized.length > maxLength) {\n sanitized = sanitized.substring(0, maxLength);\n }\n\n return sanitized.length > 0 ? sanitized : null;\n}\n\n/**\n * Valida e sanitiza URL (para pageUrl)\n */\nexport function isValidUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== 'string') return false;\n const trimmed = url.trim();\n if (trimmed.length > 2048) return false; // Limite razo\u00E1vel\n try {\n const parsed = new URL(trimmed);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n}\n\n/**\n * Valida formato de CPF (11 d\u00EDgitos)\n */\nexport function isValidCPF(cpf: string | null | undefined): boolean {\n if (!cpf || typeof cpf !== 'string') return false;\n const cleaned = cpf.replace(/\\D/g, '');\n return cleaned.length === 11 && /^\\d+$/.test(cleaned);\n}\n\n/**\n * Valida formato de CNPJ (14 d\u00EDgitos)\n */\nexport function isValidCNPJ(cnpj: string | null | undefined): boolean {\n if (!cnpj || typeof cnpj !== 'string') return false;\n const cleaned = cnpj.replace(/\\D/g, '');\n return cleaned.length === 14 && /^\\d+$/.test(cleaned);\n}\n\n/**\n * Valida formato de valor num\u00E9rico (para value em Purchase)\n */\nexport function isValidValue(value: number | null | undefined): boolean {\n if (value === null || value === undefined) return true; // Valor opcional\n const num = Number(value);\n return !isNaN(num) && num >= 0 && num <= 9_999_999;\n}\n\n/**\n * Valida moeda (currency field)\n */\nexport function isValidCurrency(currency: string | null | undefined): boolean {\n if (!currency || typeof currency !== 'string') return true; // Opcional\n const trimmed = currency.trim().toUpperCase();\n const validCurrencies = ['BRL', 'USD', 'EUR', 'GBP', 'CAD', 'AUD', 'JPY', 'CHF'];\n return trimmed.length === 3 && validCurrencies.includes(trimmed);\n}\n\n/**\n * Sanitiza array de strings (para contentIds, etc.)\n */\nexport function sanitizeStringArray(input: string[] | null | undefined, maxLength: number = 512): string[] | null {\n if (!input || !Array.isArray(input)) return null;\n const sanitized = input\n .map(item => sanitizeString(item, maxLength))\n .filter(item => item !== null) as string[];\n return sanitized.length > 0 ? sanitized : null;\n}\n\n/**\n * Valida UTM parameters (utmSource, utmMedium, utmCampaign, utmContent, utmTerm)\n */\nexport function isValidUTM(param: string | null | undefined, paramType: string): boolean {\n if (!param || typeof param !== 'string') return true; // Opcional\n const trimmed = param.trim();\n const maxLength = paramType === 'utm_source' ? 100 : 200;\n\n if (trimmed.length > maxLength) return false;\n\n // Verifica caracteres perigosos\n const dangerousPatterns = ['<script', 'javascript:', 'onload=', 'onerror=', 'onclick='];\n const lowerCase = trimmed.toLowerCase();\n return !dangerousPatterns.some(pattern => lowerCase.includes(pattern));\n}\n", "/**\n * CDP Edge \u2014 Camada D1 (Database)\n * Todas as opera\u00E7\u00F5es de escrita/leitura no banco D1.\n * Bindings: env.DB, env.GEO_CACHE, env.AUDIT_LOGS\n */\n\nimport { sha256, normalizePhone, normalizeCity } from './utils.js';\nimport { Env, TrackPayload } from '../types.js';\nimport { D1Database } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface GeoData {\n country: string | null;\n continent: string | null;\n asn: string | null;\n asOrg: string | null;\n colo: string | null;\n city: string | null;\n region: string | null;\n regionCode: string | null;\n postalCode: string | null;\n latitude: number | null;\n longitude: number | null;\n timezone: string | null;\n metroCode: string | null;\n}\n\nexport interface LtvResult {\n value: number;\n class: string;\n score?: number;\n}\n\nexport interface HealthMetrics {\n platform: string;\n hours: number;\n events_sent: number;\n events_failed: number;\n success_rate: number;\n errors_detected: Array<{ code: string; count: number }>;\n issues: string[];\n}\n\nexport interface DailyReport {\n platform: string;\n status: string;\n}\n\n// \u2500\u2500 saveLead \u2014 inserir evento de convers\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function saveLead(env: Env, eventName: string, payload: TrackPayload, request: Request, platform: string = 'website'): Promise<void> {\n if (!env.DB) return;\n try {\n const {\n email, phone, firstName, lastName,\n city, state, country,\n fbp, fbc, userId,\n utmSource, utmMedium, utmCampaign, utmContent, utmTerm,\n pageUrl, value, currency, eventId, botScore,\n engagementScore, intentionLevel, utmRestored,\n } = payload;\n\n await env.DB.prepare(`\n INSERT INTO leads (\n event_name, event_id, email, phone, first_name, last_name,\n city, state, country, fbp, fbc, user_id,\n utm_source, utm_medium, utm_campaign, utm_content, utm_term,\n page_url, value, currency, ip_address, platform, bot_score,\n engagement_score, intention_level, utm_restored, created_at\n ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))\n `).bind(\n eventName,\n eventId || null,\n email || null,\n normalizePhone(phone) || null,\n firstName || null,\n lastName || null,\n city || null,\n state || null,\n (country || (request as any).cf?.country || null),\n fbp || null,\n fbc || null,\n userId || null,\n utmSource || null,\n utmMedium || null,\n utmCampaign || null,\n utmContent || null,\n utmTerm || null,\n pageUrl || null,\n value !== undefined ? parseFloat(String(value)) : null,\n currency || 'BRL',\n request.headers.get('CF-Connecting-IP') || null,\n platform,\n botScore || 0,\n engagementScore !== undefined ? parseFloat(String(engagementScore)) : null,\n intentionLevel || null,\n utmRestored ? 1 : 0,\n ).run();\n } catch (err: any) {\n console.error('D1 saveLead error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 calculateCohortLabel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function calculateCohortLabel(score: number, eventName: string): string {\n if (eventName === 'Purchase') return 'buyer_lookalike';\n if (score >= 80) return 'high_intent';\n if (score >= 30) return 'nurture';\n return 'lost';\n}\n\n// \u2500\u2500 upsertProfile \u2014 acumula cookies/scores entre visitas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function upsertProfile(env: Env, eventName: string, payload: TrackPayload, request: Request): Promise<void> {\n if (!env.DB || !payload.userId) return;\n try {\n const {\n userId, email, phone,\n fbp, fbc, ttp, gclid, ttclid, gaClientId,\n city, state, country,\n engagementScore, userScore,\n } = payload;\n\n const scoreMap: Record<string, number> = { PageView: 5, ViewContent: 10, ScrollDepth: 3, TimeOnPage: 5, Lead: 30, InitiateCheckout: 50, Purchase: 100 };\n const eventScore = scoreMap[eventName] || 2;\n\n const behaviorBonus = userScore\n ? Math.round((Math.min(userScore, 100) / 100) * 20)\n : (engagementScore ? Math.round((Math.min(engagementScore, 5) / 5) * 10) : 0);\n\n const totalDelta = eventScore + behaviorBonus;\n\n await env.DB.prepare(`\n INSERT INTO user_profiles\n (user_id, email, phone, fbp, fbc, ttp, gclid, ttclid, ga_client_id,\n city, state, country, score, cohort_label, created_at, updated_at)\n VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'),datetime('now'))\n ON CONFLICT(user_id) DO UPDATE SET\n email = COALESCE(excluded.email, user_profiles.email),\n phone = COALESCE(excluded.phone, user_profiles.phone),\n fbp = COALESCE(excluded.fbp, user_profiles.fbp),\n fbc = COALESCE(excluded.fbc, user_profiles.fbc),\n ttp = COALESCE(excluded.ttp, user_profiles.ttp),\n gclid = COALESCE(excluded.gclid, user_profiles.gclid),\n ttclid = COALESCE(excluded.ttclid, user_profiles.ttclid),\n ga_client_id = COALESCE(excluded.ga_client_id, user_profiles.ga_client_id),\n city = COALESCE(excluded.city, user_profiles.city),\n state = COALESCE(excluded.state, user_profiles.state),\n country = COALESCE(excluded.country, user_profiles.country),\n score = user_profiles.score + excluded.score,\n cohort_label = excluded.cohort_label,\n updated_at = datetime('now')\n `).bind(\n userId,\n email || null,\n normalizePhone(phone) || null,\n fbp || null,\n fbc || null,\n ttp || null,\n gclid || null,\n ttclid || null,\n gaClientId || null,\n city || null,\n state || null,\n (country || (request as any).cf?.country || null),\n totalDelta,\n calculateCohortLabel(totalDelta, eventName),\n ).run();\n } catch (err: any) {\n console.error('D1 upsertProfile error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 resolveDeviceGraph \u2014 Cross-Device Identity \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function resolveDeviceGraph(DB: D1Database, currentUserId: string, email?: string | null, phone?: string | null): Promise<void> {\n if (!DB || !currentUserId) return;\n if (!email && !phone) return;\n\n try {\n const conditions: string[] = [];\n const bindings: (string | number)[] = [];\n\n if (email) {\n conditions.push('email = ?');\n bindings.push(email.toLowerCase().trim());\n }\n if (phone) {\n const digits = String(phone).replace(/\\D/g, '');\n if (digits.length >= 10) {\n conditions.push('phone LIKE ?');\n bindings.push(`%${digits.slice(-10)}`);\n }\n }\n\n if (conditions.length === 0) return;\n\n bindings.push(currentUserId);\n const rows = await DB.prepare(`\n SELECT user_id, email, phone, created_at\n FROM user_profiles\n WHERE (${conditions.join(' OR ')})\n AND user_id != ?\n ORDER BY created_at ASC\n LIMIT 5\n `).bind(...bindings).all();\n\n if (!rows.results || rows.results.length === 0) return;\n\n for (const match of rows.results) {\n const emailMatch = email && match.email &&\n email.toLowerCase().trim() === (match.email as string).toLowerCase().trim();\n const phoneMatch = phone && match.phone && (() => {\n const a = String(phone).replace(/\\D/g, '');\n const b = String(match.phone).replace(/\\D/g, '');\n return a.slice(-10) === b.slice(-10) && a.length >= 10;\n })();\n\n if (!emailMatch && !phoneMatch) continue;\n\n const matchType = emailMatch && phoneMatch ? 'email+phone' : (emailMatch ? 'email' : 'phone');\n const matchConfidence = emailMatch && phoneMatch ? 0.99 : (emailMatch ? 0.95 : 0.85);\n const primary = match.user_id as string;\n const secondary = currentUserId;\n\n await DB.prepare(`\n INSERT OR IGNORE INTO device_graph\n (primary_user_id, secondary_user_id, match_type, match_confidence)\n VALUES (?, ?, ?, ?)\n `).bind(primary, secondary, matchType, matchConfidence).run();\n\n // sem log de user IDs \u2014 dados sens\u00EDveis n\u00E3o entram em Workers log\n }\n } catch (err: any) {\n console.error('resolveDeviceGraph error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 fireAutomation \u2014 dispara regras de automa\u00E7\u00E3o (WA/Email) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function fireAutomation(env: Env, eventName: string, leadId: number | null, payload: TrackPayload): Promise<void> {\n if (!env.DB) return;\n\n try {\n const { results: rules } = await env.DB\n .prepare(\n `SELECT id, channel, subject_template, message_template\n FROM automation_rules\n WHERE trigger_event = ?1 AND is_active = 1`\n )\n .bind(eventName)\n .all();\n\n if (!rules || rules.length === 0) return;\n\n const vars: Record<string, string> = {\n name: String(payload.firstName || (payload as any).name || ''),\n email: String(payload.email || ''),\n phone: String(payload.phone || ''),\n campaign: String(payload.utmCampaign || payload.utm_campaign || ''),\n intention: String(payload.intentionLevel || payload.intention_level || ''),\n };\n\n const interpolate = (tpl: string) =>\n tpl.replace(/\\{\\{(\\w+)\\}\\}/g, (_, k) => vars[k] ?? '');\n\n for (const rule of rules) {\n const message = interpolate(rule.message_template as string);\n const subject = rule.subject_template ? interpolate(rule.subject_template as string) : null;\n\n try {\n if (rule.channel === 'whatsapp' && payload.phone && env.WHATSAPP_ACCESS_TOKEN && env.WHATSAPP_PHONE_NUMBER_ID) {\n const digits = String(payload.phone).replace(/\\D/g, '');\n const e164 = digits.startsWith('55') ? `+${digits}` : `+55${digits}`;\n const waRes = await fetch(\n `https://graph.facebook.com/v22.0/${env.WHATSAPP_PHONE_NUMBER_ID}/messages`,\n {\n method: 'POST',\n headers: { 'Authorization': `Bearer ${env.WHATSAPP_ACCESS_TOKEN}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ messaging_product: 'whatsapp', recipient_type: 'individual', to: e164, type: 'text', text: { body: message } }),\n }\n );\n const waData = await waRes.json();\n const status = waRes.ok ? 'sent' : 'failed';\n const meta = waRes.ok ? ((waData as any).messages?.[0]?.id ?? null) : JSON.stringify(waData);\n await env.DB.prepare(\n `INSERT INTO messaging_history (lead_id, channel, recipient, subject, content, status, meta) VALUES (?1,?2,?3,?4,?5,?6,?7)`\n ).bind(leadId, 'whatsapp', e164, null, message, status, meta).run();\n\n } else if (rule.channel === 'email' && payload.email && env.RESEND_API_KEY) {\n const resendRes = await fetch('https://api.resend.com/emails', {\n method: 'POST',\n headers: { 'Authorization': `Bearer ${env.RESEND_API_KEY}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n from: env.RESEND_FROM_EMAIL || 'noreply@cdp-edge.app',\n to: [payload.email],\n subject: subject || `Ol\u00E1, ${vars.name || 'voc\u00EA'}!`,\n html: `<p>${message.replace(/\\n/g, '<br>')}</p>`,\n }),\n });\n const resendData = await resendRes.json();\n const status = resendRes.ok ? 'sent' : 'failed';\n const meta = resendRes.ok ? ((resendData as any).id ?? null) : JSON.stringify(resendData);\n await env.DB.prepare(\n `INSERT INTO messaging_history (lead_id, channel, recipient, subject, content, status, meta) VALUES (?1,?2,?3,?4,?5,?6,?7)`\n ).bind(leadId, 'email', payload.email, subject, message, status, meta).run();\n }\n } catch (err: any) {\n console.error(`[Automation] rule ${(rule as any).id} error:`, err?.message || String(err));\n }\n }\n } catch (err: any) {\n console.error('[Automation] fireAutomation error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 getProfileByEmail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function getProfileByEmail(env: Env, email: string): Promise<any | null> {\n if (!env.DB || !email) return null;\n try {\n return await env.DB.prepare(\n 'SELECT * FROM user_profiles WHERE email = ? ORDER BY updated_at DESC LIMIT 1'\n ).bind(email.toLowerCase().trim()).first();\n } catch {\n return null;\n }\n}\n\n// \u2500\u2500 enrichGeoFromEdge \u2014 enriquece payload com dados de geolocaliza\u00E7\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function enrichGeoFromEdge(request: Request, env: Env, payload: TrackPayload): Promise<GeoData> {\n const cf = (request as any).cf || {};\n const ip = request.headers.get('CF-Connecting-IP') || '';\n\n let geoData: GeoData | null = null;\n if (env.GEO_CACHE && ip) {\n try {\n const cached = await env.GEO_CACHE.get(`geo:${ip}`, 'json') as GeoData | null;\n if (cached) geoData = cached;\n } catch (err: any) {\n console.error('[DB] Error fetching geo data from cache:', {\n ip,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n if (!geoData) {\n geoData = {\n country: cf.country || null,\n continent: cf.continent || null,\n asn: cf.asn || null,\n asOrg: cf.asOrganization || null,\n colo: cf.colo || null,\n city: cf.city || null,\n region: cf.region || null,\n regionCode: cf.regionCode || null,\n postalCode: cf.postalCode || null,\n latitude: cf.latitude || null,\n longitude: cf.longitude || null,\n timezone: cf.timezone || null,\n metroCode: cf.metroCode || null,\n };\n\n if (env.GEO_CACHE && ip && geoData.country) {\n try {\n await env.GEO_CACHE.put(`geo:${ip}`, JSON.stringify(geoData), { expirationTtl: 3600 });\n } catch (err: any) {\n console.error('[DB] Error caching geo data:', {\n ip,\n country: geoData.country,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n }\n\n payload.country = payload.country || geoData.country;\n payload.city = payload.city || geoData.city;\n payload.state = payload.state || geoData.regionCode;\n payload.zip = payload.zip || geoData.postalCode;\n (payload as any).geo = geoData;\n\n return geoData;\n}\n\n// \u2500\u2500 writeAuditLog \u2014 grava evento no R2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function writeAuditLog(env: Env, eventName: string, payload: TrackPayload, geoData: GeoData | null): Promise<void> {\n if (!env.AUDIT_LOGS) return;\n try {\n const now = new Date();\n const y = now.getUTCFullYear();\n const m = String(now.getUTCMonth() + 1).padStart(2, '0');\n const d = String(now.getUTCDate()).padStart(2, '0');\n const key = `logs/${y}/${m}/${d}/${now.getTime()}_${eventName}.json`;\n\n const log = {\n timestamp: now.toISOString(),\n event: eventName,\n userId: payload.userId || null,\n eventId: payload.eventId || null,\n value: payload.value || null,\n currency: payload.currency || null,\n ltvClass: payload.ltvClass || null,\n utm: {\n source: payload.utmSource || null,\n medium: payload.utmMedium || null,\n campaign: payload.utmCampaign || null,\n content: payload.utmContent || null,\n term: payload.utmTerm || null,\n restored: payload.utmRestored || false,\n },\n geo: geoData || null,\n };\n\n await env.AUDIT_LOGS.put(key, JSON.stringify(log), {\n httpMetadata: { contentType: 'application/json' },\n });\n } catch (err: any) {\n console.error('[R2 Audit] Error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 generateEdgeFingerprint \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function generateEdgeFingerprint(request: Request): Promise<string | undefined> {\n const asn = String((request as any).cf?.asn || '0');\n const lang = (request.headers.get('Accept-Language') || 'unknown').split(',')[0].trim();\n const ua = request.headers.get('User-Agent') || '';\n\n const uaBase = ua\n .toLowerCase()\n .replace(/[\\d.]+/g, '')\n .replace(/[^a-z\\s]/g, ' ')\n .split(' ')\n .filter(w => w.length > 3)\n .slice(0, 4)\n .join(' ')\n .trim();\n\n const raw = `${asn}|${lang}|${uaBase}`;\n return sha256(raw);\n}\n\n// \u2500\u2500 saveEdgeFingerprint \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function saveEdgeFingerprint(DB: D1Database, fingerprint: string | undefined, userId: string | undefined, payload: TrackPayload): Promise<void> {\n if (!DB || !fingerprint) return;\n const { utmSource, utmMedium, utmCampaign, utmContent, utmTerm } = payload;\n if (!utmSource) return;\n\n try {\n await DB.prepare(`\n INSERT INTO edge_fingerprints (fingerprint, user_id, utm_source, utm_medium, utm_campaign, utm_content, utm_term)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `).bind(\n fingerprint,\n userId || null,\n utmSource || null,\n utmMedium || null,\n utmCampaign || null,\n utmContent || null,\n utmTerm || null,\n ).run();\n } catch (err: any) {\n console.error('saveEdgeFingerprint error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 resurrectUTM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function resurrectUTM(DB: D1Database, fingerprint: string | undefined): Promise<any | null> {\n if (!DB || !fingerprint) return null;\n try {\n return await DB.prepare(`\n SELECT utm_source, utm_medium, utm_campaign, utm_content, utm_term\n FROM edge_fingerprints\n WHERE fingerprint = ?\n AND utm_source IS NOT NULL\n AND created_at > datetime('now', '-48 hours')\n ORDER BY created_at DESC\n LIMIT 1\n `).bind(fingerprint).first();\n } catch {\n return null;\n }\n}\n\n// \u2500\u2500 upsertLtvProfile \u2014 persiste LTV no perfil \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function upsertLtvProfile(env: Env, userId: string, ltv: LtvResult): Promise<void> {\n if (!env.DB || !userId) return;\n try {\n await env.DB.prepare(`\n UPDATE user_profiles\n SET predicted_ltv_class = ?,\n predicted_ltv_value = ?,\n updated_at = datetime('now')\n WHERE user_id = ?\n `).bind(ltv.class, ltv.value, userId).run();\n } catch (err: any) {\n console.error('upsertLtvProfile error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 recordLtvFeedback \u2014 fecha o ciclo preditivo com valor real de compra \u2500\u2500\u2500\u2500\u2500\n// Chamado em background quando um Purchase chega com payload.value > 0.\n// Atualiza user_profiles + ltv_ab_assignments + ltv_ab_variations em cascata.\nexport async function recordLtvFeedback(env: Env, userId: string, realValue: number): Promise<void> {\n if (!env.DB || !userId || !realValue || realValue <= 0) return;\n\n try {\n // 1. Busca predicted_ltv_value atual do perfil\n const profile = await env.DB.prepare(`\n SELECT predicted_ltv_value FROM user_profiles WHERE user_id = ?\n `).bind(userId).first();\n\n // accuracy = 1 - |pred-real|/real (0\u20131, mesmo padr\u00E3o do A/B test accuracy_score)\n const predictedValue = profile?.predicted_ltv_value;\n const ltv_accuracy = (predictedValue !== null && predictedValue !== undefined)\n ? Math.max(0, Math.round((1 - Math.abs(Number(predictedValue) - realValue) / Math.max(realValue, 1)) * 100) / 100)\n : null;\n\n // 2. Grava valor real + accuracy no perfil\n await env.DB.prepare(`\n UPDATE user_profiles\n SET real_ltv_value = ?,\n ltv_accuracy = ?,\n ltv_feedback_at = datetime('now'),\n updated_at = datetime('now')\n WHERE user_id = ?\n `).bind(realValue, ltv_accuracy, userId).run();\n\n // 3. Fecha assignment do A/B test mais recente n\u00E3o convertido (janela 60 dias)\n const assignment = await env.DB.prepare(`\n SELECT id, variation_id, predicted_ltv\n FROM ltv_ab_assignments\n WHERE user_id = ?\n AND converted = 0\n AND assigned_at > datetime('now', '-60 days')\n ORDER BY assigned_at DESC\n LIMIT 1\n `).bind(userId).first();\n\n if (!assignment) return;\n\n // 3a. Marca assignment como convertido\n await env.DB.prepare(`\n UPDATE ltv_ab_assignments\n SET converted = 1,\n real_revenue = ?,\n converted_at = datetime('now')\n WHERE id = ?\n `).bind(realValue, (assignment as any).id).run();\n\n // 3b. Atualiza m\u00E9tricas acumuladas da varia\u00E7\u00E3o (running average \u2014 safe para concorr\u00EAncia D1)\n const predLtv = (assignment as any).predicted_ltv || 0;\n const indivAcc = Math.max(0, 1 - Math.abs(predLtv - realValue) / Math.max(realValue, 1));\n\n await env.DB.prepare(`\n UPDATE ltv_ab_variations\n SET total_purchases = total_purchases + 1,\n sum_real_revenue = sum_real_revenue + ?,\n avg_real_revenue = (sum_real_revenue + ?) / (total_purchases + 1),\n accuracy_score = ROUND(\n (COALESCE(accuracy_score, 0) * total_purchases + ?) / (total_purchases + 1),\n 4\n )\n WHERE id = ?\n `).bind(realValue, realValue, indivAcc, (assignment as any).variation_id).run();\n\n } catch (err: any) {\n console.error('[LTV-Feedback] recordLtvFeedback error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 Feedback Loop \u2014 Log de falhas e m\u00E9tricas de sa\u00FAde \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function logApiFailure(DB: D1Database, platform: string, eventName: string, errorCode: string | number, errorMessage: string, eventId: string, rawPayload: string): Promise<void> {\n try {\n await DB.prepare(`\n INSERT INTO api_failures (platform, event_name, error_code, error_message, event_id, raw_payload, retry_count, final_status)\n VALUES (?, ?, ?, ?, ?, ?, 0, 'failed')\n `).bind(platform, eventName, String(errorCode), errorMessage, eventId, rawPayload).run();\n } catch (err: any) {\n console.error('Failed to log API failure:', err?.message || String(err));\n }\n}\n\nexport async function getHealthMetrics(DB: D1Database, platform: string, hours: number = 24): Promise<HealthMetrics> {\n try {\n const failures = await DB.prepare(`\n SELECT COUNT(*) as count, error_code\n FROM api_failures\n WHERE platform = ? AND created_at > datetime('now', '-${hours} hours')\n GROUP BY error_code\n `).bind(platform).all();\n\n const totalSent = await DB.prepare(`\n SELECT COUNT(*) as count\n FROM leads\n WHERE platform = ? AND created_at > datetime('now', '-${hours} hours')\n `).bind(platform).first();\n\n const totalFailed = failures.results?.reduce((sum: number, f: any) => sum + f.count, 0) || 0;\n const successRate = (totalSent as any)?.count > 0\n ? (((totalSent as any).count - totalFailed) / (totalSent as any).count) * 100\n : 100;\n\n return {\n platform,\n hours,\n events_sent: (totalSent as any)?.count || 0,\n events_failed: totalFailed,\n success_rate: successRate,\n errors_detected: (failures.results || []).map((f: any) => ({ code: f.error_code, count: f.count })),\n issues: totalFailed > ((totalSent as any)?.count || 0) * 0.1 ? ['high_error_rate'] : [],\n };\n } catch (err: any) {\n console.error('Failed to get health metrics:', err?.message || String(err));\n return { platform, hours, events_sent: 0, events_failed: 0, success_rate: 0, errors_detected: [], issues: ['metrics_unavailable'] };\n }\n}\n\nexport async function generateDailyReport(DB: D1Database): Promise<DailyReport[]> {\n const platforms = ['meta', 'ga4', 'tiktok', 'pinterest', 'reddit'];\n const today = new Date().toISOString().split('T')[0];\n const reports: DailyReport[] = [];\n\n for (const platform of platforms) {\n const metrics = await getHealthMetrics(DB, platform, 24);\n\n try {\n await DB.prepare(`\n INSERT INTO health_reports (report_date, platform, events_sent, events_failed, success_rate, errors_detected, issues_detected)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `).bind(\n today, platform,\n metrics.events_sent, metrics.events_failed, metrics.success_rate,\n JSON.stringify(metrics.errors_detected), JSON.stringify(metrics.issues)\n ).run();\n reports.push({ platform, status: 'ok' });\n } catch (err: any) {\n console.error(`Failed to generate report for ${platform}:`, err?.message || String(err));\n reports.push({ platform, status: 'failed' });\n }\n }\n\n return reports;\n}\n\nexport async function logIntelligence(DB: D1Database, runType: string, platform: string, checkType: string, status: string, currentValue: any, expectedValue: any, message: string, alertSent: boolean = false): Promise<void> {\n if (!DB) return;\n try {\n await DB.prepare(`\n INSERT INTO intelligence_logs (run_type, platform, check_type, status, current_value, expected_value, message, alert_sent)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(runType, platform, checkType, status, String(currentValue ?? ''), String(expectedValue ?? ''), message, alertSent ? 1 : 0).run();\n } catch (err: any) {\n console.error('logIntelligence error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 Webhook Processing Helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * Processa webhook de e-commerce (Hotmart, Kiwify, Ticto, etc.)\n * - Verifica duplicatas\n * - Registra evento em webhook_events\n * - Retorna true se j\u00E1 foi processado, false se deve continuar\n */\nexport async function processWebhookDuplicateCheck(\n env: Env,\n platform: string,\n transactionId: string,\n rawPayload: string,\n context?: { email?: string; orderId?: string }\n): Promise<{ duplicate: boolean; error?: string }> {\n if (!env.DB) {\n return { duplicate: false };\n }\n\n try {\n // 1. Verifica duplicatas\n const dup = await env.DB.prepare(\n 'SELECT id FROM webhook_events WHERE transaction_id = ? AND platform = ? AND status = ?'\n ).bind(transactionId, platform, 'processed').first();\n\n if (dup) {\n console.log(`[Webhook] Duplicate event skipped: ${platform}/${transactionId}`);\n return { duplicate: true };\n }\n\n // 2. Registra o evento\n await env.DB.prepare(\n 'INSERT OR IGNORE INTO webhook_events (platform, transaction_id, email, status, raw_payload) VALUES (?,?,?,?,?)'\n ).bind(platform, transactionId, context?.email || null, 'processed', rawPayload).run();\n\n return { duplicate: false };\n } catch (err: any) {\n console.error(`[Webhook] Error processing ${platform}/${transactionId}:`, {\n platform,\n transactionId,\n email: context?.email,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n return { duplicate: false, error: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 WhatsApp Cloud API v22.0 + HMAC Verification\n * sendWhatsApp, processWhatsAppWebhook, verifyHmac, sendCallMeBot\n */\n\nimport { sha256, normalizePhone } from '../utils.js';\nimport { saveLead, logApiFailure } from '../db.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ninterface WhatsAppOptions {\n to?: string;\n template?: {\n name: string;\n language?: string;\n components?: any[];\n };\n mediaType?: 'image' | 'document' | 'video' | 'audio';\n mediaUrl?: string;\n caption?: string;\n filename?: string;\n interactive?: 'buttons' | 'list';\n bodyText?: string;\n buttons?: Array<{ id: string; title: string }>;\n listButton?: string;\n rows?: Array<{ id: string; title: string; description?: string }>;\n}\n\ninterface WhatsAppMessage {\n from: string;\n id: string;\n type: string;\n text?: { body: string };\n referral?: {\n ctwa_clid?: string;\n source_id?: string;\n source_url?: string;\n headline?: string;\n };\n}\n\n// \u2500\u2500 Resolvedores de secrets (can\u00F4nico + legado) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Meta Cloud API v22.0 usa PHONE_NUMBER_ID e ACCESS_TOKEN como termos oficiais.\n// Suportamos ambos os nomes para compatibilidade com secrets j\u00E1 configurados.\nfunction resolvePhoneNumberId(env: Env): string | undefined {\n return env.WHATSAPP_PHONE_NUMBER_ID || env.WA_PHONE_ID;\n}\nfunction resolveAccessToken(env: Env): string | undefined {\n return env.WHATSAPP_ACCESS_TOKEN || env.WA_ACCESS_TOKEN;\n}\n\n// \u2500\u2500 sendWhatsApp \u2014 envia mensagem via Meta Cloud API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendWhatsApp(env: Env, tipo: string, payload: TrackPayload, options: WhatsAppOptions = {}): Promise<any> {\n if (!resolvePhoneNumberId(env) || !resolveAccessToken(env) || !env.WA_NOTIFY_NUMBER) {\n return { skipped: 'WhatsApp n\u00E3o configurado' };\n }\n\n const to = options.to || env.WA_NOTIFY_NUMBER;\n\n if (options.template) {\n const { name, language = 'pt_BR', components = [] } = options.template;\n const body = { messaging_product: 'whatsapp', to, type: 'template', template: { name, language: { code: language }, components } };\n return _sendWARequest(env, body);\n }\n\n if (options.mediaType && options.mediaUrl) {\n const mediaPayload: Record<string, string> = { link: options.mediaUrl };\n if (options.caption) mediaPayload.caption = options.caption;\n if (options.filename) mediaPayload.filename = options.filename;\n const body = { messaging_product: 'whatsapp', to, type: options.mediaType, [options.mediaType]: mediaPayload };\n return _sendWARequest(env, body);\n }\n\n if (options.interactive === 'buttons' && options.buttons && options.buttons.length > 0) {\n const body = {\n messaging_product: 'whatsapp', to, type: 'interactive',\n interactive: {\n type: 'button',\n body: { text: options.bodyText || '' },\n action: {\n buttons: options.buttons.slice(0, 3).map(b => ({ type: 'reply', reply: { id: b.id, title: b.title } })),\n },\n },\n };\n return _sendWARequest(env, body);\n }\n\n if (options.interactive === 'list' && options.rows && options.rows.length > 0) {\n const body = {\n messaging_product: 'whatsapp', to, type: 'interactive',\n interactive: {\n type: 'list',\n body: { text: options.bodyText || '' },\n action: { button: options.listButton || 'Ver op\u00E7\u00F5es', sections: [{ rows: options.rows.slice(0, 10) }] },\n },\n };\n return _sendWARequest(env, body);\n }\n\n // Text fallback (dentro da janela de 24h)\n const nome = [payload.firstName, payload.lastName].filter(Boolean).join(' ') || 'sem nome';\n const valor = payload.value ? `R$ ${parseFloat(String(payload.value)).toFixed(2)}` : '\u2014';\n const utm = payload.utmSource || 'direto';\n const produto = payload.contentName || '';\n\n let texto = '';\n if (tipo === 'Purchase') {\n texto =\n `\uD83D\uDED2 *Nova Venda!*\\n\\n` +\n `\uD83D\uDC64 ${nome}\\n\uD83D\uDCE7 ${payload.email || '\u2014'}\\n\uD83D\uDCF1 ${payload.phone || '\u2014'}\\n` +\n `\uD83D\uDCB0 ${valor}\\n${produto ? `\uD83D\uDCE6 ${produto}\\n` : ''}` +\n `\uD83D\uDD17 UTM: ${utm}\\n\uD83D\uDD50 ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })}`;\n } else if (tipo === 'Lead') {\n texto =\n `\uD83D\uDCCB *Novo Lead!*\\n\\n` +\n `\uD83D\uDCE7 ${payload.email || '\u2014'}\\n\uD83D\uDD17 UTM: ${utm}\\n` +\n `\uD83C\uDF10 ${payload.pageUrl || '\u2014'}\\n\uD83D\uDD50 ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })}`;\n } else {\n return { skipped: `tipo ${tipo} n\u00E3o suportado sem template` };\n }\n\n return _sendWARequest(env, { messaging_product: 'whatsapp', to, type: 'text', text: { body: texto } });\n}\n\n// \u2500\u2500 _sendWARequest \u2014 executor interno \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nasync function _sendWARequest(env: Env, body: Record<string, any>): Promise<any> {\n try {\n const phoneNumberId = resolvePhoneNumberId(env);\n const accessToken = resolveAccessToken(env);\n const res = await fetch(`https://graph.facebook.com/v22.0/${phoneNumberId}/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n if (!res.ok) console.error('WhatsApp Meta API error:', res.status, (data as any).error?.message || 'unknown');\n return { ok: res.ok, status: res.status, data };\n } catch (err: any) {\n console.error('WhatsApp Meta API failed:', err?.message || String(err));\n return { ok: false, error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 sendCallMeBot \u2014 alertas de sistema via WhatsApp \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendCallMeBot(env: Env, mensagem: string): Promise<any> {\n if (!env.CALLMEBOT_PHONE || !env.CALLMEBOT_APIKEY) {\n return { skipped: 'CallMeBot n\u00E3o configurado' };\n }\n try {\n const url = `https://api.callmebot.com/whatsapp.php?phone=${encodeURIComponent(env.CALLMEBOT_PHONE)}&text=${encodeURIComponent(mensagem)}&apikey=${env.CALLMEBOT_APIKEY}`;\n const res = await fetch(url);\n return { ok: res.ok, status: res.status };\n } catch (err: any) {\n console.error('CallMeBot failed:', err?.message || String(err));\n return { ok: false, error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 processWhatsAppWebhook \u2014 CTWA (Click to WhatsApp) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function processWhatsAppWebhook(env: Env, body: any, request: Request, ctx: ExecutionContext): Promise<any> {\n const entry: any = body?.entry?.[0];\n const change = entry?.changes?.find((c: any) => c.field === 'messages');\n if (!change) return { skipped: 'no messages field' };\n\n const messages = change.value?.messages;\n if (!messages || messages.length === 0) return { skipped: 'no messages' };\n\n const results: any[] = [];\n\n for (const message of messages) {\n const phone = message.from;\n const wamid = message.id;\n const referral = message.referral || {};\n const ctwaClid = referral.ctwa_clid || null;\n const adId = referral.source_id || null;\n const sourceUrl = referral.source_url || null;\n const headline = referral.headline || null;\n const messageBody = message.text?.body || message.type || '';\n\n if (!phone) { results.push({ skipped: 'no phone' }); continue; }\n\n const phoneNorm = normalizePhone(phone) || phone;\n const phoneHash = await sha256(phoneNorm);\n\n // Deduplica\u00E7\u00E3o por wamid\n if (env.DB && wamid) {\n try {\n const existing = await env.DB.prepare('SELECT id FROM whatsapp_contacts WHERE wamid = ?').bind(wamid).first();\n if (existing) { results.push({ skipped: 'duplicate wamid', wamid }); continue; }\n } catch { /* n\u00E3o bloquear se D1 falhar */ }\n }\n\n const eventId = `ctwa_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n if (env.DB) {\n ctx.waitUntil(\n env.DB.prepare(\n `INSERT OR IGNORE INTO whatsapp_contacts (phone_hash, phone_raw, wamid, ctwa_clid, ad_id, source_url, headline, capi_sent, capi_event_id, message_body) VALUES (?,?,?,?,?,?,?,0,?,?)`\n ).bind(phoneHash, phoneNorm, wamid || null, ctwaClid, adId, sourceUrl, headline, eventId, messageBody || null).run()\n );\n }\n\n const capiEvent: Record<string, any> = {\n event_name: 'Contact',\n event_time: Math.floor(Date.now() / 1000),\n event_id: eventId,\n action_source: 'chat',\n user_data: {\n ph: phoneHash,\n ...(ctwaClid && { ctwa_clid: ctwaClid }),\n client_ip_address: request.headers.get('CF-Connecting-IP') || '',\n client_user_agent: request.headers.get('User-Agent') || '',\n },\n ...(sourceUrl && { event_source_url: sourceUrl }),\n };\n\n ctx.waitUntil(\n (async () => {\n try {\n const requestBody: Record<string, any> = { data: [capiEvent], access_token: env.META_ACCESS_TOKEN };\n if (env.META_TEST_CODE) requestBody.test_event_code = env.META_TEST_CODE;\n\n const res = await fetch(\n `https://graph.facebook.com/v22.0/${env.META_PIXEL_ID}/events`,\n { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }\n );\n const data = await res.json();\n\n if (res.ok && env.DB && wamid) {\n await env.DB.prepare('UPDATE whatsapp_contacts SET capi_sent = 1 WHERE wamid = ?').bind(wamid).run();\n } else if (!res.ok) {\n console.error('[CTWA] Meta CAPI error:', res.status, (data as any).error?.message || 'unknown');\n if (env.DB) {\n await logApiFailure(env.DB, 'meta', 'Contact', (data as any).error?.code || res.status, (data as any).error?.message || 'CTWA CAPI error', eventId, JSON.stringify(requestBody));\n }\n }\n } catch (err: any) {\n console.error('[CTWA] Meta CAPI fetch failed:', err?.message || String(err));\n }\n })()\n );\n\n ctx.waitUntil(\n saveLead(env, 'Contact', {\n phone: phoneNorm, eventId, pageUrl: sourceUrl,\n utmSource: 'whatsapp_ctwa', utmMedium: 'paid_social',\n }, request, 'whatsapp')\n );\n\n results.push({ ok: true, phone: phoneNorm.slice(0, 4) + '****', ctwa_clid: ctwaClid ? 'present' : 'absent', event_id: eventId });\n }\n\n return { processed: results.length, results };\n}\n\n// \u2500\u2500 verifyHmac \u2014 valida\u00E7\u00E3o constant-time de assinatura HMAC-SHA256 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function verifyHmac(secret: string, rawBody: string, receivedSignature: string): Promise<boolean> {\n if (!secret || !receivedSignature) return false;\n try {\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(rawBody));\n const computed = Array.from(new Uint8Array(sig)).map(b => b.toString(16).padStart(2, '0')).join('');\n if (computed.length !== receivedSignature.length) return false;\n let diff = 0;\n for (let i = 0; i < computed.length; i++) {\n diff |= computed.charCodeAt(i) ^ receivedSignature.charCodeAt(i);\n }\n return diff === 0;\n } catch {\n return false;\n }\n}\n", "/**\n * CDP Edge \u2014 Match Quality (Fase 5)\n * Rastreia qualidade dos dados enviados ao Meta CAPI.\n * Detecta degrada\u00E7\u00E3o e alerta via CallMeBot.\n * Tenta auto-corre\u00E7\u00E3o onde poss\u00EDvel.\n */\n\nimport { sendCallMeBot } from '../dispatch/whatsapp.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { D1Database } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface MatchQualityThresholds {\n email_rate_min: number;\n fbp_rate_min: number;\n composite_min: number;\n min_events_alert: number;\n}\n\nexport interface EnrichedPayloadResult {\n payload: TrackPayload;\n recovered: { email: boolean; utm: boolean };\n}\n\nexport interface MatchQualityAlert {\n type: string;\n metric: string;\n message: string;\n severity?: 'critical' | 'warning';\n}\n\nexport interface MatchQualityAnalysis {\n total?: number;\n email_rate?: number;\n phone_rate?: number;\n fbp_rate?: number;\n fbc_rate?: number;\n ext_id_rate?: number;\n email_recovered_rate?: number;\n composite_score?: number;\n alerts: MatchQualityAlert[];\n}\n\n// \u2500\u2500 Thresholds de alerta \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst THRESHOLDS: MatchQualityThresholds = {\n email_rate_min: 0.40, // < 40% dos eventos com email \u2192 alerta\n fbp_rate_min: 0.30, // < 30% com fbp cookie \u2192 alerta\n composite_min: 0.45, // < 45% score composto \u2192 alerta cr\u00EDtico\n min_events_alert: 10, // m\u00EDnimo de eventos nas \u00FAltimas 2h para disparar alerta\n};\n\n// \u2500\u2500 Log de qualidade (chamado em meta.js a cada dispatch) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Registra flags de qualidade de um evento no D1 (background, n\u00E3o bloqueia).\n */\nexport async function logMatchQuality(DB: D1Database, eventName: string, payload: TrackPayload, recovered: { email: boolean; utm: boolean } = { email: false, utm: false }): Promise<void> {\n if (!DB) return;\n try {\n await DB.prepare(`\n INSERT INTO match_quality_log (\n event_name, has_email, has_phone, has_fbp, has_fbc, has_external_id,\n was_email_recovered, was_utm_restored\n ) VALUES (?,?,?,?,?,?,?,?)\n `).bind(\n eventName,\n payload.email ? 1 : 0,\n payload.phone ? 1 : 0,\n payload.fbp ? 1 : 0,\n payload.fbc ? 1 : 0,\n payload.userId ? 1 : 0,\n recovered.email ? 1 : 0,\n recovered.utm ? 1 : 0,\n ).run();\n } catch { /* n\u00E3o bloquear dispatch */ }\n}\n\n// \u2500\u2500 Auto-corre\u00E7\u00E3o de payload \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tenta enriquecer o payload com dados do Identity Graph antes do envio ao Meta.\n * Retorna { payload enriquecido, flags de recupera\u00E7\u00E3o }.\n */\nexport async function autoEnrichPayload(env: Env, payload: TrackPayload): Promise<EnrichedPayloadResult> {\n const recovered = { email: false, utm: false };\n if (!env.DB) return { payload, recovered };\n\n // 1. Tentar recuperar email/fbp/fbc do perfil pelo userId\n if (!payload.email && payload.userId) {\n try {\n const profile = await env.DB.prepare(\n `SELECT email, fbp, fbc, phone FROM user_profiles WHERE user_id = ? LIMIT 1`\n ).bind(payload.userId).first();\n\n if (profile) {\n if (profile.email && !payload.email) {\n payload.email = profile.email as string;\n recovered.email = true;\n }\n if (profile.fbp && !payload.fbp) payload.fbp = profile.fbp as string;\n if (profile.fbc && !payload.fbc) payload.fbc = profile.fbc as string;\n if (profile.phone && !payload.phone) payload.phone = profile.phone as string;\n }\n } catch (err: any) {\n console.error('[MatchQuality] Error enriching payload with profile data:', {\n userId: payload.userId,\n email: payload.email,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n // 2. UTM Resurrection j\u00E1 foi tentada no /track handler (payload.utmRestored)\n if (payload.utmRestored) recovered.utm = true;\n\n return { payload, recovered };\n}\n\n// \u2500\u2500 An\u00E1lise de qualidade (chamada pelo cron) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Analisa a qualidade das \u00FAltimas 2h e retorna m\u00E9tricas + alertas.\n */\nexport async function analyzeMatchQuality(env: Env): Promise<MatchQualityAnalysis | null> {\n if (!env.DB) return null;\n\n try {\n const row = await env.DB.prepare(`\n SELECT\n COUNT(*) AS total,\n ROUND(AVG(has_email) * 100, 1) AS email_rate,\n ROUND(AVG(has_phone) * 100, 1) AS phone_rate,\n ROUND(AVG(has_fbp) * 100, 1) AS fbp_rate,\n ROUND(AVG(has_fbc) * 100, 1) AS fbc_rate,\n ROUND(AVG(has_external_id) * 100, 1) AS ext_id_rate,\n ROUND(AVG(was_email_recovered) * 100, 1) AS email_recovered_rate,\n ROUND((AVG(has_email)*0.4 + AVG(has_fbp)*0.3 + AVG(has_phone)*0.2 + AVG(has_fbc)*0.1) * 100, 1) AS composite_score\n FROM match_quality_log\n WHERE logged_at >= datetime('now', '-2 hours')\n `).first();\n\n if (!row || Number((row as any).total) < THRESHOLDS.min_events_alert) return { total: Number((row as any)?.total || 0), alerts: [] };\n\n const alerts: MatchQualityAlert[] = [];\n\n if (Number((row as any).email_rate || 0) < THRESHOLDS.email_rate_min * 100) {\n alerts.push({\n type: 'email_low',\n metric: `email_rate: ${(row as any).email_rate}%`,\n message: `Taxa de email baixa: ${(row as any).email_rate}% (m\u00EDnimo: ${THRESHOLDS.email_rate_min * 100}%)`,\n });\n }\n\n if (Number((row as any).fbp_rate || 0) < THRESHOLDS.fbp_rate_min * 100) {\n alerts.push({\n type: 'fbp_low',\n metric: `fbp_rate: ${(row as any).fbp_rate}%`,\n message: `Cookie fbp ausente em ${100 - Number((row as any).fbp_rate)}% dos eventos \u2014 verificar cdpTrack.js`,\n });\n }\n\n if (Number((row as any).composite_score || 0) < THRESHOLDS.composite_min * 100) {\n alerts.push({\n type: 'composite_critical',\n metric: `composite: ${(row as any).composite_score}%`,\n message: `Score composto de match quality cr\u00EDtico: ${(row as any).composite_score}%`,\n severity: 'critical',\n });\n }\n\n return {\n total: Number((row as any).total),\n email_rate: Number((row as any).email_rate),\n phone_rate: Number((row as any).phone_rate),\n fbp_rate: Number((row as any).fbp_rate),\n fbc_rate: Number((row as any).fbc_rate),\n ext_id_rate: Number((row as any).ext_id_rate),\n email_recovered_rate: Number((row as any).email_recovered_rate),\n composite_score: Number((row as any).composite_score),\n alerts,\n };\n } catch (err: any) {\n console.error('[MatchQuality] analyze error:', err?.message || String(err));\n return null;\n }\n}\n\n// \u2500\u2500 Alerta via CallMeBot \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function alertMatchQuality(env: Env, analysis: MatchQualityAnalysis): Promise<void> {\n if (!analysis || analysis.alerts.length === 0) return;\n\n const hasCritical = analysis.alerts.some(a => a.severity === 'critical');\n const icon = hasCritical ? '\uD83D\uDEA8' : '\u26A0\uFE0F';\n\n const lines = [\n `${icon} CDP Edge \u2014 Match Quality Alert`,\n ``,\n `\uD83D\uDCCA \u00DAltimas 2h (${analysis.total || 0} eventos):`,\n ` Email: ${analysis.email_rate ?? 0}% ${(analysis.email_rate ?? 0) < 40 ? '\u274C' : '\u2705'}`,\n ` fbp: ${analysis.fbp_rate ?? 0}% ${(analysis.fbp_rate ?? 0) < 30 ? '\u274C' : '\u2705'}`,\n ` Score: ${analysis.composite_score ?? 0}%`,\n ``,\n `\uD83D\uDD0D Problemas:`,\n ...analysis.alerts.map(a => ` \u00B7 ${a.message}`),\n ``,\n `\uD83D\uDEE0 A\u00E7\u00F5es autom\u00E1ticas j\u00E1 ativas:`,\n ` \u00B7 Identity Graph recovery: ${analysis.email_recovered_rate ?? 0}% emails recuperados`,\n ` \u00B7 UTM Resurrection ativa`,\n ``,\n new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' }),\n ];\n\n await sendCallMeBot(env, lines.join('\\n'));\n}\n\n// \u2500\u2500 Purge peri\u00F3dico (mensal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function purgeOldMatchQualityLogs(DB: D1Database): Promise<void> {\n if (!DB) return;\n try {\n await DB.prepare(\n `DELETE FROM match_quality_log WHERE logged_at < datetime('now', '-30 days')`\n ).run();\n } catch (err: any) {\n console.error('[MatchQuality] Error purging old match quality logs:', {\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n}\n", "/**\n * CDP Edge \u2014 Meta Conversions API v22.0\n * Envia eventos server-side para a Meta CAPI.\n */\n\nimport { sha256, normalizePhone, normalizeCity } from '../utils.js';\nimport { logApiFailure } from '../db.js';\nimport { logMatchQuality, autoEnrichPayload } from '../ml/matchquality.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\ninterface EnrichedPayload {\n payload: TrackPayload;\n recovered: { email: boolean; utm: boolean };\n}\n\nexport async function sendMetaCapi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n // Auto-enriquecer payload com dados do Identity Graph antes do envio\n let recovered = { email: false, utm: false };\n if (env.DB && payload) {\n const enriched = await autoEnrichPayload(env, payload) as EnrichedPayload;\n payload = enriched.payload;\n recovered = enriched.recovered;\n }\n\n const {\n email, phone, firstName, lastName,\n city, state, country,\n zip, dob,\n fbp, fbc, userId,\n eventId, pageUrl,\n value, currency,\n contentIds, contentName, contentType, numItems,\n // Dual-layer context \u2014 funil avan\u00E7ado + im\u00F3veis\n funnel_stage, distanceBucket: distance_bucket, intentScoreNum: intent_score, intent_bucket,\n ltvScore, ltvClass, metaSignal, metaSignalBucket: metaSignalBucketVal,\n } = payload;\n\n const phoneNorm = normalizePhone(phone);\n const countryCode = (country || (request as any)?.cf?.country || 'br').toLowerCase();\n const stateCode = state ? String(state).toLowerCase() : undefined;\n const cityNorm = normalizeCity(city);\n\n const userData: Record<string, string> = {\n ...(email && { em: await sha256(email) || '' }),\n ...(phoneNorm && { ph: await sha256(phoneNorm) || '' }),\n ...(firstName && { fn: await sha256(firstName) || '' }),\n ...(lastName && { ln: await sha256(lastName) || '' }),\n ...(cityNorm && { ct: await sha256(cityNorm) || '' }),\n ...(stateCode && { st: await sha256(stateCode) || '' }),\n ...(countryCode && { country: await sha256(countryCode) || '' }),\n ...(userId && { external_id: await sha256(String(userId)) || '' }),\n ...(zip && { zp: await sha256(zip) || '' }),\n ...(dob && { db: await sha256(dob) || '' }),\n ...(fbp && { fbp }),\n ...(fbc && { fbc }),\n client_ip_address: request?.headers.get('CF-Connecting-IP')\n || request?.headers.get('X-Forwarded-For')\n || '',\n client_user_agent: request?.headers.get('User-Agent') || '',\n };\n\n const customData: Record<string, string | number | string[]> = {\n ...(value !== undefined && { value: parseFloat(String(value)) }),\n ...(currency && { currency: String(currency).toUpperCase() }),\n ...(contentIds && contentIds.length > 0 && { content_ids: contentIds }),\n ...(contentName && { content_name: contentName }),\n ...(contentType && { content_type: contentType }),\n ...(numItems && { num_items: parseInt(String(numItems)) }),\n // Contexto de funil e proximidade \u2014 enriquece matching e otimiza\u00E7\u00E3o Meta\n ...(funnel_stage && { funnel_stage }),\n ...(distance_bucket && { distance_bucket }),\n ...(intent_score && { intent_score }),\n ...(ltvScore !== undefined && ltvScore !== null && { ltv_score: ltvScore }),\n ...(ltvClass && { ltv_class: ltvClass }),\n ...(metaSignal !== undefined && metaSignal !== null && { meta_signal: metaSignal }),\n ...(metaSignalBucketVal && { meta_signal_bucket: metaSignalBucketVal }),\n ...(intent_bucket && { intent_bucket }),\n };\n\n const eventPayload = {\n event_name: eventName,\n event_time: Math.floor(Date.now() / 1000),\n event_id: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n event_source_url: pageUrl || `https://${env.SITE_DOMAIN}`,\n action_source: 'website',\n user_data: userData,\n ...(Object.keys(customData).length > 0 && { custom_data: customData }),\n };\n\n const requestBody: Record<string, any> = {\n data: [eventPayload],\n access_token: env.META_ACCESS_TOKEN,\n };\n\n if (env.META_TEST_CODE) {\n requestBody.test_event_code = env.META_TEST_CODE;\n }\n\n // Logar match quality em background (n\u00E3o bloqueia dispatch)\n if (env.DB && ctx) {\n ctx.waitUntil(logMatchQuality(env.DB, eventName, payload, recovered));\n } else if (env.DB) {\n logMatchQuality(env.DB, eventName, payload, recovered).catch(() => {});\n }\n\n const endpoint = `https://graph.facebook.com/v22.0/${env.META_PIXEL_ID}/events`;\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestBody),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n const errorCode = (data as any).error?.code || String(res.status);\n const errorMessage = (data as any).error?.message || (data as any).error?.error_user_msg || 'Unknown error';\n console.error('Meta CAPI error:', res.status, errorMessage);\n\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'meta', eventName, errorCode, errorMessage, eventPayload.event_id, JSON.stringify(requestBody)));\n }\n }\n\n return data;\n } catch (err: any) {\n console.error('Meta CAPI fetch failed:', err?.message || String(err));\n\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'meta', eventName, 'FETCH_ERROR', err?.message || String(err), eventPayload.event_id, JSON.stringify(requestBody)));\n }\n\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'meta' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n\n return { error: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 GA4 Measurement Protocol\n * Envia eventos server-side para o GA4 via Measurement Protocol.\n */\n\nimport { normalizePhone } from '../utils.js';\nimport { logApiFailure } from '../db.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\nexport async function sendGA4Mp(env: Env, ga4EventName: string, payload: TrackPayload, ctx: ExecutionContext | null): Promise<{ ok?: boolean; status?: number; skipped?: string; error?: string }> {\n if (!env.GA4_API_SECRET) return { skipped: 'GA4_API_SECRET not set' };\n\n const {\n gaClientId: clientId, sessionId,\n value, currency, contentName,\n email, phone, firstName,\n orderId,\n } = payload;\n\n if (!clientId) return { skipped: 'no clientId' };\n\n const eventParams: Record<string, string | number> = {\n ...(value !== undefined && { value: parseFloat(String(value)) }),\n ...(currency && { currency: String(currency).toUpperCase() }),\n ...(contentName && { content_name: contentName }),\n ...(orderId && { transaction_id: orderId }),\n ...(email && { user_data_email_address: email.toLowerCase().trim() }),\n ...(phone && { user_data_phone_number: normalizePhone(phone) || '' }),\n ...(firstName && { user_data_first_name: firstName.toLowerCase().trim() }),\n ...(sessionId && { session_id: sessionId }),\n engagement_time_msec: 100,\n };\n\n const body = {\n client_id: clientId,\n events: [{ name: ga4EventName, params: eventParams }],\n };\n\n const url = `https://www.google-analytics.com/mp/collect`\n + `?measurement_id=${env.GA4_MEASUREMENT_ID}`\n + `&api_secret=${env.GA4_API_SECRET}`;\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (res.status !== 204) {\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'ga4', ga4EventName, String(res.status), 'GA4 returned non-204 status', '', JSON.stringify(body)));\n }\n }\n\n return res.status === 204 ? { ok: true } : { status: res.status };\n } catch (err: any) {\n console.error('GA4 MP fetch failed:', err?.message || String(err));\n\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'ga4', ga4EventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n }\n\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: ga4EventName, payload, platform: 'ga4' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n\n return { error: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 TikTok Events API v1.3\n * Envia eventos server-side para a TikTok Events API.\n */\n\nimport { sha256, normalizePhone } from '../utils.js';\nimport { logApiFailure } from '../db.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\nexport async function sendTikTokApi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n if (!env.TIKTOK_ACCESS_TOKEN) return { skipped: 'TIKTOK_ACCESS_TOKEN not set' };\n\n const pixelId = env.TIKTOK_PIXEL_ID;\n if (!pixelId || pixelId === 'SEU_TIKTOK_PIXEL_ID') return { skipped: 'TIKTOK_PIXEL_ID not configured' };\n\n const {\n email, phone, firstName, lastName,\n fbp, fbc, ttp, ttclid, userId,\n eventId, pageUrl,\n value, currency,\n contentIds, contentName, contentType,\n } = payload;\n\n const phoneNorm = normalizePhone(phone);\n\n const user: Record<string, string> = {\n ...(email && { email: await sha256(email) || '' }),\n ...(phoneNorm && { phone_number: await sha256(phoneNorm) || '' }),\n ...(userId && { external_id: await sha256(String(userId)) || '' }),\n ...(ttp && { ttp }),\n ...(ttclid && { ttclid }),\n };\n\n const properties: Record<string, any> = {\n ...(value !== undefined && { value: parseFloat(String(value)) }),\n ...(currency && { currency: String(currency).toUpperCase() }),\n ...(contentIds && contentIds && contentIds.length > 0 && {\n contents: contentIds.map(id => ({\n content_id: String(id),\n content_name: contentName || '',\n content_type: contentType || 'product',\n quantity: 1,\n price: value ? parseFloat(String(value)) : 0,\n })),\n }),\n };\n\n const event: Record<string, any> = {\n event: eventName,\n event_time: Math.floor(Date.now() / 1000),\n event_id: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n user,\n page: {\n url: pageUrl || `https://${env.SITE_DOMAIN}`,\n referrer: request?.headers.get('Referer') || '',\n },\n ...(Object.keys(properties).length > 0 && { properties }),\n context: {\n ip: request?.headers.get('CF-Connecting-IP') || '',\n user_agent: request?.headers.get('User-Agent') || '',\n },\n };\n\n const body = {\n event_source: 'web',\n event_source_id: pixelId,\n data: [event],\n };\n\n // Endpoint can\u00F4nico: sempre /v1.3/event/track/\n const endpoint = 'https://business-api.tiktok.com/open_api/v1.3/event/track/';\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Token': env.TIKTOK_ACCESS_TOKEN,\n },\n body: JSON.stringify(body),\n });\n\n const data = await res.json();\n if (!res.ok || (data as any).code !== 0) {\n console.error('TikTok Events API error:', res.status, (data as any).message || (data as any).code || 'unknown');\n\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'tiktok', eventName, String((data as any).code || res.status), (data as any).message || 'TikTok API error', event.event_id, JSON.stringify(body)));\n }\n }\n return data;\n } catch (err: any) {\n console.error('TikTok Events API fetch failed:', err?.message || String(err));\n\n if (env.DB && ctx) {\n ctx.waitUntil(logApiFailure(env.DB, 'tiktok', eventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n }\n\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'tiktok' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n\n return { error: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 Plataformas Adicionais\n * Pinterest CAPI v5, Reddit CAPI v2.0, LinkedIn CAPI 202401, Spotify CAPI v1\n */\n\nimport { sha256, normalizePhone } from '../utils.js';\nimport { logApiFailure } from '../db.js';\nimport { Env, TrackPayload } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Pinterest Conversions API v5 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendPinterestCapi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n if (!env.PINTEREST_ACCESS_TOKEN || !env.PINTEREST_AD_ACCOUNT_ID) {\n return { skipped: 'Pinterest credentials not set' };\n }\n\n const { email, phone, userId, eventId, pageUrl, value, currency, contentIds, contentName } = payload;\n const phoneNorm = normalizePhone(phone);\n\n const pinterestEventMap: Record<string, string> = {\n PageView: 'pagevisit', ViewContent: 'pagevisit', Lead: 'lead', Purchase: 'checkout',\n AddToCart: 'addtocart', InitiateCheckout: 'checkout', CompleteRegistration: 'signup',\n Search: 'search', Contact: 'lead',\n };\n const pEvent = pinterestEventMap[eventName] || 'custom';\n\n const userData: Record<string, string | string[]> = {\n ...(email && { em: [await sha256(email) || ''] }),\n ...(phoneNorm && { ph: [await sha256(phoneNorm) || ''] }),\n ...(userId && { external_id: [await sha256(String(userId)) || ''] }),\n client_ip_address: request?.headers.get('CF-Connecting-IP') || '',\n client_user_agent: request?.headers.get('User-Agent') || '',\n };\n\n const body = {\n data: [{\n event_name: pEvent,\n action_source: 'web',\n event_time: Math.floor(Date.now() / 1000),\n event_id: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n event_source_url: pageUrl || '',\n user_data: userData,\n custom_data: {\n currency: (currency || 'BRL').toUpperCase(),\n value: value ? String(parseFloat(String(value))) : '0',\n ...(contentIds && contentIds.length > 0 && { content_ids: contentIds.map(String) }),\n ...(contentName && { content_name: contentName }),\n content_type: 'product',\n },\n }],\n };\n\n try {\n const res = await fetch(\n `https://api.pinterest.com/v5/ad_accounts/${env.PINTEREST_AD_ACCOUNT_ID}/events`,\n { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${env.PINTEREST_ACCESS_TOKEN}` }, body: JSON.stringify(body) }\n );\n const data = await res.json();\n if (!res.ok) {\n const msg = (data as any).message || (data as any).code || String(res.status);\n console.error('Pinterest CAPI error:', res.status, msg);\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'pinterest', eventName, String(res.status), msg, (body.data as any)[0].event_id, JSON.stringify(body)));\n }\n return data;\n } catch (err: any) {\n console.error('Pinterest CAPI fetch failed:', err?.message || String(err));\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'pinterest', eventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'pinterest' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n return { error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 Reddit Conversions API v2.0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendRedditCapi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n if (!env.REDDIT_ACCESS_TOKEN || !env.REDDIT_AD_ACCOUNT_ID) {\n return { skipped: 'Reddit credentials not set' };\n }\n\n const { email, phone, userId, eventId, pageUrl, value, currency } = payload;\n const phoneNorm = normalizePhone(phone);\n\n const redditEventMap: Record<string, string> = {\n PageView: 'PageVisit', ViewContent: 'ViewContent', Lead: 'Lead', Purchase: 'Purchase',\n AddToCart: 'AddToCart', InitiateCheckout: 'Purchase', CompleteRegistration: 'SignUp',\n Search: 'Search', Contact: 'Lead',\n };\n const rEvent = redditEventMap[eventName] || 'Custom';\n\n const user: Record<string, { value: string }> = {\n ...(email && { email: { value: await sha256(email) || '' } }),\n ...(phoneNorm && { phoneNumber: { value: await sha256(phoneNorm) || '' } }),\n ...(userId && { externalId: { value: await sha256(String(userId)) || '' } }),\n ipAddress: { value: request?.headers.get('CF-Connecting-IP') || '' },\n userAgent: { value: request?.headers.get('User-Agent') || '' },\n };\n\n const event: Record<string, any> = {\n event_at: new Date().toISOString(),\n event_type: { tracking_type: rEvent, ...(eventName === 'InitiateCheckout' && { conversion_type: 'BEGIN_CHECKOUT' }) },\n click_id: (payload as any).rdtClid || '',\n event_metadata: {\n currency: (currency || 'BRL').toUpperCase(),\n value_decimal: String(value || 0),\n item_count: '1',\n conversion_id: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n },\n user,\n };\n\n const body = { events: [event] };\n\n try {\n const res = await fetch(\n `https://ads-api.reddit.com/api/v2.0/conversions/events/${env.REDDIT_AD_ACCOUNT_ID}`,\n { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${env.REDDIT_ACCESS_TOKEN}` }, body: JSON.stringify(body) }\n );\n if (!res.ok) {\n const txt = await res.text();\n console.error('Reddit CAPI error:', txt);\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'reddit', eventName, String(res.status), txt, event.event_metadata.conversion_id, JSON.stringify(body)));\n return { error: `HTTP ${res.status}` };\n }\n return await res.json();\n } catch (err: any) {\n console.error('Reddit CAPI fetch failed:', err?.message || String(err));\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'reddit', eventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'reddit' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n return { error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 LinkedIn Conversions API (LinkedIn-Version: 202401) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendLinkedInCapi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n if (!env.LINKEDIN_ACCESS_TOKEN || !env.LINKEDIN_CONVERSION_ID) {\n return { skipped: 'LinkedIn credentials not set' };\n }\n\n const { email, phone, firstName, lastName, userId, eventId, pageUrl, value, currency } = payload;\n const phoneNorm = normalizePhone(phone);\n\n const linkedInEventMap: Record<string, string> = {\n Lead: 'LEAD', Purchase: 'PURCHASE', CompleteRegistration: 'REGISTRATION',\n AddToCart: 'ADD_TO_CART', InitiateCheckout: 'OTHER', ViewContent: 'OTHER',\n PageView: 'OTHER', Contact: 'LEAD',\n };\n\n const userInfo: Record<string, string> = {\n ...(email && { 'SHA256_EMAIL': await sha256(email) || '' }),\n ...(phoneNorm && { 'SHA256_PHONE': await sha256(phoneNorm) || '' }),\n ...(firstName && { 'SHA256_FIRST_NAME': await sha256(firstName.toLowerCase().trim()) || '' }),\n ...(lastName && { 'SHA256_LAST_NAME': await sha256(lastName.toLowerCase().trim()) || '' }),\n };\n\n const body: Record<string, any> = {\n conversion: `urn:li:conversion:${env.LINKEDIN_CONVERSION_ID}`,\n conversionHappenedAt: Date.now(),\n conversionValue: value ? { currencyCode: (currency || 'BRL').toUpperCase(), amount: String(parseFloat(String(value))) } : undefined,\n eventId: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n ...(Object.keys(userInfo).length > 0 && { user: { userIds: Object.entries(userInfo).map(([idType, idValue]) => ({ idType, idValue })) } }),\n };\n\n try {\n const res = await fetch('https://api.linkedin.com/rest/conversionEvents', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${env.LINKEDIN_ACCESS_TOKEN}`,\n 'LinkedIn-Version': '202401',\n 'X-Restli-Protocol-Version': '2.0.0',\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const txt = await res.text();\n console.error('LinkedIn CAPI error:', txt);\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'linkedin', eventName, String(res.status), txt, body.eventId, JSON.stringify(body)));\n return { error: `HTTP ${res.status}` };\n }\n return { ok: true };\n } catch (err: any) {\n console.error('LinkedIn CAPI fetch failed:', err?.message || String(err));\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'linkedin', eventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'linkedin' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n return { error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 Spotify Conversions API v1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendSpotifyCapi(env: Env, eventName: string, payload: TrackPayload, request: Request | null, ctx: ExecutionContext | null): Promise<any> {\n if (!env.SPOTIFY_ACCESS_TOKEN || !env.SPOTIFY_AD_ACCOUNT_ID) {\n return { skipped: 'Spotify credentials not set' };\n }\n\n const { email, phone, userId, eventId, pageUrl, value, currency } = payload;\n const phoneNorm = normalizePhone(phone);\n\n const spotifyEventMap: Record<string, string> = {\n Purchase: 'PURCHASE', Lead: 'LEAD', CompleteRegistration: 'SIGN_UP',\n AddToCart: 'ADD_TO_CART', InitiateCheckout: 'INITIATE_CHECKOUT',\n ViewContent: 'VIEW_CONTENT', PageView: 'PAGE_VIEW', Contact: 'LEAD',\n };\n const spEvent = spotifyEventMap[eventName] || 'CUSTOM';\n\n const user: Record<string, string> = {\n ...(email && { hashed_email: await sha256(email) || '' }),\n ...(phoneNorm && { hashed_phone: await sha256(phoneNorm) || '' }),\n ...(userId && { user_id: userId }),\n ip_address: request?.headers.get('CF-Connecting-IP') || '',\n user_agent: request?.headers.get('User-Agent') || '',\n };\n\n const body = {\n data: [{\n event_id: eventId || `cdp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n event_type: spEvent,\n event_time: Math.floor(Date.now() / 1000),\n url: pageUrl || '',\n user,\n ...(value !== undefined && {\n value: { currency: (currency || 'BRL').toUpperCase(), amount: parseFloat(String(value)) },\n }),\n }],\n };\n\n try {\n const res = await fetch(\n `https://advertising-api.spotify.com/conversion/v1/accounts/${env.SPOTIFY_AD_ACCOUNT_ID}/events`,\n { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${env.SPOTIFY_ACCESS_TOKEN}` }, body: JSON.stringify(body) }\n );\n if (!res.ok) {\n const txt = await res.text();\n console.error('Spotify CAPI error:', txt);\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'spotify', eventName, String(res.status), txt, (body.data as any)[0].event_id, JSON.stringify(body)));\n return { error: `HTTP ${res.status}` };\n }\n return await res.json();\n } catch (err: any) {\n console.error('Spotify CAPI fetch failed:', err?.message || String(err));\n if (env.DB && ctx) ctx.waitUntil(logApiFailure(env.DB, 'spotify', eventName, 'FETCH_ERROR', err?.message || String(err), '', JSON.stringify(body)));\n if (env.RETRY_QUEUE) {\n const send = env.RETRY_QUEUE.send({ eventType: eventName, payload, platform: 'spotify' });\n if (ctx) ctx.waitUntil(send); else send.catch(() => {});\n }\n return { error: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 Logistic Regression (pure TS, sem deps externas)\n * Treina modelo de predi\u00E7\u00E3o de convers\u00E3o com dados reais do D1.\n *\n * Features usadas (todas normalizadas 0-1):\n * utm_source, engagement_score, intention_level, recency,\n * has_email, has_phone, is_br, hour_normalized\n */\n\nimport { Env } from '../../types.js';\nimport { D1Database, KVNamespace } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface DatasetRow {\n features: number[];\n label: number;\n}\n\nexport interface LogisticModel {\n bias: number;\n weights: number[];\n accuracy: number;\n positiveRate: number;\n sampleSize: number;\n threshold: number;\n featureNames: string[];\n trainedAt: string;\n}\n\nexport interface ExtractedFeatures {\n utm_score: number;\n engagement: number;\n intention: number;\n recency: number;\n has_email: number;\n has_phone: number;\n is_br: number;\n hour: number;\n}\n\n// \u2500\u2500 Feature Engineering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst UTM_SCORES: Record<string, number> = {\n facebook: 0.90, instagram: 0.90, meta: 0.90,\n google: 0.82, youtube: 0.82,\n tiktok: 0.75,\n email: 0.68, sms: 0.68,\n organic: 0.30,\n direct: 0.20,\n};\n\nconst INTENTION_SCORES: Record<string, number> = {\n comprador: 1.00, high_intent: 1.00,\n interessado: 0.60,\n nurture: 0.30,\n curioso: 0.15,\n};\n\nexport function extractFeatures(row: any): number[] {\n const src = (row.utm_source || '').toLowerCase().trim();\n const intention = (row.intention_level || '').toLowerCase().trim();\n const daysSince = row.days_since_lead || 0;\n\n return [\n UTM_SCORES[src] ?? (src ? 0.10 : 0.05), // utm_score\n Math.min((row.engagement_score || 0) / 5, 1), // engagement (0-5 \u2192 0-1)\n INTENTION_SCORES[intention] ?? 0, // intention\n Math.max(0, 1 - daysSince / 90), // recency (0=90 dias, 1=hoje)\n row.has_email ? 1 : 0, // has_email\n row.has_phone ? 1 : 0, // has_phone\n row.is_br ? 1 : 0, // is_br\n ((row.hour || 12) / 23), // hour normalized\n ];\n}\n\n// \u2500\u2500 Sigmoid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction sigmoid(z: number): number {\n if (z > 20) return 1;\n if (z < -20) return 0;\n return 1 / (1 + Math.exp(-z));\n}\n\nfunction dot(weights: number[], features: number[]): number {\n return features.reduce((sum, f, i) => sum + (weights[i] || 0) * f, 0);\n}\n\n// \u2500\u2500 Treinamento \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Treina regress\u00E3o log\u00EDstica com gradiente descendente.\n */\nexport function trainLogisticRegression(dataset: DatasetRow[], opts: { iterations?: number; learningRate?: number; lambda?: number } = {}): LogisticModel | null {\n if (!dataset || dataset.length < 50) {\n return null; // dados insuficientes\n }\n\n const iterations = opts.iterations || 200;\n const learningRate = opts.learningRate || 0.1;\n const lambda = opts.lambda || 0.01; // L2 regularization\n const nFeatures = dataset[0].features.length;\n\n let bias = 0;\n let weights = new Array(nFeatures).fill(0);\n\n const positives = dataset.filter(d => d.label === 1).length;\n const positiveRate = positives / dataset.length;\n\n // Se menos de 5% positivos, n\u00E3o treina (dados de compra insuficientes)\n if (positiveRate < 0.03) return null;\n\n for (let iter = 0; iter < iterations; iter++) {\n let dBias = 0;\n const dWeights = new Array(nFeatures).fill(0);\n\n for (const { features, label } of dataset) {\n const z = dot(weights, features) + bias;\n const pred = sigmoid(z);\n const error = pred - label;\n\n dBias += error;\n for (let j = 0; j < nFeatures; j++) {\n dWeights[j] += error * features[j];\n }\n }\n\n const n = dataset.length;\n bias -= learningRate * (dBias / n);\n for (let j = 0; j < nFeatures; j++) {\n // L2: penaliza pesos grandes para evitar overfitting\n weights[j] -= learningRate * ((dWeights[j] / n) + lambda * weights[j]);\n }\n }\n\n // Calcular acur\u00E1cia no conjunto de treino\n let correct = 0;\n const threshold = positiveRate > 0.3 ? 0.5 : Math.max(0.3, positiveRate * 1.5);\n\n for (const { features, label } of dataset) {\n const z = dot(weights, features) + bias;\n const pred = sigmoid(z) >= threshold ? 1 : 0;\n if (pred === label) correct++;\n }\n\n const accuracy = correct / dataset.length;\n\n return {\n bias,\n weights,\n accuracy,\n positiveRate,\n sampleSize: dataset.length,\n threshold,\n featureNames: ['utm_score', 'engagement', 'intention', 'recency', 'has_email', 'has_phone', 'is_br', 'hour'],\n trainedAt: new Date().toISOString(),\n };\n}\n\n// \u2500\u2500 Infer\u00EAncia \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Prediz score de convers\u00E3o (0-100) usando pesos treinados.\n */\nexport function predictWithWeights(model: LogisticModel, features: number[]): number {\n const z = dot(model.weights, features) + model.bias;\n const prob = sigmoid(z);\n return Math.round(prob * 100);\n}\n\n// \u2500\u2500 Helpers de persist\u00EAncia \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const LTV_WEIGHTS_KV_KEY = 'ltv_weights_active';\n\nexport async function loadActiveWeights(env: Env): Promise<LogisticModel | null> {\n // 1. Tentar KV (cache ~7 dias)\n if (env.GEO_CACHE) {\n try {\n const cached = await env.GEO_CACHE.get(LTV_WEIGHTS_KV_KEY, 'json') as LogisticModel | null;\n if (cached?.weights?.length) return cached;\n } catch (err: any) {\n console.error('[Logistic] Error fetching LTV weights from KV cache:', {\n key: LTV_WEIGHTS_KV_KEY,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n // 2. Fallback: D1\n if (!env.DB) return null;\n try {\n const row = await env.DB.prepare(\n `SELECT weights_json FROM ltv_model_weights WHERE is_active = 1 ORDER BY trained_at DESC LIMIT 1`\n ).first();\n if (!row || !(row as any).weights_json) return null;\n const model = JSON.parse((row as any).weights_json) as LogisticModel;\n\n // Popular KV para pr\u00F3ximas requests\n if (env.GEO_CACHE && model?.weights?.length) {\n env.GEO_CACHE.put(LTV_WEIGHTS_KV_KEY, JSON.stringify(model), { expirationTtl: 604800 }).catch(() => {});\n }\n return model;\n } catch {\n return null;\n }\n}\n\nexport async function saveWeights(DB: D1Database, model: LogisticModel): Promise<void> {\n if (!DB || !model) return;\n const now = new Date().toISOString();\n\n // Desativar modelo anterior\n await DB.prepare(`UPDATE ltv_model_weights SET is_active = 0 WHERE is_active = 1`).run();\n\n // Inserir novo como ativo\n await DB.prepare(`\n INSERT INTO ltv_model_weights (trained_at, is_active, sample_size, positive_rate, accuracy, weights_json)\n VALUES (?, 1, ?, ?, ?, ?)\n `).bind(\n now,\n model.sampleSize,\n model.positiveRate,\n model.accuracy,\n JSON.stringify(model),\n ).run();\n}\n", "/**\n * CDP Edge \u2014 LTV Prediction + A/B Testing de Prompts (Fases 3 e 4)\n * predictLtv, getLtvAbVariation, recordAbAssignment, handlers /api/ltv/*\n */\n\nimport { extractFeatures, predictWithWeights, loadActiveWeights } from './logistic.js';\nimport { Env, TrackPayload } from '../../types.js';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface LtvResult {\n score: number;\n class: string;\n value: number;\n source?: string;\n}\n\nexport interface AbVariation {\n id: number;\n test_id: number;\n name: string;\n system_prompt: string;\n weight: number;\n is_control: number;\n total_assigned?: number;\n accuracy_score?: number;\n}\n\nexport interface AbTestCreate {\n name: string;\n description?: string;\n min_sample?: number;\n variations: Array<{\n name: string;\n system_prompt?: string;\n weight?: number;\n is_control?: boolean;\n }>;\n}\n\nexport interface AutoDecideResult {\n decided: boolean;\n reason?: string;\n test_id?: number;\n test_name?: string;\n winner_id?: number;\n winner_name?: string;\n improvement?: string;\n is_control_winner?: boolean;\n winning_prompt?: string;\n}\n\n// Cache key para o teste ativo (KV \u2014 evita hit no D1 a cada request /track)\nconst AB_LTV_CACHE_KEY = 'ab_ltv_active_test';\n\n// \u2500\u2500 Prompt especializado para im\u00F3veis \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Ativado automaticamente quando property_lat/lng est\u00E3o presentes no payload.\n// Override por A/B test tem prioridade sobre este prompt.\nconst REAL_ESTATE_PROMPT = `You are a real estate lead scoring expert for the Brazilian market.\nReply ONLY with a JSON object {\"adjustment\": <integer between -15 and 15>} based on the lead data.\nScoring rules (apply additively):\n- distance_km < 5: +12 (lives nearby, buys fast)\n- distance_km 5-15: +8\n- distance_km 15-30: +3\n- distance_km > 30: 0\n- distance_km unknown: +3 (gave intent signal without geo)\n- event = Schedule or route click: +5 (physical visit intent)\n- scroll_score >= 3 AND time_level = comprador: +4 (deep engagement)\n- hour_brt between 18-22 (weekday): +3 (active decision window)\n- has_phone = true: +2 (reachable for follow-up)\nNo explanation. JSON only.`;\n\n// \u2500\u2500 predictLtv \u2014 Heur\u00EDstica em 5 dimens\u00F5es (0-100 pts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function predictLtv(env: Env, payload: TrackPayload, request: Request | null, customSystemPrompt: string | null = null): Promise<LtvResult> {\n // \u2500\u2500 Tentar modelo treinado (regress\u00E3o log\u00EDstica real) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Se existir modelo ativo no KV/D1, usa-o em vez da heur\u00EDstica manual.\n // Fallback autom\u00E1tico para heur\u00EDstica se modelo n\u00E3o dispon\u00EDvel.\n try {\n const model = await loadActiveWeights(env);\n if (model?.weights?.length) {\n const hour = new Date().getUTCHours();\n const country = (payload.country || (request as any)?.cf?.country || '').toUpperCase();\n const features = extractFeatures({\n utm_source: payload.utmSource,\n engagement_score: parseFloat(String(payload.engagementScore || '0')),\n intention_level: payload.intentionLevel,\n days_since_lead: 0, // evento atual = rec\u00EAncia m\u00E1xima\n has_email: !!payload.email,\n has_phone: !!payload.phone,\n is_br: country === 'BR',\n hour,\n });\n\n const score100 = predictWithWeights(model, features);\n const ltvClass = score100 >= 70 ? 'High' : score100 >= 40 ? 'Medium' : 'Low';\n const ltvMultiplier = score100 >= 70 ? 3.5 : score100 >= 40 ? 1.8 : 0.8;\n const productValue = payload.value ? parseFloat(String(payload.value)) : 0;\n const baseValue = productValue > 0 ? productValue : 197;\n const predictedValue = Math.round(baseValue * ltvMultiplier * 100) / 100;\n\n return { score: score100, class: ltvClass, value: predictedValue, source: 'model' };\n }\n } catch { /* fallback para heur\u00EDstica */ }\n\n let score = 0;\n\n // 1. Engajamento browser (0\u201330)\n const engScore = parseFloat(String(payload.engagementScore || '0'));\n const userScore = parseFloat(String((payload as any).userScore || '0'));\n score += Math.min(15, Math.round((engScore / 5) * 15));\n score += Math.min(15, Math.round((userScore / 100) * 15));\n\n // 2. Origem de tr\u00E1fego (0\u201325)\n const src = (payload.utmSource || '').toLowerCase();\n const utm_score_map: Record<string, number> = {\n facebook: 25, instagram: 25, meta: 25,\n google: 22, youtube: 22, tiktok: 20,\n email: 18, sms: 18,\n organic: 10, direct: 5,\n };\n score += utm_score_map[src] ?? (src ? 8 : 3);\n\n // 3. Contexto de rede (0\u201315)\n const hour = new Date().getUTCHours();\n const country = (payload.country || (request as any)?.cf?.country || '').toUpperCase();\n const org = String((request as any).cf?.asOrganization || '').toLowerCase();\n\n const isHighConvTime = hour >= 21 || hour <= 2;\n score += isHighConvTime ? 8 : (hour >= 12 && hour <= 20 ? 4 : 1);\n\n const latam = ['AR', 'CL', 'CO', 'MX', 'PE', 'UY', 'PY', 'BO'];\n score += country === 'BR' ? 5 : (latam.includes(country) ? 3 : 1);\n\n const isCorp = /ltda|s\\.a\\.|corp|telecom|fibra|claro|vivo|tim|oi/.test(org);\n score += isCorp ? 2 : 0;\n\n // 4. Contexto do evento (0\u201320)\n const intentionLevel = (payload.intentionLevel || '').toLowerCase();\n if (intentionLevel === 'comprador' || intentionLevel === 'high_intent') score += 20;\n else if (intentionLevel === 'interessado') score += 12;\n else if (intentionLevel === 'nurture') score += 6;\n\n // 5. Dados PII dispon\u00EDveis (0\u201310)\n if (payload.email) score += 4;\n if (payload.phone) score += 4;\n if (payload.firstName) score += 2;\n\n // 5b. Tipo de evento imobili\u00E1rio (0\u201315) \u2014 sinais de inten\u00E7\u00E3o de compra f\u00EDsica\n const evType = ((payload as any).eventType || '').toLowerCase();\n if (evType === 'customizeproduct') score += 15; // simula\u00E7\u00E3o de financiamento \u2192 inten\u00E7\u00E3o m\u00E1xima\n else if (evType === 'findlocation') score += 10; // viu mapa/localiza\u00E7\u00E3o \u2192 visita f\u00EDsica iminente\n else if (evType === 'addtowishlist') score += 8; // favoritou \u2192 interesse persistente\n\n // 6. Proximidade ao im\u00F3vel f\u00EDsico (0\u201315) \u2014 apenas quando dist\u00E2ncia calculada\n const distKm = parseFloat(String(payload.distanceKm || (payload as any).user_distance_km || '-1'));\n if (distKm >= 0) {\n if (distKm < 5) score += 15;\n else if (distKm < 15) score += 10;\n else if (distKm < 30) score += 6;\n else if (distKm < 60) score += 3;\n // > 60km: sem b\u00F4nus \u2014 lead distante precisa de argumento diferente\n } else if (payload.property_lat || (payload as any).propertyLat) {\n // Coords no payload mas dist\u00E2ncia n\u00E3o resolvida: pequeno b\u00F4nus por inten\u00E7\u00E3o de rota\n score += 3;\n }\n\n score = Math.min(100, score);\n\n let ltvClass: string;\n let ltvMultiplier: number;\n if (score >= 70) {\n ltvClass = 'High'; ltvMultiplier = 3.5;\n } else if (score >= 40) {\n ltvClass = 'Medium'; ltvMultiplier = 1.8;\n } else {\n ltvClass = 'Low'; ltvMultiplier = 0.8;\n }\n\n const productValue = payload.value ? parseFloat(String(payload.value)) : 0;\n const baseValue = productValue > 0 ? productValue : 197;\n const predictedValue = Math.round(baseValue * ltvMultiplier * 100) / 100;\n\n // Enriquecimento opcional via Workers AI\n let aiAdjustment = 0;\n if (env.AI && score >= 40) {\n try {\n const isRealEstate = !!(payload.property_lat || (payload as any).propertyLat);\n const systemContent = customSystemPrompt ||\n (isRealEstate\n ? REAL_ESTATE_PROMPT\n : 'You are a conversion rate expert. Reply ONLY with a JSON object {\"adjustment\": <number between -10 and 10>} based on the lead data provided. No explanation.');\n\n const userContext: Record<string, any> = {\n utm_source: payload.utmSource,\n intention: intentionLevel,\n engagement: engScore,\n hour_utc: hour,\n country,\n has_email: !!payload.email,\n has_phone: !!payload.phone,\n };\n if (isRealEstate) {\n userContext.event_type = 'real_estate_schedule';\n userContext.distance_km = payload.distanceKm || (payload as any).user_distance_km || 'unknown';\n userContext.distance_bucket = payload.distanceBucket || 'unknown';\n userContext.scroll_score = payload.scrollScore || (payload as any).scroll_score || 0;\n userContext.time_level = payload.timeLevel || (payload as any).timeLevel || 'unknown';\n userContext.intent_score = payload.intentScoreNum || payload.intent_score || 'high';\n userContext.hour_brt = (hour - 3 + 24) % 24; // UTC-3 aproximado\n }\n\n const prompt = [\n { role: 'system', content: systemContent },\n { role: 'user', content: JSON.stringify(userContext) },\n ];\n const aiRes = await env.AI.run('@cf/ibm-granite/granite-4.0-h-micro', { messages: prompt, max_tokens: 32 });\n const parsed = JSON.parse((aiRes as any).response.trim());\n if (typeof parsed.adjustment === 'number') {\n aiAdjustment = Math.max(-10, Math.min(10, parsed.adjustment));\n }\n } catch { /* graceful fallback */ }\n }\n\n return {\n score: Math.min(100, Math.max(0, score + aiAdjustment)),\n class: ltvClass,\n value: predictedValue,\n };\n}\n\n// \u2500\u2500 getLtvAbVariation \u2014 busca varia\u00E7\u00E3o ativa do A/B test \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function getLtvAbVariation(env: Env): Promise<AbVariation | null> {\n if (!env.DB) return null;\n\n try {\n let testData: any = null;\n if (env.GEO_CACHE) {\n const cached = await env.GEO_CACHE.get(AB_LTV_CACHE_KEY, 'json') as any;\n if (cached) testData = cached;\n }\n\n if (!testData) {\n const test = await env.DB.prepare(`\n SELECT t.id AS test_id, v.id AS variation_id,\n v.name, v.system_prompt, v.weight, v.is_control\n FROM ltv_ab_tests t\n JOIN ltv_ab_variations v ON v.test_id = t.id\n WHERE t.status = 'running'\n ORDER BY t.id DESC\n `).all();\n\n if (!test.results || test.results.length === 0) {\n if (env.GEO_CACHE) await env.GEO_CACHE.put(AB_LTV_CACHE_KEY, JSON.stringify(null), { expirationTtl: 300 });\n return null;\n }\n\n testData = test.results;\n if (env.GEO_CACHE) await env.GEO_CACHE.put(AB_LTV_CACHE_KEY, JSON.stringify(testData), { expirationTtl: 300 });\n }\n\n if (!testData || testData.length === 0) return null;\n\n const totalWeight = testData.reduce((s: number, v: AbVariation) => s + (v.weight || 0.5), 0);\n let rand = Math.random() * totalWeight;\n for (const variation of testData) {\n rand -= (variation.weight || 0.5);\n if (rand <= 0) return variation;\n }\n return testData[testData.length - 1];\n\n } catch (err: any) {\n console.error('[AB-LTV] getLtvAbVariation error:', err?.message || String(err));\n return null;\n }\n}\n\n// \u2500\u2500 recordAbAssignment \u2014 registra varia\u00E7\u00E3o usada para um lead \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function recordAbAssignment(env: Env, userId: string, variationId: number, testId: number, predictedLtv: number | null, predictedClass: string | null, emailHash: string | null): Promise<void> {\n if (!env.DB) return;\n try {\n await env.DB.prepare(`\n INSERT INTO ltv_ab_assignments (test_id, variation_id, user_id, email_hash, predicted_ltv, predicted_class, assigned_at)\n VALUES (?, ?, ?, ?, ?, ?, datetime('now'))\n `).bind(testId, variationId, userId, emailHash || null, predictedLtv || null, predictedClass || null).run();\n\n await env.DB.prepare(`UPDATE ltv_ab_variations SET total_assigned = total_assigned + 1 WHERE id = ?`).bind(variationId).run();\n } catch (err: any) {\n console.error('[AB-LTV] recordAbAssignment error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 POST /api/ltv/ab-test/create \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleLtvAbTestCreate(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: AbTestCreate;\n try { body = await request.json() as AbTestCreate; }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido no body' }), { status: 400, headers }); }\n\n const { name, description, min_sample = 100, variations } = body;\n if (!name) return new Response(JSON.stringify({ error: 'name \u00E9 obrigat\u00F3rio' }), { status: 400, headers });\n if (!Array.isArray(variations) || variations.length < 2) {\n return new Response(JSON.stringify({ error: 'M\u00EDnimo 2 varia\u00E7\u00F5es s\u00E3o necess\u00E1rias' }), { status: 400, headers });\n }\n\n const running = await env.DB.prepare(`SELECT id FROM ltv_ab_tests WHERE status = 'running' LIMIT 1`).first();\n if (running) {\n return new Response(JSON.stringify({ error: 'J\u00E1 existe um teste em andamento.', running_test_id: (running as any).id }), { status: 409, headers });\n }\n\n try {\n const now = new Date().toISOString();\n const totalWeight = variations.reduce((s, v) => s + (v.weight || 0.5), 0);\n if (Math.abs(totalWeight - 1.0) > 0.05) {\n return new Response(JSON.stringify({ error: `A soma dos weights deve ser 1.0. Recebido: ${totalWeight.toFixed(3)}` }), { status: 400, headers });\n }\n if (!variations.some(v => v.is_control)) {\n return new Response(JSON.stringify({ error: 'Pelo menos uma varia\u00E7\u00E3o deve ter is_control: true' }), { status: 400, headers });\n }\n\n const testRes = await env.DB.prepare(`\n INSERT INTO ltv_ab_tests (name, description, status, min_sample, created_at) VALUES (?, ?, 'running', ?, ?)\n `).bind(name, description || null, min_sample, now).run();\n\n const testId = (testRes as any).meta?.last_row_id;\n if (!testId) throw new Error('Falha ao criar o teste no D1');\n\n const createdVariations: Array<{ id: number; name: string; weight: number; is_control: boolean }> = [];\n for (const v of variations) {\n const vRes = await env.DB.prepare(`\n INSERT INTO ltv_ab_variations (test_id, name, system_prompt, weight, is_control, created_at) VALUES (?, ?, ?, ?, ?, ?)\n `).bind(testId, v.name, v.system_prompt, v.weight || 0.5, v.is_control ? 1 : 0, now).run();\n createdVariations.push({ id: (vRes as any).meta?.last_row_id, name: v.name, weight: v.weight || 0.5, is_control: !!v.is_control });\n }\n\n if (env.GEO_CACHE) await env.GEO_CACHE.delete(AB_LTV_CACHE_KEY);\n\n return new Response(JSON.stringify({ success: true, test_id: testId, name, status: 'running', min_sample, variations: createdVariations, started_at: now }), { status: 201, headers });\n } catch (err: any) {\n console.error('[AB-LTV] create error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/ltv/ab-test/list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleLtvAbTestList(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const status = url.searchParams.get('status') || null;\n const limit = Math.min(parseInt(url.searchParams.get('limit') || '20'), 50);\n\n try {\n const cond = status ? 'WHERE t.status = ?' : '';\n const bindings: (string | number)[] = status ? [status, limit] : [limit];\n\n const tests = await env.DB.prepare(`\n SELECT t.id, t.name, t.description, t.status, t.winner_id,\n t.started_at, t.completed_at, t.created_at, t.min_sample,\n COUNT(DISTINCT v.id) AS variation_count,\n SUM(v.total_assigned) AS total_assigned\n FROM ltv_ab_tests t\n LEFT JOIN ltv_ab_variations v ON v.test_id = t.id\n ${cond}\n GROUP BY t.id\n ORDER BY t.created_at DESC\n LIMIT ?\n `).bind(...bindings).all();\n\n return new Response(JSON.stringify({ success: true, total: (tests.results || []).length, tests: tests.results || [] }), { status: 200, headers });\n } catch (err: any) {\n console.error('[AB-LTV] list error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/ltv/ab-test/results \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleLtvAbTestResults(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const testId = url.searchParams.get('test_id');\n\n try {\n let testRes: any;\n\n if (testId) {\n // Query espec\u00EDfica para teste por ID\n testRes = await env.DB.prepare(`\n SELECT id, name, status, min_sample, winner_id, started_at\n FROM ltv_ab_tests\n WHERE test_id = ?\n LIMIT 1\n `).bind(parseInt(testId)).first();\n } else {\n // Query padr\u00E3o: busca teste ativo em execu\u00E7\u00E3o\n testRes = await env.DB.prepare(`\n SELECT id, name, status, min_sample, winner_id, started_at\n FROM ltv_ab_tests\n WHERE status = 'running'\n LIMIT 1\n `).first();\n }\n if (!testRes) return new Response(JSON.stringify({ error: 'Nenhum teste encontrado' }), { status: 404, headers });\n\n const perf = await env.DB.prepare(`SELECT * FROM v_ab_test_performance WHERE test_id = ?`).bind((testRes as any).id).all();\n const variations = perf.results || [];\n const ready = variations.every((v: any) => (v.total_assigned || 0) >= (testRes as any).min_sample);\n let recommendation: any = null;\n\n if (ready && variations.length > 0) {\n const best = variations.reduce((a: any, b: any) => (Number(b.accuracy_score) || 0) > (Number(a.accuracy_score) || 0) ? b : a);\n const control = variations.find((v: any) => v.is_control);\n const improvement = control ? ((Number(best.accuracy_score) || 0) - (Number(control.accuracy_score) || 0)) * 100 : null;\n recommendation = {\n winner_variation_id: best.variation_id, winner_variation_name: best.variation_name,\n accuracy_score: best.accuracy_score, improvement_vs_control: improvement ? `+${improvement.toFixed(1)}%` : null,\n ready_to_declare: true,\n };\n }\n\n return new Response(JSON.stringify({\n success: true,\n test: { id: (testRes as any).id, name: (testRes as any).name, status: (testRes as any).status, min_sample: (testRes as any).min_sample, started_at: (testRes as any).started_at, is_ready: ready },\n variations, recommendation,\n }), { status: 200, headers });\n } catch (err: any) {\n console.error('[AB-LTV] results error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 POST /api/ltv/ab-test/winner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleLtvAbTestWinner(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: any;\n try { body = await request.json(); }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido' }), { status: 400, headers }); }\n\n const { test_id, variation_id } = body;\n if (!test_id || !variation_id) {\n return new Response(JSON.stringify({ error: 'test_id e variation_id s\u00E3o obrigat\u00F3rios' }), { status: 400, headers });\n }\n\n try {\n const variation = await env.DB.prepare(`SELECT id, name, system_prompt, is_control FROM ltv_ab_variations WHERE id = ? AND test_id = ?`).bind(variation_id, test_id).first();\n if (!variation) return new Response(JSON.stringify({ error: 'Varia\u00E7\u00E3o n\u00E3o encontrada para este teste' }), { status: 404, headers });\n\n await env.DB.prepare(`UPDATE ltv_ab_tests SET winner_id = ?, status = 'completed', completed_at = datetime('now') WHERE id = ?`).bind(variation_id, test_id).run();\n if (env.GEO_CACHE) await env.GEO_CACHE.delete(AB_LTV_CACHE_KEY);\n\n return new Response(JSON.stringify({\n success: true, test_id, winner_variation_id: variation_id, winner_name: (variation as any).name,\n is_control: (variation as any).is_control === 1, winning_prompt: (variation as any).system_prompt,\n message: (variation as any).is_control === 1\n ? 'O prompt original (controle) venceu. Nenhuma altera\u00E7\u00E3o necess\u00E1ria.'\n : 'Novo prompt vencedor identificado. Copie o campo winning_prompt e aplique ao predictLtv() como novo default.',\n }), { status: 200, headers });\n } catch (err: any) {\n console.error('[AB-LTV] winner error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 autoDecideAbWinner \u2014 declara winner automaticamente via cron \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Crit\u00E9rio: todas as varia\u00E7\u00F5es com amostra >= min_sample\n// E diferen\u00E7a de accuracy_score >= 5pp entre melhor e controle\nexport async function autoDecideAbWinner(env: Env): Promise<AutoDecideResult> {\n if (!env.DB) return { decided: false, reason: 'no_db' };\n\n try {\n // Buscar teste ativo\n const test = await env.DB.prepare(\n `SELECT id, name, min_sample, status FROM ltv_ab_tests WHERE status = 'running' ORDER BY id DESC LIMIT 1`\n ).first();\n\n if (!test) return { decided: false, reason: 'no_running_test' };\n\n // Buscar performance das varia\u00E7\u00F5es\n const perf = await env.DB.prepare(\n `SELECT * FROM v_ab_test_performance WHERE test_id = ?`\n ).bind((test as any).id).all();\n\n const variations = perf.results || [];\n if (variations.length < 2) return { decided: false, reason: 'insufficient_variations' };\n\n // Verificar se todas t\u00EAm amostra suficiente\n const allReady = variations.every((v: any) => (v.total_assigned || 0) >= (test as any).min_sample);\n if (!allReady) {\n const minAssigned = Math.min(...variations.map((v: any) => v.total_assigned || 0));\n return { decided: false, reason: `sample_insufficient (${minAssigned}/${(test as any).min_sample})` };\n }\n\n // Encontrar melhor e controle\n const best = variations.reduce((a: any, b: any) => (b.accuracy_score || 0) > (a.accuracy_score || 0) ? b : a);\n const control = variations.find((v: any) => v.is_control) || variations[0];\n\n const bestScore = parseFloat(String(best.accuracy_score) || '0');\n const controlScore = parseFloat(String(control.accuracy_score) || '0');\n const diff = bestScore - controlScore;\n\n // Empate t\u00E9cnico \u2192 controle vence (determin\u00EDstico)\n if (diff < 0.05) {\n return { decided: false, reason: `difference_too_small (${(diff * 100).toFixed(1)}pp < 5pp)` };\n }\n\n // Declarar winner\n await env.DB.prepare(\n `UPDATE ltv_ab_tests SET winner_id = ?, status = 'completed', completed_at = datetime('now') WHERE id = ?`\n ).bind(best.variation_id, test.id).run();\n\n if (env.GEO_CACHE) await env.GEO_CACHE.delete(AB_LTV_CACHE_KEY);\n\n console.log(`[AB-LTV] Winner auto-declarado: teste ${test.id}, varia\u00E7\u00E3o \"${best.variation_name}\" (+${(diff * 100).toFixed(1)}pp)`);\n\n return {\n decided: true,\n test_id: (test as any).id,\n test_name: (test as any).name,\n winner_id: typeof best.variation_id === 'number' ? best.variation_id : undefined,\n winner_name: typeof best.variation_name === 'string' ? best.variation_name : undefined,\n improvement: `+${(diff * 100).toFixed(1)}pp`,\n is_control_winner: best.variation_id === control.variation_id,\n winning_prompt: String(best.system_prompt || ''),\n };\n\n } catch (err: any) {\n console.error('[AB-LTV] autoDecide error:', err?.message || String(err));\n return { decided: false, reason: err?.message || String(err) };\n }\n}\n", "/**\n * CDP Edge \u2014 ML Clustering (Fase 1)\n * Handlers das rotas /api/segmentation/*\n */\n\nimport { tryParseJson } from '../utils.js';\nimport { Env } from '../../types.js';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ninterface KmeansResult {\n assignments: number[];\n centroids: number[][];\n}\n\ninterface ClusterStats {\n c: number;\n size: number;\n pct: number;\n avgLtv: number;\n avgEng: number;\n avgDays: number;\n topSource: string;\n topState: string;\n topIntent: string;\n}\n\ninterface Cluster {\n cluster_id: number;\n name: string;\n size: number;\n percentage: number;\n action_recommendation: string;\n characteristics: {\n avg_ltv_class: number;\n avg_engagement_score: number;\n avg_intention_level: number;\n avg_days_since_lead: number;\n dominant_countries: string[];\n dominant_states: string[];\n dominant_utm_sources: string[];\n top_features: string[];\n };\n}\n\ninterface ClusterInfo {\n cluster_id: number;\n name: string;\n action: string;\n}\n\n// \u2500\u2500 Helpers K-means vetorial \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _cosDist(a: number[], b: number[]): number {\n let dot = 0, na = 0, nb = 0;\n for (let i = 0; i < a.length; i++) { dot += a[i]*b[i]; na += a[i]*a[i]; nb += b[i]*b[i]; }\n return 1 - dot / (Math.sqrt(na) * Math.sqrt(nb) + 1e-10);\n}\n\nfunction _kmeansRun(vectors: number[][], k: number, maxIter = 25): KmeansResult {\n const n = vectors.length, dim = vectors[0].length;\n const centroids = [vectors[Math.floor(Math.random() * n)]];\n while (centroids.length < k) {\n const dists = vectors.map(v => Math.min(...centroids.map(c => _cosDist(v, c))));\n const sum = dists.reduce((a, b) => a + b, 0);\n let r = Math.random() * sum, cumul = 0;\n for (let i = 0; i < n; i++) { cumul += dists[i]; if (cumul >= r) { centroids.push(vectors[i]); break; } }\n if (centroids.length < k) centroids.push(vectors[Math.floor(Math.random() * n)]);\n }\n let assignments = new Array(n).fill(0);\n for (let iter = 0; iter < maxIter; iter++) {\n let changed = false;\n for (let i = 0; i < n; i++) {\n let best = 0, bestD = Infinity;\n for (let c = 0; c < k; c++) { const d = _cosDist(vectors[i], centroids[c]); if (d < bestD) { bestD = d; best = c; } }\n if (assignments[i] !== best) { assignments[i] = best; changed = true; }\n }\n if (!changed) break;\n for (let c = 0; c < k; c++) {\n const members = vectors.filter((_, i) => assignments[i] === c);\n if (!members.length) continue;\n for (let d = 0; d < dim; d++) centroids[c][d] = members.reduce((s, v) => s + v[d], 0) / members.length;\n }\n }\n return { assignments, centroids };\n}\n\nfunction _silhouette(vectors: number[][], assignments: number[], k: number): number {\n const n = vectors.length;\n let total = 0;\n for (let i = 0; i < n; i++) {\n const ci = assignments[i];\n const same = vectors.filter((_, j) => j !== i && assignments[j] === ci);\n const a = same.length ? same.reduce((s, v) => s + _cosDist(vectors[i], v), 0) / same.length : 0;\n let b = Infinity;\n for (let c = 0; c < k; c++) {\n if (c === ci) continue;\n const other = vectors.filter((_, j) => assignments[j] === c);\n if (other.length) b = Math.min(b, other.reduce((s, v) => s + _cosDist(vectors[i], v), 0) / other.length);\n }\n total += b === Infinity ? 0 : (b - a) / Math.max(a, b);\n }\n return Math.round((total / n) * 1000) / 1000;\n}\n\nfunction _buildLeadProfile(l: any): string {\n return [\n `LTV: ${l.predicted_ltv_class || 'desconhecido'}`,\n `engajamento: ${Math.round(l.engagement_score || 0)}`,\n `inten\u00E7\u00E3o: ${l.intention_level || 'desconhecida'}`,\n `origem: ${l.utm_source || 'direto'}`,\n `canal: ${l.utm_medium || 'desconhecido'}`,\n `pa\u00EDs: ${l.country || 'BR'}`,\n `estado: ${l.state || ''}`,\n `hora: ${l.hour_of_day || 12}h`,\n (l.is_weekend ? 'fim-de-semana' : 'dia-\u00FAtil'),\n `rec\u00EAncia: ${l.days_since_lead || 0} dias`,\n ].filter(Boolean).join(', ');\n}\n\n// \u2500\u2500 POST /api/segmentation/cluster \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Clustering real: embeddinggemma-300m \u2192 K-means vetorial \u2192 Granite para nomear\nexport async function handleSegmentationCluster(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n if (!env.AI) return new Response(JSON.stringify({ error: 'Workers AI n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const algorithm = url.searchParams.get('algorithm') || 'kmeans';\n const nClusters = Math.min(10, Math.max(2, parseInt(url.searchParams.get('n_clusters') || '5')));\n const clientVertical = url.searchParams.get('vertical') || 'general';\n const forceRecluster = url.searchParams.get('force') === 'true';\n\n if (!['kmeans', 'dbscan', 'hierarchical'].includes(algorithm)) {\n return new Response(JSON.stringify({ error: 'algorithm deve ser: kmeans, dbscan ou hierarchical', received: algorithm }), { status: 400, headers });\n }\n\n try {\n if (!forceRecluster) {\n const existing = await env.DB.prepare(`\n SELECT id, created_at, cluster_name FROM ml_segments\n WHERE clustering_algorithm = ? AND is_active = 1 AND client_vertical = ?\n ORDER BY created_at DESC LIMIT 1\n `).bind(algorithm, clientVertical).first();\n if (existing) {\n const ageDays = (Date.now() - new Date((existing as any).created_at).getTime()) / 864e5;\n if (ageDays < 7) {\n return new Response(JSON.stringify({\n success: true, message: 'Cluster existente ainda v\u00E1lido (< 7 dias). Use ?force=true para re-clustering.',\n cluster_id: (existing as any).id, cluster_name: (existing as any).cluster_name,\n age_days: Math.round(ageDays * 10) / 10, use_existing: true,\n }), { status: 200, headers });\n }\n }\n }\n\n const leadsRes = await env.DB.prepare(`\n SELECT id, predicted_ltv_class, engagement_score, intention_level,\n country, state, utm_source, utm_medium, bot_score,\n CAST(strftime('%H', created_at) AS INTEGER) AS hour_of_day,\n CAST(julianday('now') - julianday(created_at) AS INTEGER) AS days_since_lead,\n CASE WHEN strftime('%w', created_at) IN ('0','6') THEN 1 ELSE 0 END AS is_weekend\n FROM leads\n WHERE created_at >= datetime('now', '-6 months') AND (bot_score IS NULL OR bot_score < 2)\n ORDER BY RANDOM() LIMIT 2000\n `).all();\n\n const leads = leadsRes.results || [];\n if (leads.length < 50) {\n return new Response(JSON.stringify({ error: 'Dados insuficientes para clustering. M\u00EDnimo: 50 leads.', leads_found: leads.length, required: 50 }), { status: 400, headers });\n }\n\n const startTime = Date.now();\n const sample = leads.slice(0, 100);\n const profiles = sample.map(_buildLeadProfile);\n\n // Embeddings reais via embeddinggemma-300m\n const embRes = await env.AI.run('@cf/baai/bge-m3', { text: profiles });\n const vectors = (embRes as any).data as number[][];\n if (!vectors || vectors.length < nClusters) throw new Error(`embeddinggemma retornou ${vectors?.length ?? 0} vetores`);\n\n // K-means vetorial real\n const { assignments } = _kmeansRun(vectors, nClusters);\n const silhouetteScore = _silhouette(vectors, assignments, nClusters);\n\n // Agrega\u00E7\u00E3o por cluster para nomear com Granite\n const clusterStats: (ClusterStats | null)[] = Array.from({ length: nClusters }, (_, c) => {\n const members = sample.filter((_, i) => assignments[i] === c);\n if (!members.length) return null;\n const ltvMap: Record<string, number> = { High: 1, Medium: 0.5, Low: 0 };\n const avgLtv = members.reduce((s: number, l: any) => s + (ltvMap[l.predicted_ltv_class] ?? 0), 0) / members.length;\n const avgEng = members.reduce((s: number, l: any) => s + (l.engagement_score || 0), 0) / members.length;\n const avgDays = members.reduce((s: number, l: any) => s + (l.days_since_lead || 0), 0) / members.length;\n const freq = (arr: string[]) => arr.length ? [...arr.reduce((m,s) => m.set(s,(m.get(s)||0)+1), new Map())].sort((a,b)=>b[1]-a[1])[0]?.[0] : null;\n return {\n c, size: members.length, pct: Math.round(members.length / sample.length * 100),\n avgLtv, avgEng, avgDays,\n topSource: freq(members.map((l: any) => l.utm_source).filter(Boolean)) || 'direto',\n topState: freq(members.map((l: any) => l.state).filter(Boolean)) || 'BR',\n topIntent: freq(members.map((l: any) => l.intention_level).filter(Boolean)) || 'desconhecida',\n };\n }).filter(Boolean) as ClusterStats[];\n\n // Type guard function to filter null values\n function isNotNull<T>(value: T | null): value is T {\n return value !== null;\n }\n\n const validClusterStats = clusterStats.filter(isNotNull);\n\n // Granite apenas para nomear segmentos\n const namingPrompt =\n`Voc\u00EA \u00E9 especialista em segmenta\u00E7\u00E3o de clientes. D\u00EA um nome descritivo em portugu\u00EAs e uma recomenda\u00E7\u00E3o de campanha para cada segmento. Retorne SOMENTE JSON v\u00E1lido:\n{\"segments\":[{\"cluster_id\":0,\"name\":\"...\",\"action\":\"...\"},...]}\n\n${validClusterStats.map(s => `Cluster ${s.c}: LTV=${s.avgLtv.toFixed(2)}, engajamento=${s.avgEng.toFixed(0)}, inten\u00E7\u00E3o=\"${s.topIntent}\", origem=\"${s.topSource}\", estado=\"${s.topState}\", rec\u00EAncia=${s.avgDays.toFixed(0)} dias, tamanho=${s.size}`).join('\\n')}`;\n\n const nameRes = await env.AI.run('@cf/ibm-granite/granite-4.0-h-micro', { messages: [{ role: 'user', content: namingPrompt }], max_tokens: 800 });\n let clusterNames: Record<number, ClusterInfo> = {};\n try {\n const m = ((nameRes as any)?.response || '').match(/\\{[\\s\\S]*\\}/);\n if (m) {\n const parsed = JSON.parse(m[0]);\n (parsed.segments || []).forEach((s: any) => {\n if (typeof s.cluster_id === 'number') {\n clusterNames[s.cluster_id] = {\n cluster_id: s.cluster_id,\n name: s.name || `Segmento ${s.cluster_id + 1}`,\n action: s.action || '',\n };\n }\n });\n }\n } catch { /* usa nomes fallback */ }\n\n const duration = Date.now() - startTime;\n\n const clusters: Cluster[] = validClusterStats.map(s => ({\n cluster_id: s.c,\n name: clusterNames[s.c]?.name || `Segmento ${s.c + 1}`,\n size: s.size, percentage: s.pct,\n action_recommendation: clusterNames[s.c]?.action || '',\n characteristics: {\n avg_ltv_class: s.avgLtv, avg_engagement_score: s.avgEng,\n avg_intention_level: s.avgLtv, avg_days_since_lead: s.avgDays,\n dominant_countries: ['BR'], dominant_states: [s.topState || 'BR'],\n dominant_utm_sources: [s.topSource || 'direto'], top_features: ['ltv', 'engagement', 'intention'],\n },\n }));\n\n await env.DB.prepare(`UPDATE ml_segments SET is_active = 0 WHERE clustering_algorithm = ? AND client_vertical = ? AND is_active = 1`).bind(algorithm, clientVertical).run();\n\n const now = new Date().toISOString();\n for (const cluster of clusters) {\n const ch = cluster.characteristics;\n await env.DB.prepare(`\n INSERT INTO ml_segments (\n cluster_id, cluster_name, clustering_algorithm, client_vertical, size, percentage,\n avg_ltv_class, avg_behavior_score, avg_engagement_score, avg_intention_level, avg_days_since_lead,\n dominant_countries, dominant_states, dominant_utm_sources, dominant_features,\n silhouette_score, action_recommendations, bid_recommendations, campaign_recommendations,\n is_active, created_at, updated_at\n ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1,?,?)\n `).bind(\n cluster.cluster_id, cluster.name, algorithm, clientVertical, cluster.size, cluster.percentage,\n ch.avg_ltv_class, ch.avg_engagement_score, ch.avg_engagement_score, ch.avg_intention_level, ch.avg_days_since_lead,\n JSON.stringify(ch.dominant_countries), JSON.stringify(ch.dominant_states),\n JSON.stringify(ch.dominant_utm_sources), JSON.stringify(ch.top_features),\n silhouetteScore,\n JSON.stringify([cluster.action_recommendation]), JSON.stringify([]), JSON.stringify([]),\n now, now,\n ).run();\n }\n\n try {\n await env.DB.prepare(`\n INSERT INTO ml_clustering_history (clustering_id, started_at, completed_at, algorithm, n_leads_processed, n_clusters_created, total_duration_ms, workers_ai_neurons_used, status, parameters, results_summary)\n VALUES (0, ?, datetime('now'), ?, ?, ?, ?, ?, 'completed', ?, ?)\n `).bind(new Date(startTime).toISOString(), algorithm, leads.length, clusters.length, duration, Math.ceil(duration * 0.01),\n JSON.stringify({ algorithm, n_clusters: nClusters, vertical: clientVertical, engine: 'embeddinggemma-300m+kmeans' }),\n JSON.stringify({ clusters: clusters.length, silhouette: silhouetteScore }),\n ).run();\n } catch (e: any) { console.error('[Segmentation] history log error:', e?.message || String(e)); }\n\n return new Response(JSON.stringify({\n success: true, algorithm, engine: 'embeddinggemma-300m + kmeans vetorial',\n n_clusters: clusters.length, client_vertical: clientVertical,\n leads_analyzed: leads.length, sample_embedded: sample.length,\n duration_ms: duration, silhouette_score: silhouetteScore,\n clusters, generated_at: now,\n }), { status: 200, headers });\n\n } catch (err: any) {\n console.error('[Segmentation] cluster error:', err?.message || String(err));\n try {\n if (env.DB) await env.DB.prepare(`\n INSERT INTO ml_clustering_history (clustering_id, started_at, algorithm, n_leads_processed, n_clusters_created, total_duration_ms, workers_ai_neurons_used, status, error_message, parameters, results_summary)\n VALUES (0, datetime('now'), ?, 0, 0, 0, 0, 'failed', ?, ?, '{}')\n `).bind(algorithm, err?.message || String(err), JSON.stringify({ algorithm, n_clusters: nClusters })).run();\n } catch { /* n\u00E3o bloquear */ }\n return new Response(JSON.stringify({ error: 'Erro ao executar clustering', message: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/segmentation/list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleSegmentationList(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const algorithm = url.searchParams.get('algorithm') || null;\n const vertical = url.searchParams.get('vertical') || null;\n\n try {\n const conditions: string[] = ['is_active = 1'];\n const bindings: (string | number)[] = [];\n if (algorithm) { conditions.push('clustering_algorithm = ?'); bindings.push(algorithm); }\n if (vertical) { conditions.push('client_vertical = ?'); bindings.push(vertical); }\n\n const result = await env.DB.prepare(`\n SELECT id, cluster_id, cluster_name, clustering_algorithm, client_vertical,\n size, percentage, avg_ltv_class, avg_behavior_score, avg_engagement_score,\n avg_intention_level, avg_days_since_lead, silhouette_score,\n dominant_countries, dominant_states, dominant_utm_sources, dominant_features,\n action_recommendations, bid_recommendations, campaign_recommendations,\n is_active, created_at, updated_at\n FROM ml_segments\n WHERE ${conditions.join(' AND ')}\n ORDER BY created_at DESC\n LIMIT 50\n `).bind(...bindings).all();\n\n const segments = (result.results || []).map((s: any) => ({\n ...s,\n dominant_countries: tryParseJson(s.dominant_countries, []),\n dominant_states: tryParseJson(s.dominant_states, []),\n dominant_utm_sources: tryParseJson(s.dominant_utm_sources, []),\n dominant_features: tryParseJson(s.dominant_features, []),\n action_recommendations: tryParseJson(s.action_recommendations, []),\n bid_recommendations: tryParseJson(s.bid_recommendations, []),\n campaign_recommendations: tryParseJson(s.campaign_recommendations, []),\n }));\n\n return new Response(JSON.stringify({ success: true, total: segments.length, segments }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Segmentation] list error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/segmentation/outliers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleSegmentationOutliers(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'), 200);\n const days = parseInt(url.searchParams.get('days') || '30');\n\n try {\n const result = await env.DB.prepare(`\n SELECT msm.lead_id, msm.cluster_id, msm.confidence, msm.is_outlier, msm.outlier_reason, msm.assigned_at,\n l.email, l.phone, l.country, l.state, l.city, l.utm_source, l.bot_score, l.engagement_score, l.intention_level, l.created_at AS lead_created_at\n FROM ml_segment_members msm\n LEFT JOIN leads l ON CAST(msm.lead_id AS INTEGER) = l.id\n WHERE msm.is_outlier = 1 AND msm.assigned_at >= datetime('now', '-' || ? || ' days')\n ORDER BY msm.assigned_at DESC\n LIMIT ?\n `).bind(days, limit).all();\n\n return new Response(JSON.stringify({ success: true, total: (result.results || []).length, period_days: days, outliers: result.results || [] }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Segmentation] outliers error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 PUT /api/segmentation/update \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleSegmentationUpdate(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: any;\n try { body = await request.json(); }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido no body da requisi\u00E7\u00E3o' }), { status: 400, headers }); }\n\n const { cluster_id, action_recommendations, bid_recommendations, campaign_recommendations } = body;\n if (cluster_id === undefined || cluster_id === null) {\n return new Response(JSON.stringify({ error: 'cluster_id \u00E9 obrigat\u00F3rio' }), { status: 400, headers });\n }\n\n try {\n const sets: string[] = [];\n const bindings: (string | number)[] = [];\n if (action_recommendations !== undefined) { sets.push('action_recommendations = ?'); bindings.push(JSON.stringify(action_recommendations)); }\n if (bid_recommendations !== undefined) { sets.push('bid_recommendations = ?'); bindings.push(JSON.stringify(bid_recommendations)); }\n if (campaign_recommendations !== undefined) { sets.push('campaign_recommendations = ?'); bindings.push(JSON.stringify(campaign_recommendations)); }\n\n if (sets.length === 0) {\n return new Response(JSON.stringify({ error: 'Nenhum campo v\u00E1lido para atualizar (action_recommendations, bid_recommendations, campaign_recommendations)' }), { status: 400, headers });\n }\n\n sets.push(\"updated_at = datetime('now')\");\n bindings.push(cluster_id);\n\n await env.DB.prepare(`UPDATE ml_segments SET ${sets.join(', ')} WHERE id = ?`).bind(...bindings).run();\n return new Response(JSON.stringify({ success: true, cluster_id, fields_updated: sets.length - 1 }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Segmentation] update error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n", "/**\n * CDP Edge \u2014 Bidding Recommendations ML (Fase 2)\n * Handlers das rotas /api/bidding/*\n */\n\nimport { tryParseJson } from '../utils.js';\nimport { Env } from '../../types.js';\nimport { ExecutionContext } from '@cloudflare/workers-types';\n\n// \u2500\u2500 Constantes de calibra\u00E7\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst PLATFORM_FACTORS: Record<string, number> = { meta: 0.85, google: 0.90, tiktok: 0.75 };\n\nfunction getSegmentMultiplier(avgLtvClass: string | number, avgBehaviorScore: string | number): number {\n const ltv = parseFloat(String(avgLtvClass) || '0');\n const eng = parseFloat(String(avgBehaviorScore) || '0');\n if (ltv >= 0.7 && eng >= 0.7) return 1.4;\n if (ltv >= 0.7 && eng >= 0.4) return 1.2;\n if (ltv >= 0.4 && eng >= 0.7) return 1.0;\n if (ltv >= 0.4 && eng >= 0.4) return 0.8;\n return 0.6;\n}\n\nfunction getConfidenceAdjustment(confidence: number): number {\n if (confidence >= 0.7) return 1.00;\n if (confidence >= 0.4) return 0.85;\n return 0.70;\n}\n\n// \u2500\u2500 POST /api/bidding/recommend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleBiddingRecommend(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: any;\n try { body = await request.json(); }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido no body' }), { status: 400, headers }); }\n\n const {\n vertical = 'geral', platform = 'meta',\n target_roi = 3.5, period_days = 30,\n campaign_id = null, budget = null,\n } = body;\n\n const platforms = platform === 'all'\n ? Object.keys(PLATFORM_FACTORS)\n : [platform].filter(p => PLATFORM_FACTORS[p]);\n\n if (platforms.length === 0) {\n return new Response(JSON.stringify({ error: 'platform deve ser: meta, google, tiktok ou all' }), { status: 400, headers });\n }\n if (target_roi < 1 || target_roi > 20) {\n return new Response(JSON.stringify({ error: 'target_roi deve estar entre 1 e 20' }), { status: 400, headers });\n }\n\n try {\n const segmentsRes = await env.DB.prepare(`\n SELECT ms.id AS segment_id, ms.cluster_name, ms.avg_ltv_class, ms.avg_behavior_score,\n ms.avg_engagement_score, ms.silhouette_score,\n COUNT(msm.id) AS member_count,\n AVG(l.predicted_ltv) AS real_avg_ltv,\n SUM(CASE WHEN l.event_name IN ('Purchase','CompletePayment') THEN 1 ELSE 0 END) AS conversions\n FROM ml_segments ms\n LEFT JOIN ml_segment_members msm ON msm.cluster_id = ms.id\n LEFT JOIN leads l ON CAST(msm.lead_id AS INTEGER) = l.id\n AND l.created_at >= datetime('now', '-' || ? || ' days')\n WHERE ms.is_active = 1 AND ms.client_vertical IN (?, 'general')\n GROUP BY ms.id\n HAVING member_count > 0\n ORDER BY real_avg_ltv DESC\n LIMIT 10\n `).bind(period_days, vertical).all();\n\n const segments = segmentsRes.results || [];\n\n let globalLtv = 0, globalLeads = 0, globalConversions = 0;\n if (segments.length === 0) {\n const globalRes = await env.DB.prepare(`\n SELECT COUNT(*) AS total_leads, AVG(predicted_ltv) AS avg_ltv,\n SUM(CASE WHEN event_name IN ('Purchase','CompletePayment') THEN 1 ELSE 0 END) AS conversions\n FROM leads\n WHERE created_at >= datetime('now', '-' || ? || ' days')\n AND (bot_score IS NULL OR bot_score < 2)\n `).bind(period_days).first();\n\n globalLeads = Number((globalRes as any)?.total_leads) || 0;\n globalLtv = Number((globalRes as any)?.avg_ltv) || 0;\n globalConversions = Number((globalRes as any)?.conversions) || 0;\n\n if (globalLeads < 10) {\n return new Response(JSON.stringify({\n error: `Dados insuficientes. Apenas ${globalLeads} leads no per\u00EDodo de ${period_days} dias. M\u00EDnimo: 10.`,\n leads_found: globalLeads, required: 10,\n }), { status: 400, headers });\n }\n }\n\n const now = new Date().toISOString();\n const recommendations: any[] = [];\n\n const targetSegments = segments.length > 0\n ? segments\n : [{ segment_id: null, cluster_name: 'Global (sem segmenta\u00E7\u00E3o)', avg_ltv_class: 0.5, avg_behavior_score: 0.5, avg_engagement_score: 0.5, member_count: globalLeads, real_avg_ltv: globalLtv, conversions: globalConversions }];\n\n for (const seg of targetSegments) {\n const avgLtv = parseFloat(String(seg.real_avg_ltv) || '0');\n const convs = parseInt(String(seg.conversions || '0'));\n const confidence = Math.min(1, convs / 100);\n\n const estimatedLtv = avgLtv > 0 ? avgLtv :\n Number(seg.avg_ltv_class) >= 0.7 ? 497 : Number(seg.avg_ltv_class) >= 0.4 ? 297 : 97;\n\n const cpaTarget = estimatedLtv / target_roi;\n const segMult = getSegmentMultiplier(String(seg.avg_ltv_class), String(seg.avg_behavior_score));\n const confAdj = getConfidenceAdjustment(confidence);\n const alertMsg = convs < 30 ? `Aten\u00E7\u00E3o: apenas ${convs} convers\u00F5es no per\u00EDodo. Bid baseado em estimativa de LTV \u2014 aplique com cautela.` : null;\n\n for (const plat of platforms) {\n const platFactor = PLATFORM_FACTORS[plat] || 0.8;\n const recommendedBid = Math.max(5, cpaTarget * platFactor * segMult * confAdj);\n const expectedRoi = estimatedLtv / (recommendedBid / platFactor);\n\n const reasoning = `Segmento \"${seg.cluster_name}\": LTV=${estimatedLtv.toFixed(0)} BRL, ` +\n `CPA_alvo=${cpaTarget.toFixed(0)} BRL, fator_plataforma=${platFactor}, ` +\n `mult_segmento=${segMult}, ajuste_confian\u00E7a=${confAdj}, ` +\n `base: ${convs} convers\u00F5es em ${period_days} dias.`;\n\n try {\n await env.DB.prepare(`\n INSERT INTO bid_recommendations (\n generated_at, vertical, platform, period_days, target_roi,\n segment_id, segment_name, leads_analyzed, conversions_found,\n avg_ltv, cpa_target, recommended_bid, bid_currency,\n confidence, expected_roi, reasoning, ai_used, alert_message,\n platform_factor, confidence_adjustment, segment_multiplier, is_active\n ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,?,?,?,?,1)\n `).bind(\n now, vertical, plat, period_days, target_roi,\n seg.segment_id || null, seg.cluster_name,\n seg.member_count || globalLeads, convs,\n estimatedLtv, cpaTarget, recommendedBid, 'BRL',\n confidence, expectedRoi, reasoning, alertMsg || null,\n platFactor, confAdj, segMult,\n ).run();\n } catch (e: any) { console.error('[Bidding] D1 insert error:', e?.message || String(e)); }\n\n recommendations.push({\n platform: plat, segment: seg.cluster_name, segment_id: seg.segment_id || null,\n avg_ltv: Math.round(estimatedLtv * 100) / 100,\n avg_ltv_class: Number(seg.avg_ltv_class) >= 0.7 ? 'High' : Number(seg.avg_ltv_class) >= 0.4 ? 'Medium' : 'Low',\n cpa_target: Math.round(cpaTarget * 100) / 100,\n recommended_bid: Math.round(recommendedBid * 100) / 100,\n bid_currency: 'BRL', confidence: Math.round(confidence * 100) / 100,\n expected_roi: Math.round(expectedRoi * 100) / 100, reasoning, alert: alertMsg,\n });\n }\n }\n\n await env.DB.prepare(`UPDATE bid_recommendations SET is_active = 0 WHERE vertical = ? AND generated_at < ? AND is_active = 1`).bind(vertical, now).run().catch(() => {});\n\n const avgConfidence = recommendations.length > 0\n ? recommendations.reduce((s, r) => s + r.confidence, 0) / recommendations.length\n : 0;\n\n return new Response(JSON.stringify({\n success: true, generated_at: now, vertical, period_days, target_roi,\n data_quality: {\n leads_analyzed: targetSegments.reduce((s: number, sg: any) => s + (sg.member_count || 0), 0),\n conversions_found: targetSegments.reduce((s: number, sg: any) => s + (sg.conversions || 0), 0),\n segments_active: segments.length, confidence: Math.round(avgConfidence * 100) / 100,\n },\n recommendations,\n global_summary: {\n total_recommendations: recommendations.length,\n avg_confidence: Math.round(avgConfidence * 100) / 100,\n expected_cost_reduction: avgConfidence >= 0.7 ? '-20%' : avgConfidence >= 0.4 ? '-10%' : 'indefinido (dados insuficientes)',\n segments_analyzed: segments.length,\n },\n }), { status: 200, headers });\n\n } catch (err: any) {\n console.error('[Bidding] recommend error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: 'Erro ao gerar recomenda\u00E7\u00F5es', message: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/bidding/history \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleBiddingHistory(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const vertical = url.searchParams.get('vertical') || null;\n const platform = url.searchParams.get('platform') || null;\n const limit = Math.min(parseInt(url.searchParams.get('limit') || '20'), 100);\n\n try {\n const conditions: string[] = [];\n const bindings: (string | number)[] = [];\n if (vertical) { conditions.push('vertical = ?'); bindings.push(vertical); }\n if (platform) { conditions.push('platform = ?'); bindings.push(platform); }\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n const result = await env.DB.prepare(`\n SELECT id, generated_at, vertical, platform, period_days, target_roi,\n segment_name, leads_analyzed, conversions_found, avg_ltv, cpa_target,\n recommended_bid, bid_currency, confidence, expected_roi,\n reasoning, alert_message, ai_used, is_active,\n applied_at, applied_campaign, applied_result\n FROM bid_recommendations\n ${where}\n ORDER BY generated_at DESC\n LIMIT ?\n `).bind(...bindings, limit).all();\n\n const items = (result.results || []).map((r: any) => ({ ...r, applied_result: tryParseJson(r.applied_result, null) }));\n return new Response(JSON.stringify({ success: true, total: items.length, history: items }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Bidding] history error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/bidding/status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleBiddingStatus(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const vertical = url.searchParams.get('vertical') || null;\n\n try {\n let query = `\n SELECT platform, vertical, MAX(generated_at) as last_generated,\n AVG(confidence) as avg_confidence, AVG(recommended_bid) as avg_bid,\n COUNT(*) as recommendations_count,\n SUM(CASE WHEN alert_message IS NOT NULL THEN 1 ELSE 0 END) as alerts_count\n FROM bid_recommendations\n WHERE is_active = 1\n `;\n const bindings: (string | number)[] = [];\n if (vertical) { query += ' AND vertical = ?'; bindings.push(vertical); }\n query += ' GROUP BY platform, vertical ORDER BY last_generated DESC';\n\n const result = await env.DB.prepare(query).bind(...bindings).all();\n return new Response(JSON.stringify({ success: true, status: result.results || [] }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Bidding] status error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n", "/**\n * CDP Edge \u2014 Fraud Detection (Fase 4)\n * checkFraudGate, logFraudSignal, handlers das rotas /api/fraud/*\n */\n\nimport { sha256, tryParseJson } from '../utils.js';\nimport { Env, TrackPayload } from '../../types.js';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface FraudResult {\n allowed: boolean;\n score: number;\n reasons: string[];\n action: 'allowed' | 'flagged' | 'dropped';\n}\n\nexport const DATACENTER_PATTERNS = /amazon|google|microsoft|digitalocean|linode|ovh|vultr|hetzner|contabo|cloudflare|packet|rackspace|leaseweb/i;\n\n// \u2500\u2500 checkFraudGate \u2014 roda ANTES de qualquer processamento de evento \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Retorna { allowed, score, reasons, action }\n// Falhas no gate = fail-safe (deixa passar)\nexport async function checkFraudGate(env: Env, request: Request, payload: TrackPayload): Promise<FraudResult> {\n const result: FraudResult = { allowed: true, score: 0, reasons: [], action: 'allowed' };\n\n try {\n const ip = request.headers.get('CF-Connecting-IP') || '';\n const ua = request.headers.get('User-Agent') || '';\n const fingerprint = (payload as any).fingerprint || '';\n const email = payload.email || '';\n const botScore = parseInt(String(payload.botScore || (payload as any).bot_score || 0));\n const asn = String((request as any).cf?.asOrganization || '').toLowerCase();\n const country = ((request as any).cf?.country || '').toUpperCase();\n const acceptLang = request.headers.get('Accept-Language');\n\n // 1. KV blocklist check \u2014 instant\u00E2neo (~0ms)\n if (env.GEO_CACHE && ip) {\n const ipBlocked = await env.GEO_CACHE.get(`fraud_block:ip:${ip}`);\n if (ipBlocked) {\n return { allowed: false, score: 100, reasons: ['ip_blocklisted'], action: 'dropped' };\n }\n }\n if (env.GEO_CACHE && fingerprint) {\n const fpBlocked = await env.GEO_CACHE.get(`fraud_block:fp:${fingerprint}`);\n if (fpBlocked) {\n return { allowed: false, score: 100, reasons: ['fingerprint_blocklisted'], action: 'dropped' };\n }\n }\n\n // 2. Bot score\n if (botScore >= 3) { result.score += 60; result.reasons.push('bot_score_high'); }\n else if (botScore === 2) { result.score += 30; result.reasons.push('bot_score_medium'); }\n\n // 3. User-Agent suspeito\n if (/headless|phantomjs|selenium|webdriver|curl|python|scrapy|bot|crawler|spider/i.test(ua)) {\n result.score += 40; result.reasons.push('suspicious_user_agent');\n }\n\n // 4. Datacenter IP\n if (ip && DATACENTER_PATTERNS.test(asn)) {\n result.score += 35; result.reasons.push('datacenter_ip');\n }\n\n // 5. Sem Accept-Language\n if (!acceptLang) {\n result.score += 20; result.reasons.push('no_accept_language');\n }\n\n // 6. Velocity check via KV\n if (env.GEO_CACHE && ip) {\n const velKey1h = `fraud_velocity:${ip}:h`;\n const velStr = await env.GEO_CACHE.get(velKey1h);\n const vel1h = parseInt(velStr || '0') + 1;\n\n await env.GEO_CACHE.put(velKey1h, String(vel1h), { expirationTtl: 3600 });\n\n if (vel1h > 20) { result.score += 50; result.reasons.push('ip_velocity_very_high'); }\n else if (vel1h > 10) { result.score += 25; result.reasons.push('ip_velocity_high'); }\n }\n\n result.score = Math.min(100, result.score);\n\n // 8. Decis\u00E3o final\n if (result.score >= 80) {\n result.allowed = false;\n result.action = 'dropped';\n } else if (result.score >= 40) {\n result.action = 'flagged';\n }\n\n return result;\n\n } catch (err: any) {\n console.error('[Fraud] checkFraudGate error:', err?.message || String(err));\n return { allowed: true, score: 0, reasons: ['gate_error_fallback'], action: 'allowed' };\n }\n}\n\n// \u2500\u2500 logFraudSignal \u2014 persiste no D1 em background \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function logFraudSignal(env: Env, request: Request, payload: TrackPayload, fraudResult: FraudResult): Promise<void> {\n if (!env.DB || fraudResult.action === 'allowed') return;\n try {\n const ip = request.headers.get('CF-Connecting-IP') || '';\n const ua = request.headers.get('User-Agent') || '';\n const fingerprint = (payload as any).fingerprint || '';\n const botScore = parseInt(String(payload.botScore || (payload as any).bot_score || 0));\n const asn = String((request as any).cf?.asOrganization || '');\n const country = (request as any).cf?.country || '';\n const velKey1h = `fraud_velocity:${ip}:h`;\n const vel1h = env.GEO_CACHE ? parseInt(await env.GEO_CACHE.get(velKey1h) || '0') : 0;\n\n let emailHash = null;\n if (payload.email) {\n try {\n emailHash = await sha256(payload.email.trim().toLowerCase());\n } catch (err: any) {\n console.error('[Fraud] Error generating email hash:', {\n email: payload.email,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n await env.DB.prepare(`\n INSERT INTO fraud_signals (\n ip_address, fingerprint, user_id, email_hash, event_name, event_id,\n fraud_score, action_taken, reasons,\n ip_country, ip_asn, user_agent, bot_score, velocity_1h, detected_at\n ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))\n `).bind(\n ip, fingerprint || null, payload.userId || null, emailHash,\n payload.eventName || null, payload.eventId || null,\n fraudResult.score, fraudResult.action, JSON.stringify(fraudResult.reasons),\n country, asn, ua.substring(0, 255), botScore, vel1h,\n ).run();\n\n if (fraudResult.action === 'dropped' && ip) {\n await env.DB.prepare(`\n INSERT INTO fraud_alerts (alert_type, entity_type, entity_value, events_total, events_dropped, peak_score, first_seen, last_seen, top_reasons)\n VALUES ('ip_attack', 'ip', ?, 1, 1, ?, datetime('now'), datetime('now'), ?)\n ON CONFLICT(entity_type, entity_value) DO UPDATE SET\n events_total = events_total + 1,\n events_dropped = events_dropped + 1,\n peak_score = MAX(peak_score, excluded.peak_score),\n last_seen = datetime('now'),\n updated_at = datetime('now')\n `).bind(ip, fraudResult.score, JSON.stringify(fraudResult.reasons)).run().catch(() => {});\n }\n } catch (err: any) {\n console.error('[Fraud] logFraudSignal error:', err?.message || String(err));\n }\n}\n\n// \u2500\u2500 GET /api/fraud/alerts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleFraudAlerts(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n const url = new URL(request.url);\n const action = url.searchParams.get('action') || null;\n const hours = parseInt(url.searchParams.get('hours') || '24');\n const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'), 200);\n\n try {\n const cond = action ? 'AND action_taken = ?' : '';\n const bindings = action ? [hours, action, limit] : [hours, limit];\n\n const result = await env.DB.prepare(`\n SELECT ip_address, fingerprint, event_name, fraud_score, action_taken,\n reasons, ip_country, ip_asn, bot_score, velocity_1h, detected_at\n FROM fraud_signals\n WHERE detected_at >= datetime('now', '-' || ? || ' hours')\n ${cond}\n ORDER BY fraud_score DESC, detected_at DESC\n LIMIT ?\n `).bind(...bindings).all();\n\n const signals = (result.results || []).map((s: any) => ({ ...s, reasons: tryParseJson(s.reasons, []) }));\n const stats = await env.DB.prepare(`SELECT * FROM v_fraud_dashboard`).first().catch(() => null);\n\n return new Response(JSON.stringify({ success: true, period_hours: hours, total: signals.length, stats, alerts: signals }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Fraud] alerts error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/fraud/blocklist \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleFraudBlocklist(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n try {\n const result = await env.DB.prepare(`\n SELECT entity_type, entity_value, events_total, events_dropped,\n peak_score, first_seen, last_seen, blocked_at, block_expires, top_reasons\n FROM fraud_alerts WHERE is_blocked = 1 ORDER BY events_dropped DESC LIMIT 100\n `).all();\n\n const blocklist = (result.results || []).map((r: any) => ({ ...r, top_reasons: tryParseJson(r.top_reasons, []) }));\n return new Response(JSON.stringify({ success: true, total: blocklist.length, blocklist }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Fraud] blocklist error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 POST /api/fraud/blocklist/add \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleFraudBlocklistAdd(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: any;\n try { body = await request.json(); }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido' }), { status: 400, headers }); }\n\n const { entity_type, entity_value, ttl_hours = 24, reason = 'manual_block' } = body;\n if (!entity_type || !entity_value) {\n return new Response(JSON.stringify({ error: 'entity_type (ip|fingerprint) e entity_value s\u00E3o obrigat\u00F3rios' }), { status: 400, headers });\n }\n if (!['ip', 'fingerprint'].includes(entity_type)) {\n return new Response(JSON.stringify({ error: 'entity_type deve ser: ip ou fingerprint' }), { status: 400, headers });\n }\n\n try {\n const kvKey = `fraud_block:${entity_type}:${entity_value}`;\n const ttlSec = Math.min(ttl_hours * 3600, 7 * 24 * 3600);\n const expiresAt = new Date(Date.now() + ttlSec * 1000).toISOString();\n\n if (env.GEO_CACHE) {\n await env.GEO_CACHE.put(kvKey, JSON.stringify({ reason, blocked_at: new Date().toISOString() }), { expirationTtl: ttlSec });\n }\n\n await env.DB.prepare(`\n INSERT INTO fraud_alerts (alert_type, entity_type, entity_value, events_total, events_dropped, peak_score, first_seen, last_seen, is_blocked, blocked_at, block_expires, top_reasons)\n VALUES ('manual', ?, ?, 0, 0, 100, datetime('now'), datetime('now'), 1, datetime('now'), ?, ?)\n ON CONFLICT DO UPDATE SET is_blocked = 1, blocked_at = datetime('now'), block_expires = excluded.block_expires, updated_at = datetime('now')\n `).bind(entity_type, entity_value, expiresAt, JSON.stringify([reason])).run().catch(() => {});\n\n return new Response(JSON.stringify({\n success: true, entity_type, entity_value, kv_key: kvKey, ttl_hours, expires_at: expiresAt,\n message: `${entity_type} '${entity_value}' bloqueado por ${ttl_hours}h. Efeito imediato via KV.`,\n }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Fraud] blocklist add error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 DELETE /api/fraud/blocklist/remove \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleFraudBlocklistRemove(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n let body: any;\n try { body = await request.json(); }\n catch { return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido' }), { status: 400, headers }); }\n\n const { entity_type, entity_value } = body;\n if (!entity_type || !entity_value) {\n return new Response(JSON.stringify({ error: 'entity_type e entity_value s\u00E3o obrigat\u00F3rios' }), { status: 400, headers });\n }\n\n try {\n const kvKey = `fraud_block:${entity_type}:${entity_value}`;\n if (env.GEO_CACHE) await env.GEO_CACHE.delete(kvKey);\n await env.DB.prepare(`UPDATE fraud_alerts SET is_blocked = 0, resolved_at = datetime('now'), resolved_by = 'manual' WHERE entity_type = ? AND entity_value = ?`).bind(entity_type, entity_value).run();\n\n return new Response(JSON.stringify({\n success: true, entity_type, entity_value,\n message: `${entity_type} '${entity_value}' removido do blocklist. Efeito imediato via KV.`,\n }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Fraud] blocklist remove error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n\n// \u2500\u2500 GET /api/fraud/stats \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function handleFraudStats(env: Env, request: Request, headers: Headers): Promise<Response> {\n if (!env.DB) return new Response(JSON.stringify({ error: 'DB n\u00E3o configurado' }), { status: 503, headers });\n\n try {\n const dashboard = await env.DB.prepare(`SELECT * FROM v_fraud_dashboard`).first();\n const topIps = await env.DB.prepare(`\n SELECT ip_address, COUNT(*) as events, MAX(fraud_score) as peak_score\n FROM fraud_signals\n WHERE detected_at >= datetime('now', '-24 hours') AND action_taken = 'dropped'\n GROUP BY ip_address ORDER BY events DESC LIMIT 10\n `).all();\n const topReasons = await env.DB.prepare(`\n SELECT action_taken, COUNT(*) as count FROM fraud_signals\n WHERE detected_at >= datetime('now', '-24 hours')\n GROUP BY action_taken\n `).all();\n\n return new Response(JSON.stringify({\n success: true, period: '24h', dashboard,\n top_attacking_ips: topIps.results || [],\n by_action: topReasons.results || [],\n }), { status: 200, headers });\n } catch (err: any) {\n console.error('[Fraud] stats error:', err?.message || String(err));\n return new Response(JSON.stringify({ error: err?.message || String(err) }), { status: 500, headers });\n }\n}\n", "/**\n * CDP Edge \u2014 Intelligence Agent + Customer Match\n * runIntelligenceAgent, customer match Meta/Google, health checks\n */\n\nimport { sha256 } from './utils.js';\nimport { getHealthMetrics, generateDailyReport, logIntelligence } from './db.js';\nimport { sendCallMeBot } from './dispatch/whatsapp.js';\nimport { autoDecideAbWinner } from './ml/ltv.js';\nimport { analyzeMatchQuality, alertMatchQuality, purgeOldMatchQualityLogs } from './ml/matchquality.js';\nimport { trainLogisticRegression, extractFeatures, saveWeights, LTV_WEIGHTS_KV_KEY } from './ml/logistic.js';\nimport { Env } from '../types.js';\n\n// \u2500\u2500 Tipos \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface ApiVersionCheck {\n platform: string;\n current: string;\n expected: string;\n status: 'ok' | 'warning';\n}\n\nexport interface ErrorRateAlert {\n platform: string;\n errorRate: number;\n status: 'ok' | 'warning' | 'critical';\n}\n\nexport interface LtvTrainResult {\n trained?: boolean;\n skipped?: string;\n samples?: number;\n accuracy?: number;\n positiveRate?: number;\n error?: string;\n}\n\nexport interface IntelligenceAgentResult {\n versionResults: ApiVersionCheck[];\n errorAlerts: ErrorRateAlert[];\n ltvTrainResult: LtvTrainResult;\n abResult?: {\n decided: boolean;\n test_id?: number;\n winner_name?: string;\n improvement?: number;\n };\n mqAnalysis?: {\n total?: number;\n composite_score?: number;\n email_rate?: number;\n fbp_rate?: number;\n alerts?: any[];\n };\n cmResult?: {\n sent?: number;\n received?: number;\n skipped?: string;\n error?: string;\n };\n}\n\nexport interface CustomerMatchResult {\n sent?: number;\n received?: number;\n num_received?: number;\n skipped?: string;\n error?: string;\n}\n\nexport interface GoogleCustomerMatchExport {\n hashed_email: string;\n hashed_phone: string;\n first_name: string;\n last_name: string;\n}\n\n// \u2500\u2500 Vers\u00F5es esperadas das APIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst EXPECTED_API_VERSIONS: Record<string, string> = {\n meta: 'v22.0',\n ga4: 'latest',\n tiktok: 'v1.3',\n pinterest: 'v5',\n reddit: 'v2.0',\n};\n\nconst ALERT_THRESHOLDS = {\n errorRateCritical: 0.20,\n errorRateWarning: 0.10,\n};\n\n// \u2500\u2500 Alerta via CallMeBot \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function sendIntelligenceAlert(\n env: Env,\n severity: 'critical' | 'warning' | 'info',\n title: string,\n details: string\n): Promise<void> {\n const icon = severity === 'critical' ? '\uD83D\uDEA8' : severity === 'warning' ? '\u26A0\uFE0F' : '\u2139\uFE0F';\n const texto = `${icon} CDP Edge \u2014 ${title}\\n\\n${details}\\n\\n${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })}`;\n return sendCallMeBot(env, texto);\n}\n\n// \u2500\u2500 Check de vers\u00F5es de API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function checkApiVersionsIntelligence(\n env: Env,\n runType: string\n): Promise<ApiVersionCheck[]> {\n const results: ApiVersionCheck[] = [];\n\n for (const [platform, expected] of Object.entries(EXPECTED_API_VERSIONS)) {\n const currentMap: Record<string, string> = { meta: 'v22.0', tiktok: 'v1.3', ga4: 'latest', pinterest: 'v5', reddit: 'v2.0' };\n const current = currentMap[platform] || 'unknown';\n const isOk = current === expected || expected === 'latest';\n const status = isOk ? 'ok' : 'warning';\n\n if (env.DB) {\n await logIntelligence(env.DB, runType, platform, 'api_version', status, current, expected,\n isOk ? `${platform} ${current} \u2014 vers\u00E3o correta` : `${platform} ${current} desatualizado, esperado ${expected}`\n );\n }\n\n results.push({ platform, current, expected, status });\n }\n\n return results;\n}\n\n// \u2500\u2500 Auditoria de taxa de erro \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function auditErrorRates(\n env: Env,\n runType: string\n): Promise<ErrorRateAlert[]> {\n if (!env.DB) return [];\n const alerts: ErrorRateAlert[] = [];\n\n for (const platform of ['meta', 'ga4', 'tiktok']) {\n const metrics = await getHealthMetrics(env.DB, platform, 24);\n const errorRate = metrics.events_sent > 0 ? metrics.events_failed / metrics.events_sent : 0;\n\n let status: 'ok' | 'warning' | 'critical' = 'ok';\n if (errorRate >= ALERT_THRESHOLDS.errorRateCritical) status = 'critical';\n else if (errorRate >= ALERT_THRESHOLDS.errorRateWarning) status = 'warning';\n\n const message = `${platform}: ${metrics.events_sent} eventos, ${metrics.events_failed} falhas (${(errorRate * 100).toFixed(1)}%)`;\n let alertSent: boolean | undefined = false;\n if (status !== 'ok') {\n await sendIntelligenceAlert(env, status, `Taxa de Erro Alta \u2014 ${platform.toUpperCase()}`,\n `\uD83D\uDCCA ${message}\\n\uD83C\uDFAF Taxa: ${(errorRate * 100).toFixed(1)}% (limite: ${ALERT_THRESHOLDS.errorRateWarning * 100}%)`);\n alertSent = true;\n }\n\n if (env.DB) {\n await logIntelligence(env.DB, runType, platform, 'error_rate', status,\n `${(errorRate * 100).toFixed(1)}%`, `${ALERT_THRESHOLDS.errorRateWarning * 100}%`, message, alertSent\n );\n }\n\n if (status !== 'ok') alerts.push({ platform, errorRate, status });\n }\n\n return alerts;\n}\n\n// \u2500\u2500 Treinar modelo LTV (regress\u00E3o log\u00EDstica com dados reais do D1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function trainLtvModel(env: Env): Promise<LtvTrainResult> {\n if (!env.DB) return { skipped: 'DB n\u00E3o dispon\u00EDvel' };\n\n try {\n // Busca leads com informa\u00E7\u00E3o de convers\u00E3o (compra confirmada)\n const rows = await env.DB.prepare(`\n SELECT\n l.utm_source,\n l.utm_medium,\n l.engagement_score,\n l.intention_level,\n CAST(julianday('now') - julianday(l.created_at) AS INTEGER) AS days_since_lead,\n CASE WHEN l.email IS NOT NULL AND l.email != '' THEN 1 ELSE 0 END AS has_email,\n CASE WHEN l.phone IS NOT NULL AND l.phone != '' THEN 1 ELSE 0 END AS has_phone,\n CASE WHEN (l.country = 'br' OR l.country = 'BR' OR l.country IS NULL) THEN 1 ELSE 0 END AS is_br,\n CAST(strftime('%H', l.created_at) AS INTEGER) AS hour,\n CASE WHEN EXISTS (\n SELECT 1 FROM events e\n WHERE e.user_id = l.user_id\n AND e.event_name IN ('Purchase', 'purchase', 'PURCHASE')\n AND e.created_at > l.created_at\n ) THEN 1 ELSE 0 END AS label\n FROM leads l\n WHERE l.created_at >= datetime('now', '-90 days')\n LIMIT 5000\n `).all();\n\n const dataset = (rows.results || []).map((row: any) => ({\n features: extractFeatures(row),\n label: row.label || 0,\n }));\n\n const model = trainLogisticRegression(dataset);\n\n if (!model) {\n console.log('[LTV Train] Dados insuficientes para treinar modelo');\n return { skipped: 'dados insuficientes', samples: dataset.length };\n }\n\n await saveWeights(env.DB, model);\n\n // Invalidar cache KV para que pr\u00F3ximas requests carreguem o modelo novo\n if (env.GEO_CACHE) {\n env.GEO_CACHE.delete(LTV_WEIGHTS_KV_KEY).catch(() => {});\n }\n\n console.log(`[LTV Train] Modelo treinado: ${dataset.length} samples, accuracy=${(model.accuracy * 100).toFixed(1)}%, positive_rate=${(model.positiveRate * 100).toFixed(1)}%`);\n return { trained: true, samples: dataset.length, accuracy: model.accuracy, positiveRate: model.positiveRate };\n\n } catch (err: any) {\n console.error('[LTV Train] Erro:', err?.message || String(err));\n return { error: err?.message || String(err) };\n }\n}\n\n// \u2500\u2500 Runner principal do Intelligence Agent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function runIntelligenceAgent(\n env: Env,\n runType: string\n): Promise<IntelligenceAgentResult> {\n console.log(`[Intelligence Agent] Iniciando ${runType}`);\n\n // 1. Check de vers\u00F5es\n const versionResults = await checkApiVersionsIntelligence(env, runType);\n console.log(`[Intelligence Agent] Vers\u00F5es verificadas: ${versionResults.length} plataformas`);\n\n // 2. Relat\u00F3rio di\u00E1rio\n if (env.DB) {\n const reports = await generateDailyReport(env.DB);\n console.log(`[Intelligence Agent] Relat\u00F3rios gerados: ${reports.length}`);\n }\n\n // 3. Auditoria de taxas de erro\n const errorAlerts = await auditErrorRates(env, runType);\n if (errorAlerts.length > 0) {\n console.warn(`[Intelligence Agent] ${errorAlerts.length} alertas de taxa de erro enviados`);\n }\n\n // 4. Treinar modelo LTV (toda semana)\n const ltvTrainResult = await trainLtvModel(env);\n if (ltvTrainResult.trained) {\n console.log(`[Intelligence Agent] LTV model treinado: accuracy=${(ltvTrainResult.accuracy! * 100).toFixed(1)}%`);\n if (env.DB) {\n await logIntelligence(env.DB, runType, 'ltv', 'model_training', 'ok',\n `accuracy=${(ltvTrainResult.accuracy! * 100).toFixed(1)}%`, null,\n `Modelo LTV re-treinado com ${ltvTrainResult.samples} amostras`\n ).catch(() => {});\n }\n } else {\n console.log(`[Intelligence Agent] LTV model: ${ltvTrainResult.skipped || ltvTrainResult.error || 'sem dados'}`);\n }\n\n // 5. Auto-decis\u00E3o de winner no A/B LTV Test\n let abResult: IntelligenceAgentResult['abResult'] = undefined;\n try {\n const abRes = await autoDecideAbWinner(env);\n if (abRes?.decided) {\n abResult = {\n decided: abRes.decided,\n test_id: abRes.test_id,\n winner_name: abRes.winner_name,\n improvement: abRes.improvement ? parseFloat(abRes.improvement) : undefined,\n };\n console.log(`[Intelligence Agent] A/B LTV winner auto-decidido: test_id=${abResult.test_id}, winner=${abResult.winner_name}`);\n\n await sendIntelligenceAlert(env, 'info',\n `A/B LTV Test \u2014 Winner Declarado Automaticamente`,\n `\uD83C\uDFC6 Vencedor: ${abResult.winner_name}\\n\uD83D\uDCC8 Melhoria: +${abResult.improvement?.toFixed(1) ?? '?'}pp vs controle\\n\uD83C\uDD94 Test ID: ${abResult.test_id}\\n\\n\u2705 Prompt vencedor ativado automaticamente`\n );\n\n if (env.DB) {\n await logIntelligence(env.DB, runType, 'ltv', 'ab_auto_winner', 'ok',\n abResult.winner_name, null,\n `A/B winner auto-decidido: test ${abResult.test_id}, melhoria ${abResult.improvement?.toFixed(1)}pp`\n ).catch(() => {});\n }\n }\n } catch (err: any) {\n console.error('[Intelligence Agent] A/B auto-decide error:', err?.message || String(err));\n }\n\n // 6. Match Quality \u2014 an\u00E1lise + alertas\n let mqAnalysis: IntelligenceAgentResult['mqAnalysis'] = undefined;\n try {\n const mqRes = await analyzeMatchQuality(env);\n if (mqRes) {\n mqAnalysis = mqRes;\n console.log(`[Intelligence Agent] Match Quality: score=${mqAnalysis.composite_score ?? 0}%, alerts=${mqAnalysis.alerts?.length ?? 0}`);\n await alertMatchQuality(env, mqRes);\n\n if (env.DB && mqAnalysis.total && mqAnalysis.total > 0) {\n await logIntelligence(env.DB, runType, 'meta', 'match_quality', (mqAnalysis.alerts && mqAnalysis.alerts.length > 0) ? 'warning' : 'ok',\n `${mqAnalysis.composite_score ?? 0}%`, '45%',\n `Match quality 2h: email=${mqAnalysis.email_rate ?? 0}%, fbp=${mqAnalysis.fbp_rate ?? 0}%, score=${mqAnalysis.composite_score ?? 0}%`\n ).catch(() => {});\n }\n }\n } catch (err: any) {\n console.error('[Intelligence Agent] Match quality analysis error:', err?.message || String(err));\n }\n\n // 7. Auditoria mensal adicional\n if (runType === 'monthly_audit') {\n if (env.DB) {\n try {\n const ltvStats = await env.DB.prepare(`\n SELECT predicted_ltv_class, COUNT(*) as count\n FROM user_profiles\n WHERE predicted_ltv_class IS NOT NULL AND updated_at > datetime('now', '-30 days')\n GROUP BY predicted_ltv_class\n `).all();\n\n const summary = ltvStats.results?.map((r: any) => `${r.predicted_ltv_class}: ${r.count}`).join(', ') || 'sem dados';\n await logIntelligence(env.DB, runType, 'all', 'ltv_distribution', 'ok', summary, null,\n `Distribui\u00E7\u00E3o LTV \u00FAltimos 30 dias: ${summary}`);\n console.log(`[Intelligence Agent] LTV distribution: ${summary}`);\n } catch (err: any) {\n console.error('LTV audit error:', err?.message || String(err));\n }\n\n // Purge de logs antigos de match quality (> 30 dias)\n if (env.DB) {\n await purgeOldMatchQualityLogs(env.DB);\n console.log('[Intelligence Agent] Match quality logs antigos purgados');\n }\n }\n }\n\n // 8. Customer Match sync semanal\n const cmResult = await syncMetaCustomAudience(env);\n console.log(`[Intelligence Agent] Customer Match Meta: sent=${cmResult?.sent ?? 0}, received=${cmResult?.received ?? 0}`);\n\n console.log(`[Intelligence Agent] ${runType} conclu\u00EDdo \u2014 LTV model, A/B auto-decide, match quality, customer match`);\n\n return {\n versionResults,\n errorAlerts,\n ltvTrainResult,\n abResult,\n mqAnalysis,\n cmResult,\n };\n}\n\n// \u2500\u2500 syncMetaCustomAudience \u2014 D1 \u2192 Meta Custom Audiences \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function syncMetaCustomAudience(env: Env): Promise<CustomerMatchResult> {\n if (!env.META_ACCESS_TOKEN || !env.META_AD_ACCOUNT_ID || !env.META_AUDIENCE_ID) {\n console.log('[CustomerMatch] Meta: secrets n\u00E3o configurados \u2014 pulando sync');\n return { skipped: 'META_AD_ACCOUNT_ID ou META_AUDIENCE_ID n\u00E3o configurados' };\n }\n if (!env.DB) return { skipped: 'DB n\u00E3o dispon\u00EDvel' };\n\n try {\n const profiles = await env.DB.prepare(`\n SELECT email, phone FROM user_profiles\n WHERE cohort_label IN ('high_intent', 'buyer_lookalike')\n AND updated_at > datetime('now', '-30 days')\n AND email IS NOT NULL\n LIMIT 10000\n `).all();\n\n if (!profiles.results || profiles.results.length === 0) {\n console.log('[CustomerMatch] Meta: nenhum perfil eleg\u00EDvel');\n return { sent: 0 };\n }\n\n const data = await Promise.all(\n profiles.results.map(async (p: any) => [\n p.email ? await sha256(p.email) : '',\n p.phone ? await sha256(p.phone) : '',\n ])\n );\n\n const body = { payload: { schema: ['EMAIL_SHA256', 'PHONE_SHA256'], data } };\n const endpoint = `https://graph.facebook.com/v22.0/${env.META_AUDIENCE_ID}/users`;\n\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ ...body, access_token: env.META_ACCESS_TOKEN }),\n });\n\n const result = await res.json() as any;\n\n if (!res.ok) {\n console.error('[CustomerMatch] Meta erro:', res.status, result.error?.message || 'unknown');\n return { error: result.error?.message, sent: 0 };\n }\n\n console.log(`[CustomerMatch] Meta: ${profiles.results.length} perfis sincronizados`);\n return { sent: profiles.results.length, num_received: result.num_received, received: result.num_received };\n\n } catch (err: any) {\n console.error('[CustomerMatch] Meta fetch error:', err?.message || String(err));\n return { error: err?.message || String(err), sent: 0 };\n }\n}\n\n// \u2500\u2500 buildGoogleCustomerMatchExport \u2014 gera JSON para Google Ads Customer Match \u2500\nexport async function buildGoogleCustomerMatchExport(env: Env): Promise<GoogleCustomerMatchExport[]> {\n if (!env.DB) return [];\n\n const profiles = await env.DB.prepare(`\n SELECT email, phone, first_name, last_name FROM user_profiles\n WHERE cohort_label IN ('high_intent', 'buyer_lookalike')\n AND updated_at > datetime('now', '-30 days')\n AND email IS NOT NULL\n LIMIT 10000\n `).all();\n\n if (!profiles.results?.length) return [];\n\n const results: GoogleCustomerMatchExport[] = [];\n for (const p of profiles.results) {\n const email = p.email as string | null | undefined;\n const phone = p.phone as string | null | undefined;\n const firstName = p.first_name as string | undefined;\n const lastName = p.last_name as string | undefined;\n\n const hashed_email = email ? await sha256(email) : '';\n const hashed_phone = phone ? await sha256(phone) : '';\n if (hashed_email || hashed_phone) {\n results.push({\n hashed_email: hashed_email || '',\n hashed_phone: hashed_phone || '',\n first_name: firstName || '',\n last_name: lastName || '',\n });\n }\n }\n return results;\n}\n", "/**\n * CDP Edge \u2014 index.ts (ES Module Entry Point)\n *\n * Este arquivo \u00E9 o novo entry point modular do Worker.\n * Para us\u00E1-lo, altere em wrangler.toml:\n * main = \"worker.js\" \u2192 main = \"index.ts\"\n *\n * O worker.js original permanece intacto como fallback.\n * Todos os m\u00F3dulos ficam em ./modules/\n */\n\nimport { ExecutionContext } from '@cloudflare/workers-types';\nimport { Env, TrackPayload, BehavioralData, HotmartWebhook, KiwifyWebhook, TictoWebhook } from './types';\n\n// \u2500\u2500 Utilit\u00E1rios base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n corsHeaders,\n sha256,\n META_TO_GA4,\n VALID_EVENT_NAMES,\n resolveFunnelStage,\n resolveIntentScore,\n distanceBucketWeight,\n computeMetaSignalWeights,\n metaSignalBucket,\n isValidEmail,\n sanitizeString,\n isValidUrl,\n isValidValue,\n isValidCurrency,\n isValidUTM,\n} from './modules/utils';\n\n// \u2500\u2500 Banco de dados (D1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n saveLead,\n upsertProfile,\n resolveDeviceGraph,\n fireAutomation,\n getProfileByEmail,\n enrichGeoFromEdge,\n writeAuditLog,\n generateEdgeFingerprint,\n saveEdgeFingerprint,\n resurrectUTM,\n upsertLtvProfile,\n recordLtvFeedback,\n processWebhookDuplicateCheck,\n} from './modules/db';\n\n// \u2500\u2500 Dispatch \u2014 plataformas de ads \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport { sendMetaCapi } from './modules/dispatch/meta';\nimport { sendGA4Mp } from './modules/dispatch/ga4';\nimport { sendTikTokApi } from './modules/dispatch/tiktok';\nimport {\n sendPinterestCapi,\n sendRedditCapi,\n sendLinkedInCapi,\n sendSpotifyCapi,\n} from './modules/dispatch/platforms';\nimport {\n sendWhatsApp,\n processWhatsAppWebhook,\n verifyHmac,\n} from './modules/dispatch/whatsapp';\n\n// \u2500\u2500 ML \u2014 LTV + A/B Testing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n predictLtv,\n getLtvAbVariation,\n recordAbAssignment,\n handleLtvAbTestCreate,\n handleLtvAbTestList,\n handleLtvAbTestResults,\n handleLtvAbTestWinner,\n} from './modules/ml/ltv';\n\n// \u2500\u2500 ML \u2014 Segmenta\u00E7\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n handleSegmentationCluster,\n handleSegmentationList,\n handleSegmentationOutliers,\n handleSegmentationUpdate,\n} from './modules/ml/segmentation';\n\n// \u2500\u2500 ML \u2014 Bidding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n handleBiddingRecommend,\n handleBiddingHistory,\n handleBiddingStatus,\n} from './modules/ml/bidding';\n\n// \u2500\u2500 ML \u2014 Fraud Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n checkFraudGate,\n logFraudSignal,\n handleFraudAlerts,\n handleFraudBlocklist,\n handleFraudBlocklistAdd,\n handleFraudBlocklistRemove,\n handleFraudStats,\n} from './modules/ml/fraud';\n\n// \u2500\u2500 Intelligence Agent (Cron) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport {\n runIntelligenceAgent,\n buildGoogleCustomerMatchExport,\n} from './modules/intelligence';\n\n// \u2500\u2500 Haversine distance (km) \u2014 sem depend\u00EAncia externa \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction haversineKm(lat1: number | string | null | undefined, lon1: number | string | null | undefined, lat2: number | string | null | undefined, lon2: number | string | null | undefined): number {\n const R = 6371;\n const lat1Num = parseFloat(String(lat1 ?? '0'));\n const lon1Num = parseFloat(String(lon1 ?? '0'));\n const lat2Num = parseFloat(String(lat2 ?? '0'));\n const lon2Num = parseFloat(String(lon2 ?? '0'));\n const dLat = (lat2Num - lat1Num) * Math.PI / 180;\n const dLon = (lon2Num - lon1Num) * Math.PI / 180;\n const a = Math.sin(dLat / 2) ** 2 +\n Math.cos(lat1Num * Math.PI / 180) * Math.cos(lat2Num * Math.PI / 180) * Math.sin(dLon / 2) ** 2;\n return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// HANDLER PRINCIPAL\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport default {\n\n async fetch(request: Request, env: Env, ctx: ExecutionContext) {\n const origin = request.headers.get('Origin') || '';\n const headersObj = {\n 'Content-Type': 'application/json',\n ...corsHeaders(origin, env.SITE_DOMAIN || null),\n };\n const headers = new Headers(headersObj);\n\n // Preflight CORS\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 204, headers });\n }\n\n const url = new URL(request.url);\n\n // \u2500\u2500 Rate Limiter \u2014 camada 0, antes do Fraud Gate \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Usa apenas CF-Connecting-IP (injetado pela Cloudflare, n\u00E3o pode ser spoofado)\n // X-Forwarded-For pode ser falsificado por atacantes para bypass rate limiter\n if (url.pathname === '/track' && request.method === 'POST' && env.RATE_LIMITER) {\n const ip = request.headers.get('CF-Connecting-IP') || 'unknown';\n const { success } = await env.RATE_LIMITER.limit({ key: ip });\n if (!success) {\n return new Response(JSON.stringify({ status: 'ok', queued: true }), { status: 200, headers });\n }\n }\n\n // \u2500\u2500 Fraud Gate \u2014 Fase 4 (apenas em /track) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Roda ANTES de qualquer processamento de evento\n // Silent drop (200) \u2014 bots n\u00E3o sabem que foram detectados\n if (url.pathname === '/track' && request.method === 'POST') {\n let trackBodyForFraud: TrackPayload = {};\n try {\n const cloned = request.clone();\n trackBodyForFraud = await cloned.json().catch(() => ({})) as TrackPayload;\n } catch { trackBodyForFraud = {}; }\n\n const fraudResult = await checkFraudGate(env, request, trackBodyForFraud);\n if (!fraudResult.allowed) {\n ctx.waitUntil(logFraudSignal(env, request, trackBodyForFraud, fraudResult));\n return new Response(JSON.stringify({ status: 'ok', queued: true }), { status: 200, headers });\n }\n if (fraudResult.action === 'flagged') {\n ctx.waitUntil(logFraudSignal(env, request, trackBodyForFraud, fraudResult));\n }\n }\n\n // \u2500\u2500 GET /export/customer-match \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'GET' && url.pathname === '/export/customer-match') {\n const authHeader = request.headers.get('Authorization') || '';\n const token = authHeader.replace('Bearer ', '');\n if (!env.META_ACCESS_TOKEN || token !== env.META_ACCESS_TOKEN) {\n return new Response('Unauthorized', { status: 401 });\n }\n\n const rows = await buildGoogleCustomerMatchExport(env);\n return new Response(JSON.stringify({ total: rows.length, data: rows }, null, 2), {\n headers: { ...headers, 'Content-Disposition': 'attachment; filename=\"customer-match.json\"' },\n });\n }\n\n // \u2500\u2500 GET /health \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'GET' && url.pathname === '/health') {\n const results: Record<string, string> = {};\n\n try {\n await env.DB?.prepare('SELECT 1').run();\n results.d1 = 'ok';\n } catch (err: any) {\n results.d1 = `FAILED: ${err?.message || String(err)}`;\n }\n\n try {\n await env.GEO_CACHE?.get('__health_check__');\n results.kv = 'ok';\n } catch (err: any) {\n results.kv = `FAILED: ${err?.message || String(err)}`;\n }\n\n try {\n await env.AI?.run('@cf/ibm-granite/granite-4.0-h-micro', {\n messages: [{ role: 'user', content: 'ping' }],\n max_tokens: 1,\n });\n results.ai = 'ok';\n } catch (err: any) {\n results.ai = `FAILED: ${err?.message || String(err)}`;\n }\n\n const vars = {\n META_PIXEL_ID: env.META_PIXEL_ID ? 'set' : 'MISSING',\n GA4_MEASUREMENT_ID: env.GA4_MEASUREMENT_ID ? 'set' : 'MISSING',\n TIKTOK_PIXEL_ID: env.TIKTOK_PIXEL_ID ? 'set' : 'MISSING',\n SITE_DOMAIN: env.SITE_DOMAIN ? 'set' : 'MISSING',\n };\n\n const secrets = {\n META_ACCESS_TOKEN: env.META_ACCESS_TOKEN ? 'set' : 'MISSING',\n GA4_API_SECRET: env.GA4_API_SECRET ? 'set' : 'MISSING',\n WA_WEBHOOK_VERIFY_TOKEN: env.WA_WEBHOOK_VERIFY_TOKEN ? 'set' : 'MISSING',\n WHATSAPP_ACCESS_TOKEN: (env.WHATSAPP_ACCESS_TOKEN || env.WA_ACCESS_TOKEN) ? 'set' : 'not set (optional - only for auto-reply)',\n WHATSAPP_PHONE_NUMBER_ID: (env.WHATSAPP_PHONE_NUMBER_ID || env.WA_PHONE_ID) ? 'set' : 'not set (optional - only for auto-reply)',\n WA_NOTIFY_NUMBER: env.WA_NOTIFY_NUMBER ? 'set' : 'not set (optional - only for auto-reply)',\n TIKTOK_ACCESS_TOKEN: env.TIKTOK_ACCESS_TOKEN ? 'set' : 'not set (optional)',\n CALLMEBOT_PHONE: env.CALLMEBOT_PHONE ? 'set' : 'not set (optional)',\n };\n\n const hasMissing =\n Object.values(vars).includes('MISSING') ||\n Object.values(secrets).includes('MISSING') ||\n results.d1 !== 'ok';\n\n return new Response(JSON.stringify({\n status: hasMissing ? 'degraded' : 'ok',\n timestamp: new Date().toISOString(),\n bindings: results,\n vars,\n secrets,\n }, null, 2), { headers });\n }\n\n // \u2500\u2500 POST /track \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'POST' && url.pathname === '/track') {\n // Reject oversized payloads before reading body (64 KB limit)\n const contentLength = parseInt(request.headers.get('Content-Length') || '0', 10);\n if (contentLength > 65536) {\n return new Response(JSON.stringify({ error: 'Payload muito grande' }), { status: 413, headers });\n }\n\n let body;\n try {\n body = await request.json();\n } catch {\n return new Response(JSON.stringify({ error: 'JSON inv\u00E1lido' }), { status: 400, headers });\n }\n\n if (typeof body !== 'object' || Array.isArray(body) || body === null) {\n return new Response(JSON.stringify({ error: 'Payload inv\u00E1lido' }), { status: 400, headers });\n }\n\n const STR_FIELDS = ['email','phone','firstName','lastName','city','state','zip','userId',\n 'utmSource','utmMedium','utmCampaign','utmContent','utmTerm',\n 'fbclid','ttclid','gclid','transactionId','productName','currency'];\n\n const { eventName, behavioral_data, ...payload } = body as { eventName?: string; behavioral_data?: BehavioralData; [key: string]: any };\n const trackPayload: TrackPayload = payload;\n\n // \u2500\u2500 Valida\u00E7\u00E3o de eventName \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!eventName) {\n return new Response(JSON.stringify({ error: 'eventName \u00E9 obrigat\u00F3rio' }), { status: 400, headers });\n }\n\n if (typeof eventName !== 'string' || eventName.length > 64 || !VALID_EVENT_NAMES.has(eventName)) {\n return new Response(JSON.stringify({ error: `eventName desconhecido: ${eventName.slice(0, 64)}` }), { status: 400, headers });\n }\n\n // \u2500\u2500 Sanitiza\u00E7\u00E3o e Valida\u00E7\u00E3o de Campos String \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n type SanitizeResult = { error?: string; sanitized: string | null };\n\n const SANITIZE_FIELDS: Record<string, (val: string) => SanitizeResult> = {\n email: (val: string) => {\n if (!isValidEmail(val)) return { error: 'email inv\u00E1lido (formato incorreto)' };\n return { sanitized: val.toLowerCase().trim() };\n },\n firstName: (val: string) => ({ sanitized: sanitizeString(val, 100) }),\n lastName: (val: string) => ({ sanitized: sanitizeString(val, 100) }),\n city: (val: string) => ({ sanitized: sanitizeString(val, 100) }),\n state: (val: string) => ({ sanitized: sanitizeString(val, 100) }),\n zip: (val: string) => ({ sanitized: sanitizeString(val, 20) }),\n dob: (val: string) => ({ sanitized: sanitizeString(val, 20) }),\n productName: (val: string) => ({ sanitized: sanitizeString(val, 200) }),\n pageUrl: (val: string) => {\n if (!isValidUrl(val)) return { error: 'pageUrl inv\u00E1lido (formato incorreto)' };\n return { sanitized: val.trim() };\n },\n currency: (val: string) => {\n if (!isValidCurrency(val)) return { error: 'currency inv\u00E1lido (deve ser c\u00F3digo ISO 4217)' };\n return { sanitized: val.trim().toUpperCase() };\n },\n };\n\n // Sanitiza e valida campos espec\u00EDficos\n for (const [field, validator] of Object.entries(SANITIZE_FIELDS)) {\n const value = trackPayload[field as keyof TrackPayload];\n if (value !== undefined && value !== null) {\n if (typeof value !== 'string') {\n return new Response(JSON.stringify({ error: `Campo ${field} deve ser string` }), { status: 400, headers });\n }\n const result = validator(value);\n if (result.error) {\n return new Response(JSON.stringify({ error: result.error }), { status: 400, headers });\n }\n if (result.sanitized !== null) {\n trackPayload[field as keyof TrackPayload] = result.sanitized as any;\n }\n }\n }\n\n // Sanitiza campos de string gen\u00E9ricos\n const GENERIC_SANITIZE_FIELDS = ['utmSource', 'utmMedium', 'utmCampaign', 'utmContent', 'utmTerm'];\n for (const field of GENERIC_SANITIZE_FIELDS) {\n const value = trackPayload[field as keyof TrackPayload];\n if (value !== undefined && value !== null) {\n if (typeof value !== 'string') {\n return new Response(JSON.stringify({ error: `Campo ${field} deve ser string` }), { status: 400, headers });\n }\n const utmType = `utm_${field.replace('utm', '').toLowerCase()}`;\n if (!isValidUTM(value, utmType)) {\n return new Response(JSON.stringify({ error: `Campo ${field} cont\u00E9m caracteres perigosos` }), { status: 400, headers });\n }\n const sanitized = sanitizeString(value, 200);\n if (sanitized === null) {\n return new Response(JSON.stringify({ error: `Campo ${field} inv\u00E1lido ap\u00F3s sanitiza\u00E7\u00E3o` }), { status: 400, headers });\n }\n trackPayload[field as keyof TrackPayload] = sanitized as any;\n }\n }\n\n // Sanitiza campos de string restantes\n const TRACKING_ID_FIELDS = ['transactionId', 'fbclid', 'ttclid', 'gclid'];\n\n for (const field of TRACKING_ID_FIELDS) {\n const value = trackPayload[field as keyof TrackPayload];\n if (value !== undefined && value !== null) {\n if (typeof value !== 'string') {\n return new Response(JSON.stringify({ error: `Campo ${field} deve ser string` }), { status: 400, headers });\n }\n const sanitized = sanitizeString(value, 512);\n if (sanitized === null) {\n return new Response(JSON.stringify({ error: `Campo ${field} inv\u00E1lido ap\u00F3s sanitiza\u00E7\u00E3o` }), { status: 400, headers });\n }\n trackPayload[field as keyof TrackPayload] = sanitized as any;\n }\n }\n\n // \u2500\u2500 Valida\u00E7\u00E3o de Valor Num\u00E9rico \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (trackPayload.value !== undefined && trackPayload.value !== null) {\n if (!isValidValue(trackPayload.value)) {\n return new Response(JSON.stringify({ error: 'value fora do intervalo permitido (0-9,999,999)' }), { status: 400, headers });\n }\n trackPayload.value = Number(trackPayload.value);\n }\n\n // \u2500\u2500 Extrair dados comportamentais do browser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (behavioral_data) {\n payload.engagementScore = behavioral_data.engagement_score ?? behavioral_data.totalScore ?? null;\n payload.intentionLevel = behavioral_data.intention_level ?? null;\n payload.userScore = behavioral_data.user_score ?? null;\n // Sinais de engajamento profundo \u2014 usados no anti-falso-positivo e no LTV\n payload.scrollScore = behavioral_data.scroll_score ?? null;\n payload.timeLevel = behavioral_data.time_level ?? null;\n\n // \u2500\u2500 Sanitiza dados do behavioral_data \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Os dados do behavioral_data podem vir do browser e ser manipulados\n const sanitizedBehavioralEmail = behavioral_data.email && isValidEmail(behavioral_data.email)\n ? behavioral_data.email.toLowerCase().trim()\n : null;\n const sanitizedBehavioralPhone = behavioral_data.phone\n ? sanitizeString(behavioral_data.phone, 50)\n : null;\n const sanitizedBehavioralFirstName = behavioral_data.first_name || behavioral_data.firstName\n ? sanitizeString(behavioral_data.first_name || behavioral_data.firstName, 100)\n : null;\n const sanitizedBehavioralLastName = behavioral_data.last_name || behavioral_data.lastName\n ? sanitizeString(behavioral_data.last_name || behavioral_data.lastName, 100)\n : null;\n const sanitizedBehavioralCity = behavioral_data.city\n ? sanitizeString(behavioral_data.city, 100)\n : null;\n\n // Usa dados sanitizados do behavioral_data se n\u00E3o existirem no payload principal\n payload.email = payload.email || sanitizedBehavioralEmail;\n payload.phone = payload.phone || sanitizedBehavioralPhone;\n payload.firstName = payload.firstName || sanitizedBehavioralFirstName;\n payload.lastName = payload.lastName || sanitizedBehavioralLastName;\n payload.city = payload.city || sanitizedBehavioralCity;\n\n // Sanitiza campos restantes do behavioral_data\n const sanitizedBehavioralState = behavioral_data.state\n ? sanitizeString(behavioral_data.state, 100)\n : null;\n const sanitizedBehavioralZip = behavioral_data.zip\n ? sanitizeString(behavioral_data.zip, 20)\n : null;\n const sanitizedBehavioralDob = behavioral_data.dob\n ? sanitizeString(behavioral_data.dob, 20)\n : null;\n\n payload.state = payload.state || sanitizedBehavioralState;\n payload.zip = payload.zip || sanitizedBehavioralZip;\n payload.dob = payload.dob || sanitizedBehavioralDob;\n }\n\n // \u2500\u2500 Normaliza\u00E7\u00E3o de intent_score \u2192 0.0\u20131.0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Aceita string ('high'/'medium'/'low'), 0-1 ou 0-100 enviados pelo front.\n // intent_bucket mant\u00E9m a label leg\u00EDvel para D1 e logs.\n const intentScoreNum = resolveIntentScore(payload.intent_score);\n if (intentScoreNum !== null) {\n payload.intent_score = intentScoreNum;\n payload.intentScoreNum = intentScoreNum;\n payload.intent_bucket = intentScoreNum >= 0.8 ? 'high'\n : intentScoreNum >= 0.5 ? 'medium' : 'low';\n } else {\n payload.intentScoreNum = null;\n }\n\n // \u2500\u2500 Anti-falso-positivo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Penaliza intent se engajamento insuficiente: scroll raso E tempo curto.\n // scroll_score < 2.0 \u2248 n\u00E3o passou de 50% da p\u00E1gina.\n // time_level 'curioso' = menos de 60 segundos na p\u00E1gina.\n if (payload.intentScoreNum !== null) {\n const isShallowScroll = payload.scrollScore !== null && payload.scrollScore < 2.0;\n const isShallowTime = payload.timeLevel === 'curioso';\n if (isShallowScroll && isShallowTime) {\n const penalized = Math.round(payload.intentScoreNum * 0.7 * 100) / 100;\n payload.intentScoreNum = penalized;\n payload.intent_score = penalized;\n payload.intent_bucket = penalized >= 0.8 ? 'high' : penalized >= 0.5 ? 'medium' : 'low';\n payload.intent_penalized = true; // flag audit\u00E1vel \u2014 vis\u00EDvel no D1 e logs\n }\n }\n\n // \u2500\u2500 Edge Fingerprint + UTM Resurrection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const fingerprint = await generateEdgeFingerprint(request);\n payload.utmRestored = false;\n\n if (fingerprint && env.DB) {\n if (payload.utmSource) {\n ctx.waitUntil(saveEdgeFingerprint(env.DB, fingerprint, payload.userId, payload));\n } else {\n const recovered = await resurrectUTM(env.DB, fingerprint);\n if (recovered) {\n payload.utmSource = payload.utmSource || recovered.utm_source;\n payload.utmMedium = payload.utmMedium || recovered.utm_medium;\n payload.utmCampaign = payload.utmCampaign || recovered.utm_campaign;\n payload.utmContent = payload.utmContent || recovered.utm_content;\n payload.utmTerm = payload.utmTerm || recovered.utm_term;\n payload.utmRestored = true;\n }\n }\n }\n\n // \u2500\u2500 Bot Mitigation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const botScoreStr = (request as any).cf?.botManagement?.score;\n const cfBotScore = botScoreStr !== undefined ? parseInt(String(botScoreStr)) : 100;\n const ua = (request.headers.get('User-Agent') || '').toLowerCase();\n const isBotPattern = /bot|crawler|spider|lighthouse|postman|curl|inspect|headless/i.test(ua);\n\n const isBot = cfBotScore < 30 || isBotPattern;\n trackPayload.botScore = isBot ? 2 : (cfBotScore < 60 ? 1 : 0);\n\n if (isBot && !['Contact', 'Lead', 'Purchase'].includes(eventName)) {\n return new Response(JSON.stringify({ ok: true, skipped_due_to_bot: true }), { status: 200, headers });\n }\n\n // \u2500\u2500 Edge Geo Enrichment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const geoData = await enrichGeoFromEdge(request, env, payload);\n\n // \u2500\u2500 First-Party Cookie (Identity Resolution) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const cookieHeader = request.headers.get('Cookie') || '';\n const cdpUidMatch = cookieHeader.match(/_cdp_uid=([^;]+)/);\n const finalUserId = payload.userId || (cdpUidMatch ? cdpUidMatch[1] : crypto.randomUUID());\n payload.userId = finalUserId;\n\n const ga4Name = META_TO_GA4[eventName] || eventName.toLowerCase();\n\n // \u2500\u2500 Dual-layer semantics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Meta sempre recebe o nome can\u00F4nico (Schedule, Lead, etc.).\n // Internamente o CDP usa sem\u00E2ntica de funil precisa via FUNNEL_TAXONOMY.\n if (payload.funnel_stage) {\n const { depth, funnelDepth } = resolveFunnelStage(payload.funnel_stage);\n payload.funnelDepth = funnelDepth; // ex: 'bottom_intent', 'bottom_conversion'\n payload.funnelLevel = depth; // ex: 'bottom', 'conversion', 'mid'\n }\n if (eventName === 'Schedule' && payload.funnel_stage === 'route_click') {\n payload.internalEvent = 'IntentToVisit';\n }\n\n // \u2500\u2500 Real Estate Distance Enrichment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Calcula dist\u00E2ncia entre o IP do usu\u00E1rio (via Cloudflare) e o im\u00F3vel.\n // Ativa quando o evento carrega property_lat + property_lng (ex: Schedule de rota).\n const propLat = parseFloat(String(trackPayload.property_lat ?? trackPayload.propertyLat));\n const propLng = parseFloat(String(trackPayload.property_lng ?? trackPayload.propertyLng));\n const userLat = parseFloat(String(request.cf?.latitude ?? '0'));\n const userLng = parseFloat(String(request.cf?.longitude ?? '0'));\n if (!isNaN(propLat) && !isNaN(propLng) && !isNaN(userLat) && !isNaN(userLng)) {\n const distKm = haversineKm(userLat, userLng, propLat, propLng);\n trackPayload.distanceKm = Math.round(distKm * 10) / 10;\n trackPayload.distanceBucket = distKm < 5 ? 'very_close' :\n distKm < 15 ? 'close' :\n distKm < 30 ? 'nearby' :\n distKm < 60 ? 'moderate' : 'far';\n }\n\n // \u2500\u2500 LTV Prediction (+ A/B Testing de Prompts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const LTV_EVENTS = ['Lead', 'Contact', 'Schedule', 'CompleteRegistration'];\n if (LTV_EVENTS.includes(eventName) && !payload.value) {\n const abVariation = await getLtvAbVariation(env);\n const ltv = await predictLtv(env, payload, request, abVariation?.system_prompt || null);\n payload.value = ltv.value;\n payload.currency = payload.currency || 'BRL';\n payload.ltvClass = ltv.class;\n payload.ltvScore = ltv.score;\n ctx.waitUntil(upsertLtvProfile(env, payload.userId, ltv));\n if (abVariation) {\n const emailHash = payload.email\n ? await sha256(payload.email.trim().toLowerCase())\n : null;\n ctx.waitUntil(\n recordAbAssignment(\n env,\n payload.userId,\n abVariation.id,\n abVariation.test_id,\n ltv.value,\n ltv.class,\n emailHash ?? null,\n )\n );\n }\n }\n\n // \u2500\u2500 LTV Feedback Loop \u2014 fecha o ciclo preditivo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Quando uma compra real acontece, registra o valor real e recalcula accuracy.\n // Alimenta ltv_ab_variations.accuracy_score \u2192 autoDecideAbWinner usa isso.\n if (eventName === 'Purchase' && payload.value > 0) {\n ctx.waitUntil(recordLtvFeedback(env, payload.userId, payload.value));\n }\n\n // \u2500\u2500 Meta Signal Score (composite, pesos din\u00E2micos) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Pesos variam por profundidade de funil: fundo = comportamento pesa mais.\n {\n const w = computeMetaSignalWeights(payload.funnelLevel);\n const iW = payload.intentScoreNum ?? 0.5;\n const lW = payload.ltvScore ? payload.ltvScore / 100 : 0.5;\n const dW = distanceBucketWeight(payload.distanceBucket);\n payload.metaSignal = Math.round(((iW * w.intent) + (lW * w.ltv) + (dW * w.dist)) * 100) / 100;\n payload.metaSignalBucket = metaSignalBucket(payload.metaSignal); // 'hot'/'warm'/'cold'\n }\n\n // \u2500\u2500 Hot Lead Trigger (timing + sinal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Reage em tempo real: WhatsApp apenas quando comportamento + sinal justificam.\n // Crit\u00E9rios: rota + muito pr\u00F3ximo + (intent alto OU meta_signal alto)\n // + (janela de decis\u00E3o BRT 18\u201322h OU sinal excepcional \u2265 0.9)\n const hourBRT = (new Date().getUTCHours() - 3 + 24) % 24;\n const inWindow = hourBRT >= 18 && hourBRT <= 22;\n const isHotLead = payload.funnel_stage === 'route_click'\n && payload.distanceBucket === 'very_close'\n && ((payload.intentScoreNum ?? 0) >= 0.8 || payload.metaSignal >= 0.85)\n && (inWindow || payload.metaSignal >= 0.9);\n\n // Cross-Device Graph \u2014 background\n if (env.DB && payload.userId && (payload.email || payload.phone)) {\n ctx.waitUntil(resolveDeviceGraph(env.DB, payload.userId, payload.email, payload.phone));\n }\n\n // R2 Audit Log \u2014 background\n ctx.waitUntil(writeAuditLog(env, eventName, payload, geoData));\n\n // Disparar tudo em paralelo\n const WHATSAPP_NOTIFY_EVENTS = ['Lead', 'Purchase', 'CompleteRegistration'];\n const [metaRes, ga4Res, ttRes] = await Promise.allSettled([\n sendMetaCapi(env, eventName, payload, request, ctx),\n sendGA4Mp(env, ga4Name, payload, ctx),\n sendTikTokApi(env, eventName, payload, request, ctx),\n saveLead(env, payload.internalEvent || eventName, payload, request, 'website'),\n upsertProfile(env, eventName, payload, request),\n ...(WHATSAPP_NOTIFY_EVENTS.includes(eventName) || isHotLead\n ? [sendWhatsApp(env, isHotLead ? 'hot_lead_intent_to_visit' : eventName, payload)]\n : []),\n ]);\n\n // Automa\u00E7\u00E3o de mensagens\n const AUTOMATION_EVENTS = ['Lead', 'Purchase', 'InitiateCheckout'];\n if (AUTOMATION_EVENTS.includes(eventName) && env.DB) {\n const db = env.DB; // Captura em vari\u00E1vel local\n ctx.waitUntil(\n (async () => {\n try {\n const lastLead = await db\n .prepare(`SELECT id FROM leads WHERE event_id = ?1 LIMIT 1`)\n .bind(trackPayload.eventId || trackPayload.event_id || '')\n .first() as any;\n const leadId = lastLead?.id ? Number(lastLead.id) : null;\n if (leadId) await fireAutomation(env, eventName, leadId, trackPayload);\n } catch (e: any) { console.error('[Automation] lead lookup error:', e?.message || String(e)); }\n })()\n );\n }\n\n // Edge Personalization\n let currentScore = 0;\n if (env.DB && trackPayload.userId) {\n try {\n const profileRow = await env.DB.prepare('SELECT score FROM user_profiles WHERE user_id = ?').bind(trackPayload.userId).first();\n if (profileRow) currentScore = Number(profileRow.score) || 0;\n } catch (err: any) {\n console.error('[POST /track] Error fetching user profile score:', {\n userId: trackPayload.userId,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n const resHeaders = new Headers(headers);\n resHeaders.set('Set-Cookie', `_cdp_uid=${finalUserId}; HttpOnly; Secure; SameSite=Lax; Max-Age=31536000; Path=/; Domain=.${env.SITE_DOMAIN}`);\n\n return new Response(JSON.stringify({\n ok: true,\n userProfile: { score: currentScore, user_id: finalUserId },\n meta: metaRes.status === 'fulfilled' ? metaRes.value : { error: metaRes.reason?.message },\n ga4: ga4Res.status === 'fulfilled' ? ga4Res.value : { error: ga4Res.reason?.message },\n tiktok: ttRes.status === 'fulfilled' ? ttRes.value : { error: ttRes.reason?.message },\n }), { status: 200, headers: resHeaders });\n }\n\n // \u2500\u2500 POST /webhook/hotmart \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'POST' && url.pathname === '/webhook/hotmart') {\n if (env.WEBHOOK_SECRET_HOTMART) {\n const token = request.headers.get('X-Hotmart-Webhook-Token') || '';\n if (token !== env.WEBHOOK_SECRET_HOTMART) {\n return new Response('Unauthorized', { status: 401 });\n }\n }\n\n let wh: HotmartWebhook;\n try { wh = await request.json() as HotmartWebhook; } catch {\n return new Response('JSON inv\u00E1lido', { status: 400 });\n }\n\n const data = wh.data || wh;\n const buyer = data.buyer || {};\n const purchase = data.purchase || {};\n const product = data.product || {};\n\n if (!['APPROVED', 'COMPLETE', 'approved', 'complete'].includes(purchase.status)) {\n return new Response(JSON.stringify({ skipped: `status ${purchase.status}` }), { status: 200, headers });\n }\n\n const hmTxId = String(purchase.transaction || '');\n const dupCheck = await processWebhookDuplicateCheck(env, 'hotmart', hmTxId, JSON.stringify(wh), {\n email: buyer.email,\n });\n\n if (dupCheck.duplicate) {\n return new Response(JSON.stringify({ ok: true, skipped: 'duplicate' }), { status: 200, headers });\n }\n\n const profile = await getProfileByEmail(env, buyer.email);\n\n const payload = {\n email: buyer.email,\n phone: buyer.phone,\n firstName: buyer.name?.split(' ')[0],\n lastName: buyer.name?.split(' ').slice(1).join(' ') || undefined,\n fbp: profile?.fbp,\n fbc: profile?.fbc,\n userId: profile?.user_id,\n gaClientId: profile?.ga_client_id,\n value: purchase.price?.value,\n currency: purchase.price?.currency_value || 'BRL',\n contentIds: [String(product.id || product.ucode || '')],\n contentName: product.name,\n contentType: 'product',\n pageUrl: profile?.page_url || `https://${env.SITE_DOMAIN || 'seu-dominio.com.br'}`,\n orderId: purchase.transaction,\n eventId: `hotmart_${purchase.transaction}`,\n city: profile?.city,\n state: profile?.state,\n country: profile?.country,\n };\n\n ctx.waitUntil(Promise.allSettled([\n sendMetaCapi(env, 'Purchase', payload, request, ctx),\n sendGA4Mp(env, 'purchase', payload, ctx),\n sendTikTokApi(env, 'CompletePayment', payload, request, ctx),\n saveLead(env, 'Purchase', payload, request, 'hotmart'),\n sendWhatsApp(env, 'Purchase', payload),\n ]));\n\n return new Response(JSON.stringify({ ok: true }), { status: 200, headers });\n }\n\n // \u2500\u2500 POST /webhook/kiwify \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'POST' && url.pathname === '/webhook/kiwify') {\n if (env.WEBHOOK_SECRET_KIWIFY) {\n const token = request.headers.get('X-Kiwify-Event-Token') || '';\n if (token !== env.WEBHOOK_SECRET_KIWIFY) {\n return new Response('Unauthorized', { status: 401 });\n }\n }\n\n let wh: KiwifyWebhook;\n try { wh = await request.json() as KiwifyWebhook; } catch {\n return new Response('JSON inv\u00E1lido', { status: 400 });\n }\n\n if (wh.order_status !== 'paid' && wh.order_status !== 'approved') {\n return new Response(JSON.stringify({ skipped: `status ${wh.order_status}` }), { status: 200, headers });\n }\n\n const kwTxId = String(wh.order_id || '');\n const dupCheck = await processWebhookDuplicateCheck(env, 'kiwify', kwTxId, JSON.stringify(wh), {\n email: customer.email,\n });\n\n if (dupCheck.duplicate) {\n return new Response(JSON.stringify({ ok: true, skipped: 'duplicate' }), { status: 200, headers });\n }\n\n const customer = wh.Customer || {};\n const product = wh.Product || {};\n const profile = await getProfileByEmail(env, customer.email || '');\n\n const payload = {\n email: customer.email,\n phone: customer.mobile,\n firstName: customer.full_name?.split(' ')[0],\n lastName: customer.full_name?.split(' ').slice(1).join(' ') || undefined,\n fbp: profile?.fbp,\n fbc: profile?.fbc,\n userId: profile?.user_id,\n gaClientId: profile?.ga_client_id,\n value: wh.order_value ? parseFloat(wh.order_value) / 100 : undefined,\n currency: 'BRL',\n contentIds: [String(product.product_id || '')],\n contentName: product.product_name,\n contentType: 'product',\n pageUrl: profile?.page_url || `https://${env.SITE_DOMAIN || 'seu-dominio.com.br'}`,\n orderId: wh.order_id,\n eventId: `kiwify_${wh.order_id}`,\n city: profile?.city,\n state: profile?.state,\n country: profile?.country,\n };\n\n ctx.waitUntil(Promise.allSettled([\n sendMetaCapi(env, 'Purchase', payload, request, ctx),\n sendGA4Mp(env, 'purchase', payload, ctx),\n sendTikTokApi(env, 'CompletePayment', payload, request, ctx),\n sendPinterestCapi(env, 'Purchase', payload, request, ctx),\n sendRedditCapi(env, 'Purchase', payload, request, ctx),\n sendLinkedInCapi(env, 'Purchase', payload, request, ctx),\n sendSpotifyCapi(env, 'Purchase', payload, request, ctx),\n saveLead(env, 'Purchase', payload, request, 'kiwify'),\n sendWhatsApp(env, 'Purchase', payload),\n ]));\n\n return new Response(JSON.stringify({ ok: true }), { status: 200, headers });\n }\n\n // \u2500\u2500 POST /webhook/ticto \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'POST' && url.pathname === '/webhook/ticto') {\n let rawBody;\n try { rawBody = await request.text(); } catch {\n return new Response('Leitura de body falhou', { status: 400 });\n }\n if (env.WEBHOOK_SECRET_TICTO) {\n const sig = request.headers.get('X-Ticto-Signature') || '';\n const valid = await verifyHmac(env.WEBHOOK_SECRET_TICTO, rawBody, sig);\n if (!valid) {\n return new Response('Unauthorized', { status: 401 });\n }\n }\n\n let wh: TictoWebhook;\n try { wh = JSON.parse(rawBody) as TictoWebhook; } catch {\n return new Response('JSON inv\u00E1lido', { status: 400 });\n }\n\n const STATUS_PAID = ['paid', 'approved', 'complete', 'completed'];\n if (!STATUS_PAID.includes((wh.status || '').toLowerCase())) {\n return new Response(JSON.stringify({ skipped: `status ${wh.status}` }), { status: 200, headers });\n }\n\n const customer = wh.customer || {};\n const order = wh.order || {};\n const item = wh.item || {};\n const tracking = wh.tracking || wh.url_params || {};\n\n const valueRaw = order.paid_amount ?? order.total ?? order.amount;\n const value = valueRaw ? parseFloat(String(valueRaw)) / 100 : undefined;\n const transactionId = order.hash || order.transaction_hash || order.id;\n const tcTxId = String(order.hash || order.transaction_hash || order.id || '');\n\n const dupCheck = await processWebhookDuplicateCheck(env, 'ticto', tcTxId, rawBody, {\n email: customer.email,\n });\n\n if (dupCheck.duplicate) {\n return new Response(JSON.stringify({ ok: true, skipped: 'duplicate' }), { status: 200, headers });\n }\n\n const urlUserId = tracking.user_id || wh.url_params?.user_id;\n let profile = await getProfileByEmail(env, customer.email || '');\n if (!profile && urlUserId && env.DB) {\n try {\n profile = await env.DB.prepare(\n 'SELECT * FROM user_profiles WHERE user_id = ? ORDER BY updated_at DESC LIMIT 1'\n ).bind(urlUserId).first();\n } catch (err: any) {\n console.error('[POST /webhook/ticto] Error fetching user profile by userId:', {\n userId: urlUserId,\n email: customer.email,\n error: err?.message || String(err),\n stack: err?.stack,\n });\n }\n }\n\n const fbclid = tracking.fbclid || wh.url_params?.fbclid;\n const fbc = profile?.fbc || (fbclid ? `fb.1.${Date.now()}.${fbclid}` : undefined);\n\n const payload = {\n email: customer.email,\n phone: customer.phone,\n firstName: customer.name?.split(' ')[0],\n lastName: customer.name?.split(' ').slice(1).join(' ') || undefined,\n fbp: profile?.fbp,\n fbc,\n ttp: profile?.ttp,\n userId: profile?.user_id,\n gaClientId: profile?.ga_client_id,\n value,\n currency: 'BRL',\n contentIds: [String(item.product_id || '')],\n contentName: item.product_name,\n contentType: 'product',\n pageUrl: profile?.page_url || `https://${env.SITE_DOMAIN || 'seu-dominio.com.br'}`,\n orderId: transactionId,\n eventId: `ticto_${transactionId}`,\n city: profile?.city,\n state: profile?.state,\n country: profile?.country || 'br',\n utmSource: tracking.utm_source || tracking.src || '',\n utmMedium: tracking.utm_medium || '',\n utmCampaign: tracking.utm_campaign || '',\n utmContent: tracking.utm_content || '',\n };\n\n ctx.waitUntil(Promise.allSettled([\n sendMetaCapi(env, 'Purchase', payload, request, ctx),\n sendGA4Mp(env, 'purchase', payload, ctx),\n sendTikTokApi(env, 'CompletePayment', payload, request, ctx),\n sendPinterestCapi(env, 'Purchase', payload, request, ctx),\n sendRedditCapi(env, 'Purchase', payload, request, ctx),\n sendLinkedInCapi(env, 'Purchase', payload, request, ctx),\n sendSpotifyCapi(env, 'Purchase', payload, request, ctx),\n saveLead(env, 'Purchase', payload, request, 'ticto'),\n sendWhatsApp(env, 'Purchase', payload),\n ]));\n\n return new Response(JSON.stringify({ ok: true }), { status: 200, headers });\n }\n\n // \u2500\u2500 GET /webhook/whatsapp \u2014 verifica\u00E7\u00E3o do webhook pela Meta \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'GET' && url.pathname === '/webhook/whatsapp') {\n const mode = url.searchParams.get('hub.mode');\n const token = url.searchParams.get('hub.verify_token');\n const challenge = url.searchParams.get('hub.challenge');\n\n if (mode === 'subscribe' && env.WA_WEBHOOK_VERIFY_TOKEN && token === env.WA_WEBHOOK_VERIFY_TOKEN) {\n return new Response(challenge, { status: 200, headers: { 'Content-Type': 'text/plain' } });\n }\n return new Response('Forbidden', { status: 403 });\n }\n\n // \u2500\u2500 POST /webhook/whatsapp \u2014 mensagens recebidas (CTWA) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (request.method === 'POST' && url.pathname === '/webhook/whatsapp') {\n let body;\n try { body = await request.json(); } catch {\n return new Response('JSON inv\u00E1lido', { status: 400 });\n }\n\n const result = await processWhatsAppWebhook(env, body, request, ctx);\n return new Response(JSON.stringify({ ok: true, ...result }), { status: 200, headers });\n }\n\n // \u2500\u2500 ML \u2014 Segmenta\u00E7\u00E3o Din\u00E2mica \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (url.pathname === '/api/segmentation/cluster' && request.method === 'POST') {\n return handleSegmentationCluster(env, request, headers);\n }\n if (url.pathname === '/api/segmentation/list' && request.method === 'GET') {\n return handleSegmentationList(env, request, headers);\n }\n if (url.pathname === '/api/segmentation/outliers' && request.method === 'GET') {\n return handleSegmentationOutliers(env, request, headers);\n }\n if (url.pathname === '/api/segmentation/update' && request.method === 'PUT') {\n return handleSegmentationUpdate(env, request, headers);\n }\n\n // \u2500\u2500 ML \u2014 Bidding Recommendations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (url.pathname === '/api/bidding/recommend' && request.method === 'POST') {\n return handleBiddingRecommend(env, request, headers);\n }\n if (url.pathname === '/api/bidding/history' && request.method === 'GET') {\n return handleBiddingHistory(env, request, headers);\n }\n if (url.pathname === '/api/bidding/status' && request.method === 'GET') {\n return handleBiddingStatus(env, request, headers);\n }\n\n // \u2500\u2500 ML \u2014 A/B Testing de Prompts LTV \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (url.pathname === '/api/ltv/ab-test/create' && request.method === 'POST') {\n return handleLtvAbTestCreate(env, request, headers);\n }\n if (url.pathname === '/api/ltv/ab-test/list' && request.method === 'GET') {\n return handleLtvAbTestList(env, request, headers);\n }\n if (url.pathname === '/api/ltv/ab-test/results' && request.method === 'GET') {\n return handleLtvAbTestResults(env, request, headers);\n }\n if (url.pathname === '/api/ltv/ab-test/winner' && request.method === 'POST') {\n return handleLtvAbTestWinner(env, request, headers);\n }\n\n // \u2500\u2500 Fraud Detection \u2014 Fase 4 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (url.pathname === '/api/fraud/alerts' && request.method === 'GET') {\n return handleFraudAlerts(env, request, headers);\n }\n if (url.pathname === '/api/fraud/blocklist' && request.method === 'GET') {\n return handleFraudBlocklist(env, request, headers);\n }\n if (url.pathname === '/api/fraud/blocklist/add' && request.method === 'POST') {\n return handleFraudBlocklistAdd(env, request, headers);\n }\n if (url.pathname === '/api/fraud/blocklist/remove' && request.method === 'DELETE') {\n return handleFraudBlocklistRemove(env, request, headers);\n }\n if (url.pathname === '/api/fraud/stats' && request.method === 'GET') {\n return handleFraudStats(env, request, headers);\n }\n\n // 404\n return new Response(JSON.stringify({ error: 'rota n\u00E3o encontrada' }), { status: 404, headers });\n },\n\n // \u2500\u2500 Cron Handler \u2014 Intelligence Agent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n async scheduled(event: any, env: Env, ctx: ExecutionContext) {\n const cron = event.cron;\n const isMonthly = cron === '0 3 1 * *';\n\n ctx.waitUntil(runIntelligenceAgent(env, isMonthly ? 'monthly_audit' : 'weekly_check'));\n },\n\n // \u2500\u2500 Queue Consumer \u2014 Retry de eventos com falha \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n async queue(batch: any, env: Env, ctx: ExecutionContext) {\n for (const message of batch.messages) {\n const { eventType, payload, platform } = message.body as { eventType: string; payload: TrackPayload; platform: string; attempt?: number };\n\n try {\n if (platform === 'meta') await sendMetaCapi(env, eventType, payload, null, ctx);\n if (platform === 'ga4') await sendGA4Mp(env, eventType, payload, ctx);\n if (platform === 'tiktok') await sendTikTokApi(env, eventType, payload, null, ctx);\n if (platform === 'pinterest') await sendPinterestCapi(env, eventType, payload, null, ctx);\n if (platform === 'reddit') await sendRedditCapi(env, eventType, payload, null, ctx);\n if (platform === 'linkedin') await sendLinkedInCapi(env, eventType, payload, null, ctx);\n if (platform === 'spotify') await sendSpotifyCapi(env, eventType, payload, null, ctx);\n\n message.ack();\n } catch (err: any) {\n console.error(`[Queue] Falha ao reprocessar ${platform}/${eventType}:`, err?.message || String(err));\n message.retry();\n }\n }\n },\n};\n"],
|
|
6
|
-
"mappings": "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",
|
|
7
|
-
"names": ["PerformanceMark", "clear", "count", "countReset", "createTask", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "profile", "profileEnd", "table", "time", "timeEnd", "timeLog", "timeStamp", "trace", "warn", "hrtime", "dir", "env", "count", "cwd", "assert", "hrtime", "env", "platform", "log", "profile", "context", "env", "env", "profile", "env", "send", "env", "send", "env", "send", "env", "send", "features", "error", "env", "env", "hour", "country", "features", "ltvClass", "ltvMultiplier", "productValue", "baseValue", "predictedValue", "dot", "env", "isNotNull", "_", "env", "platform", "env", "env", "title", "platform", "env", "profile", "platform"]
|
|
8
|
-
}
|