{
  "version": 3,
  "sources": ["twenty-sdk-define-stub:__twenty-sdk-define-stub__", "../../../../src/constants/universal-identifiers.ts", "../../../../src/lib/rest-client.ts", "../../../../src/lib/ingest.ts", "../../../../src/lib/stages/load-source.stage.ts", "../../../../src/constants/field-map.ts", "../../../../src/lib/stages/sync-schema.stage.ts", "../../../../src/lib/replay.ts", "../../../../src/logic-functions/quarantine-discard.ts"],
  "sourcesContent": ["\n// Auto-generated stub for twenty-sdk/define injected by the SDK CLI build.\n// Real implementations would pull in zod, twenty-shared and ~1MB of code; at\n// runtime only `default.config.handler` is consumed, so tiny no-ops suffice.\nconst __defineFactoryStub = (config) => ({\n  success: true,\n  config,\n  errors: [],\n});\n\nconst __anyHandler = {\n  get(_target, prop) {\n    if (prop === '__esModule') return true;\n    if (prop === Symbol.toPrimitive) return () => '';\n    if (typeof prop === 'symbol') return undefined;\n    return new Proxy(() => undefined, __anyHandler);\n  },\n  apply() {\n    return new Proxy(() => undefined, __anyHandler);\n  },\n};\nconst __anyStub = new Proxy(() => undefined, __anyHandler);\n\nexport const createValidationResult = __defineFactoryStub;\nexport const defineAgent = __defineFactoryStub;\nexport const defineApplication = __defineFactoryStub;\nexport const defineApplicationRole = __defineFactoryStub;\nexport const defineCommandMenuItem = __defineFactoryStub;\nexport const defineConnectionProvider = __defineFactoryStub;\nexport const defineField = __defineFactoryStub;\nexport const defineFrontComponent = __defineFactoryStub;\nexport const defineIndex = __defineFactoryStub;\nexport const defineLogicFunction = __defineFactoryStub;\nexport const defineNavigationMenuItem = __defineFactoryStub;\nexport const defineObject = __defineFactoryStub;\nexport const definePageLayout = __defineFactoryStub;\nexport const definePageLayoutTab = __defineFactoryStub;\nexport const definePermissionFlag = __defineFactoryStub;\nexport const definePostInstallLogicFunction = __defineFactoryStub;\nexport const definePreInstallLogicFunction = __defineFactoryStub;\nexport const defineRole = __defineFactoryStub;\nexport const defineSettingsFrontComponent = __defineFactoryStub;\nexport const defineSkill = __defineFactoryStub;\nexport const defineUninstallLogicFunction = __defineFactoryStub;\nexport const defineView = __defineFactoryStub;\nexport const defineViewField = __defineFactoryStub;\nexport const AggregateOperations = __anyStub;\nexport const DateDisplayFormat = __anyStub;\nexport const FieldMetadataSettingsOnClickAction = __anyStub;\nexport const FieldType = __anyStub;\nexport const HTTPMethod = __anyStub;\nexport const NavigationMenuItemType = __anyStub;\nexport const NumberDataType = __anyStub;\nexport const ObjectOpenRecordIn = __anyStub;\nexport const ObjectRecordGroupByDateGranularity = __anyStub;\nexport const OnDeleteAction = __anyStub;\nexport const PageLayoutTabLayoutMode = __anyStub;\nexport const PageLayoutType = __anyStub;\nexport const RelationType = __anyStub;\nexport const RowLevelPermissionPredicateGroupLogicalOperator = __anyStub;\nexport const RowLevelPermissionPredicateOperand = __anyStub;\nexport const STANDARD_OBJECT = __anyStub;\nexport const STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS = __anyStub;\nexport const STANDARD_PAGE_LAYOUT = __anyStub;\nexport const STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS = __anyStub;\nexport const SystemPermissionFlag = __anyStub;\nexport const ViewCalendarLayout = __anyStub;\nexport const ViewFilterGroupLogicalOperator = __anyStub;\nexport const ViewFilterOperand = __anyStub;\nexport const ViewKey = __anyStub;\nexport const ViewOpenRecordIn = __anyStub;\nexport const ViewSortDirection = __anyStub;\nexport const ViewType = __anyStub;\nexport const ViewVisibility = __anyStub;\nexport const canAccessFullAdminPanel = __anyStub;\nexport const canImpersonate = __anyStub;\nexport const every = __anyStub;\nexport const everyDefined = __anyStub;\nexport const everyEquals = __anyStub;\nexport const favoriteRecordIds = __anyStub;\nexport const featureFlags = __anyStub;\nexport const getFieldUniversalIdentifier = __anyStub;\nexport const getSystemRelationFieldUniversalIdentifier = __anyStub;\nexport const getSystemViewFieldUniversalIdentifier = __anyStub;\nexport const getSystemViewUniversalIdentifier = __anyStub;\nexport const hasAnySoftDeleteFilterOnView = __anyStub;\nexport const includes = __anyStub;\nexport const includesEvery = __anyStub;\nexport const isDashboardPageLayoutInEditMode = __anyStub;\nexport const isDefined = __anyStub;\nexport const isInSidePanel = __anyStub;\nexport const isLayoutCustomizationModeEnabled = __anyStub;\nexport const isNonEmptyString = __anyStub;\nexport const isSelectAll = __anyStub;\nexport const none = __anyStub;\nexport const noneDefined = __anyStub;\nexport const noneEquals = __anyStub;\nexport const numberOfSelectedRecords = __anyStub;\nexport const objectMetadataItem = __anyStub;\nexport const objectMetadataLabel = __anyStub;\nexport const objectPermissions = __anyStub;\nexport const pageType = __anyStub;\nexport const selectedRecords = __anyStub;\nexport const some = __anyStub;\nexport const someDefined = __anyStub;\nexport const someEquals = __anyStub;\nexport const someNonEmptyString = __anyStub;\nexport const targetObjectReadPermissions = __anyStub;\nexport const targetObjectWritePermissions = __anyStub;\nexport const validateFields = __anyStub;\n", "export const IDS = {\n  APPLICATION: '96a389dd-384a-43a1-a376-9d3cf01b6ab7',\n  DEFAULT_ROLE: '3dd2cdb0-32c7-44b4-9f7b-0a9c667ec249',\n\n  // Objects\n  INTAKE_SOURCE_OBJECT: '8c1c227c-db7d-4834-b328-cacbe8af0bfc',\n  INTAKE_LOG_OBJECT: 'b77a2439-1503-4ef6-ab8b-8f4293bc19da',\n  INTAKE_FIELD_RULE_OBJECT: 'e74df817-ff25-4bfb-bdf0-651662ca327e',\n\n  // IntakeSource fields\n  INTAKE_SOURCE_NAME: '0deb7e4b-bb90-4c86-b903-5208b42041e2',\n  INTAKE_SOURCE_SLUG: '18f7645b-2dce-4145-b1b6-9cc3332c0578',\n  INTAKE_SOURCE_TARGET_OBJECT: '65f3d7f7-a601-4375-9c67-684d0044620b',\n  INTAKE_SOURCE_SECRET: '4c919402-07f5-4041-ade6-a42402f1881f',\n  INTAKE_SOURCE_STATUS: '6f1fa6fe-02b4-48ab-b1ee-97c600bbf483',\n  INTAKE_SOURCE_CREATE_OPP: '67ae59aa-2275-4ef2-b594-137f6bfafd99',\n  INTAKE_SOURCE_OPP_TEMPLATE: '3907b346-77a6-4c79-a4d7-6e1cc20bb82b',\n  INTAKE_SOURCE_TOTAL_INGESTED: '69655a93-bc70-48bd-874e-aeccc63ee1a8',\n  INTAKE_SOURCE_TOTAL_FAILED: '27b3a499-183e-4cc3-8e40-938f953a986d',\n  INTAKE_SOURCE_LAST_INGESTED: 'e167f628-9865-468e-894a-b4b6150cec26',\n\n  // IntakeLog fields\n  INTAKE_LOG_SOURCE_RELATION: 'b1c623ea-7a9a-47a5-bee4-35fdd668a637',\n  INTAKE_LOG_STATUS: '8b6d26d1-f89c-486c-a617-9f9f6a9ca36d',\n  INTAKE_LOG_PAYLOAD_HASH: 'c43bb1ad-e78a-4c60-bd95-02475ede7f44',\n  INTAKE_LOG_RECORD_ID: '77a55116-a64b-4954-8369-341022dd5bdd',\n  INTAKE_LOG_RECORD_TYPE: '02154e96-5808-48ed-8838-51083f174550',\n  INTAKE_LOG_FIELDS_CREATED: '2295ca2b-b559-4b38-9771-12dd8d3d76d7',\n  INTAKE_LOG_FIELDS_MATCHED: '83d07a0f-5bcd-4fb1-9759-f9b04b9381d8',\n  INTAKE_LOG_OVERFLOW_COUNT: '4090acb1-f48a-4957-bb91-c642f8f434a7',\n  INTAKE_LOG_PROCESSING_MS: 'a9191f27-4b40-42e9-8cce-20c75900e12c',\n  INTAKE_LOG_ERROR: '8d9979f1-9774-43a8-b958-d1b37bd4ecc7',\n  INTAKE_LOG_PROCESSED_AT: 'a8d99fbd-722e-4987-8afe-b830ac026f0a',\n\n  // IntakeFieldRule fields\n  INTAKE_FIELD_RULE_SOURCE_RELATION: '396dd1f1-3873-4efa-a6bb-7b41eda14d83',\n  INTAKE_FIELD_RULE_INPUT_PATTERN: '757201a0-9f64-47b9-bf3a-a793074bf84e',\n  INTAKE_FIELD_RULE_CANONICAL_NAME: 'fafebc55-a2cc-4c9f-975b-050c2676659d',\n  INTAKE_FIELD_RULE_FIELD_TYPE: '72d1f6d8-d63e-419e-a244-8127d7b4705f',\n  INTAKE_FIELD_RULE_PRIORITY: '911df299-940b-44f9-92f7-3fd01fde01a7',\n  INTAKE_FIELD_RULE_IS_ACTIVE: '6f9cd96d-aecd-437f-a7b5-d45548782771',\n  INTAKE_FIELD_RULE_TARGET_OBJECT: '7b8411a7-5e1d-40f2-a20c-683c07f67926',\n\n  // Logic Functions\n  WEBHOOK_LOGIC_FUNCTION: '8323c257-48fe-4bb6-b1dd-166844f575c0',\n  HEALTH_LOGIC_FUNCTION: '4ece4e39-286b-4820-81f4-b7beee71d092',\n  REGISTER_LOGIC_FUNCTION: '56d46e18-6cae-4d99-9893-b7d70740c9db',\n\n  // IntakeSource reverse relation fields\n  INTAKE_SOURCE_LOGS_REVERSE: '6ecfa369-22e0-4812-bb75-4338cea8be65',\n  INTAKE_SOURCE_RULES_REVERSE: '776fefaf-0eee-4ec0-93e0-d11bd80c1e20',\n\n  // v0.2.0 \u2014 rawPayload + retry + post-install + UI\n  INTAKE_LOG_RAW_PAYLOAD: 'b65c9e1c-f2c1-4c52-a5b3-1e1ac3139692',\n  RETRY_LOGIC_FUNCTION: '90f20396-a69a-4ae4-af20-6be65c565bb5',\n  POST_INSTALL_LOGIC_FUNCTION: 'e836fdd6-fd54-4aa4-ba6d-87d5a02148ef',\n  LOG_RETRY_FRONT_COMPONENT: '0cb97f6d-30e2-48c8-90e1-241b82870b4d',\n  FIELD_RULES_TABLE_FRONT_COMPONENT: 'c35faad9-3468-4746-9c1c-b13d73e5e09b',\n  SOURCE_PAGE_LAYOUT: '8c894ba8-5c8c-45ed-b0af-1d22ede93eb9',\n  SOURCE_LAYOUT_TAB_RULES: '80f5c49a-083c-4062-8bd5-ae158abb6c33',\n  SOURCE_LAYOUT_TAB_RULES_WIDGET: '26a9ebb7-1d59-4b03-a018-56968f6df224',\n  LOG_PAGE_LAYOUT: 'b0972802-ede5-463c-9f59-cb05f04957db',\n  LOG_LAYOUT_TAB_RETRY: '6b109695-ba3a-43de-a31a-23119ccf87ba',\n  LOG_LAYOUT_TAB_RETRY_WIDGET: '11727c1a-5145-46de-9742-88d07d64c72e',\n  SAMPLE_RULE_PHONE: '8440da8d-8ac4-4f4b-baa2-4d62936cde35',\n  SAMPLE_RULE_EMAIL: 'd123cde4-05aa-44e1-86f6-454be1d7048b',\n  SAMPLE_RULE_FULLNAME: '00e49fe8-1b48-4f5b-aaf4-414d0923c712',\n\n  // Views & Navigation\n  SOURCES_VIEW: '4435cd43-5c13-472f-b4f9-b686c0f46285',\n  LOGS_VIEW: 'a2cd0a93-9778-4ba5-99d9-b8b89c4fb39d',\n  INTAKE_NAV_ITEM: 'e81bf288-5686-4713-86ae-e2947b124cab',\n\n  // \u2500\u2500 v0.4.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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  // IntakeLog fields \u2014 quarantine, idempotency, replay lineage\n  INTAKE_LOG_IDEMPOTENCY_KEY: 'bf91e4c0-6477-41f2-a9bd-fb159d3091d4',\n  INTAKE_LOG_SPAM_SCORE: '4e250af2-925f-4724-85f6-f353a6bb4cfd',\n  INTAKE_LOG_QUARANTINE_REASON: '323b3c3e-a111-45d1-a211-cf70efa6cd9e',\n  INTAKE_LOG_REPLAY_OF: 'b68876b1-0045-4eaa-a4e7-f0634e110ef1',\n\n  // IntakeSource fields \u2014 silence detection, spam, merge policy\n  INTAKE_SOURCE_EXPECTED_CADENCE: 'a97c3906-5555-4e60-a6d6-84155a4e00a6',\n  INTAKE_SOURCE_HEALTH_STATUS: '2ad13b20-5bd7-450a-b52d-bcf208373cf5',\n  INTAKE_SOURCE_SILENT_SINCE: 'd3395601-f29f-4e57-98eb-561ab011cc72',\n  INTAKE_SOURCE_ALERT_WEBHOOK: '5a066d62-0426-41c1-b34c-1a7e881ce854',\n  INTAKE_SOURCE_LAST_ALERT_AT: 'fc64a598-ccbe-44e3-bd42-716e32d626a2',\n  INTAKE_SOURCE_HONEYPOT_FIELD: '5c145686-50de-496c-bb45-a30c8b39034c',\n  INTAKE_SOURCE_MERGE_POLICY: '5a946f85-b1c2-493e-92c6-31c50e637a7e',\n\n  // IntakeFieldRule fields\n  INTAKE_FIELD_RULE_MERGE_STRATEGY: '40c6fdcb-527a-4691-8518-c40a3d3e34c6',\n\n  // Logic Functions\n  CONTRACT_LOGIC_FUNCTION: '2eea4152-1b08-4b8c-903c-f4c7ee7275d0',\n  REPLAY_LOG_LOGIC_FUNCTION: '8ff98390-7358-4a91-84f3-435f758182a3',\n  REPLAY_BULK_LOGIC_FUNCTION: 'b82ed4c4-07bc-4095-8ee5-611200626dc0',\n  QUARANTINE_LIST_LOGIC_FUNCTION: '0203643c-2a97-4e7c-b4a5-b76d721cf23a',\n  QUARANTINE_RELEASE_LOGIC_FUNCTION: '5a10d4fe-c807-45c6-9e61-c191d4e37b4e',\n  QUARANTINE_DISCARD_LOGIC_FUNCTION: '1454a56e-6197-4dfd-9b41-5cc3b1436af7',\n  CHECK_SILENCE_LOGIC_FUNCTION: 'e88cd5f2-ab96-4f89-ac55-78db66b32d66',\n\n  // Application variables\n  VAR_MERGE_POLICY: 'a84fe9fd-3d7c-41d9-b0e8-dfdc1a87f348',\n  VAR_SPAM_FILTER_ENABLED: '570d3ba8-1904-4bad-a5ce-27e208e6414a',\n  VAR_SPAM_SCORE_THRESHOLD: '4395574d-24b4-4e0e-afa3-1e90fcd4f470',\n  VAR_HONEYPOT_FIELD: '2cf56c56-f5cb-47c5-aa43-84f301060a95',\n  VAR_RAW_PAYLOAD_RETENTION: 'f3314ad6-05b9-4127-bb88-cea5f2018dc9',\n  VAR_RAW_PAYLOAD_MAX_BYTES: 'b002ca76-df3d-47b4-8ac5-d3f562239c48',\n  VAR_REPLAY_MAX_BATCH: 'cf55956f-177e-4afd-8d9f-7f42c614209c',\n} as const;\n", "/**\n * Minimal REST client for Twenty's Core and Metadata APIs.\n * Uses raw fetch so it works with dynamically created custom fields\n * that the typed SDK client doesn't know about at build time.\n */\n\nconst apiUrl = () => process.env['TWENTY_API_URL'] ?? '';\nconst token = () => process.env['TWENTY_APP_ACCESS_TOKEN'] ?? '';\n\nasync function request<T>(\n  base: string,\n  method: string,\n  path: string,\n  body?: unknown,\n): Promise<T> {\n  const res = await fetch(`${base}${path}`, {\n    method,\n    headers: {\n      Authorization: `Bearer ${token()}`,\n      'Content-Type': 'application/json',\n    },\n    body: body !== undefined ? JSON.stringify(body) : undefined,\n  });\n\n  const text = await res.text();\n  if (!res.ok) {\n    throw new Error(`${method} ${path} \u2192 ${res.status}: ${text}`);\n  }\n  return JSON.parse(text) as T;\n}\n\nexport const coreApi = {\n  get: <T>(path: string) => request<T>(`${apiUrl()}/rest`, 'GET', path),\n  post: <T>(path: string, body: unknown) => request<T>(`${apiUrl()}/rest`, 'POST', path, body),\n  patch: <T>(path: string, body: unknown) => request<T>(`${apiUrl()}/rest`, 'PATCH', path, body),\n};\n\nexport const metaApi = {\n  get: <T>(path: string) => request<T>(`${apiUrl()}/rest/metadata`, 'GET', path),\n  post: <T>(path: string, body: unknown) => request<T>(`${apiUrl()}/rest/metadata`, 'POST', path, body),\n};\n\n/** Run a raw GraphQL query against the /graphql endpoint. */\nexport async function gql<T = unknown>(\n  query: string,\n  variables?: Record<string, unknown>,\n): Promise<T> {\n  return request<T>(`${apiUrl()}`, 'POST', '/graphql', { query, variables });\n}\n", "/**\n * One way to run an ingestion, shared by every entry point.\n *\n * The webhook, a replay, a retry and a quarantine release all run the same\n * pipeline and all have to deal with the same terminal outcomes. Keeping that in\n * one place is what stops the endpoints drifting apart \u2014 before this, only the\n * happy path wrote an IntakeLog, so a rejected signature or a failed record\n * write left nothing behind at all and `totalFailed` never moved off zero.\n */\n\nimport { CoreApiClient } from 'twenty-client-sdk/core';\nimport { MetadataApiClient } from 'twenty-client-sdk/metadata';\nimport { createPipeline } from './pipeline-factory';\nimport type { PipelineContext } from './pipeline';\nimport type { AppError } from './result';\nimport { writeIntakeLog, bumpSourceCounters, type LogStatus } from './intake-log-writer';\n\nexport type IngestOptions = {\n  sourceSlug: string;\n  rawPayload: Record<string, unknown>;\n  rawBody?: string | undefined;\n  headers?: Record<string, string | undefined>;\n  idempotencyKey?: string | undefined;\n  skipDedup?: boolean;\n  skipSpamFilter?: boolean;\n  replayOfLogId?: string | undefined;\n};\n\nexport type IngestOutcome =\n  | { ok: true; ctx: PipelineContext }\n  | { ok: false; error: AppError; ctx: PipelineContext };\n\nexport async function runIngestion(options: IngestOptions): Promise<IngestOutcome> {\n  const ctx: PipelineContext = {\n    sourceSlug: options.sourceSlug,\n    rawBody: options.rawBody,\n    rawPayload: options.rawPayload,\n    headers: options.headers ?? {},\n    startedAt: Date.now(),\n    fieldsCreated: 0,\n    fieldsMatched: 0,\n    warnings: [],\n    events: [],\n    ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),\n    ...(options.skipDedup ? { skipDedup: true } : {}),\n    ...(options.skipSpamFilter ? { skipSpamFilter: true } : {}),\n    ...(options.replayOfLogId ? { replayOfLogId: options.replayOfLogId } : {}),\n  };\n\n  const pipeline = createPipeline(new CoreApiClient(), new MetadataApiClient());\n  const result = await pipeline.run(ctx);\n\n  if (result.ok) return { ok: true, ctx: result.value };\n\n  await recordFailure(ctx, result.error);\n  return { ok: false, error: result.error, ctx };\n}\n\n/**\n * Log a terminal outcome.\n *\n * Two cases deliberately write nothing. An unknown slug has no source to attach\n * a log to, and logging it anyway would let anyone fill the workspace with rows\n * by POSTing to invented URLs. A duplicate is already represented by the log of\n * the request that succeeded; recording the retry as well would double-count\n * every ingestion in the dashboard.\n */\nasync function recordFailure(ctx: PipelineContext, error: AppError): Promise<void> {\n  if (error.code === 'SOURCE_NOT_FOUND') return;\n  if (error.code === 'DUPLICATE_PAYLOAD') return;\n\n  const details = (error.details ?? {}) as { spamScore?: number; reason?: string };\n  const quarantined = error.code === 'QUARANTINED';\n  const status: LogStatus = quarantined ? 'QUARANTINED' : 'FAILED';\n\n  await writeIntakeLog({\n    ctx,\n    status,\n    error: `${error.code}: ${error.message}`,\n    spamScore: details.spamScore ?? null,\n    quarantineReason: quarantined ? (details.reason ?? error.message) : null,\n  });\n\n  // A quarantine is the filter working, not the source breaking. Counting it as\n  // a failure would make a well-defended form look like a broken one.\n  if (ctx.source && !quarantined) await bumpSourceCounters(ctx.source.id, 'failed');\n}\n\n/**\n * The HTTP status for a terminal error.\n *\n * A quarantine answers 202: the request was well-formed and has been accepted\n * for review. Returning an error instead would tell a bot which of its attempts\n * were detected, and would show a real person a failure on a form that in fact\n * went through and is waiting for someone to look at it.\n */\nexport function statusCodeFor(code: string): number {\n  switch (code) {\n    case 'INVALID_SIGNATURE': return 401;\n    case 'SOURCE_NOT_FOUND': return 404;\n    case 'SOURCE_PAUSED': return 423;\n    case 'DUPLICATE_PAYLOAD': return 200;\n    case 'QUARANTINED': return 202;\n    case 'NO_STORED_PAYLOAD': return 400;\n    default: return 500;\n  }\n}\n\n/** Pull a caller-supplied idempotency key off the header or the body. */\nexport function idempotencyKeyFrom(\n  headers: Record<string, string | undefined> | undefined,\n  body: Record<string, unknown>,\n): string | undefined {\n  const header = headers?.['idempotency-key'] ?? headers?.['Idempotency-Key'];\n  const fromBody = body['idempotencyKey'];\n  const key = header ?? (typeof fromBody === 'string' ? fromBody : undefined);\n  const trimmed = key?.trim();\n  if (!trimmed) return undefined;\n  return trimmed.slice(0, 255);\n}\n\n/** The success body shared by the webhook and every replay-shaped endpoint. */\nexport function successBody(ctx: PipelineContext, startedAt: number): Record<string, unknown> {\n  return {\n    success: true,\n    recordId: ctx.personId ?? ctx.companyId,\n    recordType: ctx.recordType,\n    personId: ctx.personId,\n    companyId: ctx.companyId,\n    opportunityId: ctx.opportunityId,\n    noteId: ctx.noteId,\n    fieldsCreated: ctx.fieldsCreated,\n    fieldsMatched: ctx.fieldsMatched,\n    overflowCount: ctx.noteFields?.length ?? 0,\n    spamScore: ctx.spam?.score ?? null,\n    mergeDecisions: ctx.mergeDecisions ?? null,\n    processingMs: Date.now() - startedAt,\n    warnings: ctx.warnings,\n  };\n}\n", "import type { PipelineStage, PipelineContext } from '../pipeline';\nimport type { Result } from '../result';\nimport { ok, err, ErrorCode } from '../result';\nimport type { MergePolicy } from '../settings';\nimport type { CoreApiClient } from 'twenty-client-sdk/core';\n\nconst BASE_FIELDS = {\n  id: true,\n  name: true,\n  slug: true,\n  targetObject: true,\n  webhookSecret: true,\n  status: true,\n  createOpportunity: true,\n  opportunityNameTemplate: true,\n} as const;\n\nconst V4_FIELDS = {\n  ...BASE_FIELDS,\n  honeypotField: true,\n  mergePolicy: true,\n} as const;\n\ntype SourceNode = {\n  id: string;\n  name: string;\n  slug: string;\n  targetObject: string;\n  webhookSecret: string | null;\n  status: string;\n  createOpportunity: boolean | null;\n  opportunityNameTemplate: string | null;\n  honeypotField?: string | null;\n  mergePolicy?: string | null;\n};\n\nexport class LoadSourceStage implements PipelineStage {\n  readonly name = 'load-source';\n\n  constructor(private readonly client: CoreApiClient) {}\n\n  async execute(ctx: PipelineContext): Promise<Result<PipelineContext>> {\n    const node = await this.fetch(ctx.sourceSlug);\n\n    if (!node) {\n      return err(ErrorCode.SOURCE_NOT_FOUND, `No Intake source found with slug \"${ctx.sourceSlug}\"`);\n    }\n\n    if (node.status === 'PAUSED') {\n      return err(ErrorCode.SOURCE_PAUSED, `Source \"${node.name}\" is paused`);\n    }\n\n    return ok({\n      ...ctx,\n      source: {\n        id: node.id,\n        name: node.name,\n        slug: node.slug,\n        targetObject: node.targetObject as 'PERSON' | 'COMPANY' | 'AUTO',\n        webhookSecret: node.webhookSecret ?? null,\n        status: node.status as 'ACTIVE' | 'PAUSED',\n        createOpportunity: node.createOpportunity ?? true,\n        opportunityNameTemplate: node.opportunityNameTemplate ?? '{{source}} \u2014 {{firstName}} {{lastName}}',\n        honeypotField: node.honeypotField ?? null,\n        mergePolicy: parseMergePolicy(node.mergePolicy),\n      },\n    });\n  }\n\n  /**\n   * Ask for the 0.4.0 columns, and fall back to the original set if they are not\n   * there yet. A workspace that upgraded the package but has not re-synced its\n   * schema would otherwise fail the query and reject every request as an unknown\n   * source \u2014 an upgrade that takes the webhook offline, which is not acceptable\n   * for something sitting in front of someone's contact form.\n   */\n  private async fetch(slug: string): Promise<SourceNode | null> {\n    const args = { filter: { slug: { eq: slug } } };\n\n    try {\n      const result = await this.client.query({\n        intakeSources: { __args: args, edges: { node: V4_FIELDS } },\n      });\n      return result.intakeSources?.edges?.[0]?.node ?? null;\n    } catch {\n      try {\n        const result = await this.client.query({\n          intakeSources: { __args: args, edges: { node: BASE_FIELDS } },\n        });\n        return result.intakeSources?.edges?.[0]?.node ?? null;\n      } catch {\n        return null;\n      }\n    }\n  }\n}\n\nfunction parseMergePolicy(raw: string | null | undefined): MergePolicy | null {\n  switch ((raw ?? '').toUpperCase()) {\n    case 'PRESERVE': return 'PRESERVE';\n    case 'NEWEST_WINS': return 'NEWEST_WINS';\n    default: return null;\n  }\n}\n", "export type TwentyFieldType =\n  | 'TEXT'\n  | 'NUMBER'\n  | 'BOOLEAN'\n  | 'DATE'\n  | 'DATE_TIME'\n  | 'EMAILS'\n  | 'PHONES'\n  | 'LINKS'\n  | 'FULL_NAME'\n  | 'ADDRESS'\n  | 'SELECT'\n  | 'CURRENCY'\n  | 'RATING'\n  | 'RICH_TEXT'\n  | 'RAW_JSON';\n\nexport type FieldAction = 'field' | 'note' | 'skip';\n\nexport type FieldMapEntry = {\n  canonicalName: string;\n  twentyType: TwentyFieldType;\n  action: FieldAction;\n};\n\n/**\n * Normalise an incoming key to its lookup form:\n * camelCase \u2192 snake_case, hyphens/spaces \u2192 underscores, lowercase.\n * e.g. \"phoneNumber\" \u2192 \"phone_number\", \"E-Mail\" \u2192 \"e_mail\", \"Email\" \u2192 \"email\"\n *\n * The underscore is inserted *between* characters, never before the first one.\n * Prefixing every capital unconditionally turned a key that merely started with\n * one \u2014 `Email`, `Phone`, `First Name`, the default labels of most form builders\n * \u2014 into `_email`, which matches nothing in the map. Those payloads fell through\n * to passthrough and produced a person with an `extEmail` column and no email\n * address on the record: unreachable, and re-created from scratch on every\n * submission because dedup runs on `emails.primaryEmail`.\n *\n * Two passes handle the two shapes of a capital: one that follows a lowercase\n * letter or digit (`phoneNumber`), and a run of capitals followed by a word\n * (`XMLHttpRequest`). An all-caps key like `EMAIL` has neither and lowercases\n * cleanly. Leading underscores that were in the key to begin with survive, so\n * the `_id` skip entry still matches.\n */\nexport function normaliseKey(key: string): string {\n  return key\n    .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n    .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n    .toLowerCase()\n    .replace(/[-\\s.]/g, '_')\n    .replace(/_{2,}/g, '_');\n}\n\nexport const FIELD_MAP: Record<string, FieldMapEntry> = {\n  // \u2500\u2500 Phone \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  phone:                { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  phone_number:         { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  tel:                  { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  telephone:            { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  mobile:               { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  mobile_number:        { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  cell:                 { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  cell_phone:           { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  contact_phone:        { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  phone1:               { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n  primary_phone:        { canonicalName: 'phone', twentyType: 'PHONES', action: 'field' },\n\n  // \u2500\u2500 Email \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  email:                { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  email_address:        { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  e_mail:               { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  contact_email:        { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  email1:               { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  user_email:           { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n  primary_email:        { canonicalName: 'email', twentyType: 'EMAILS', action: 'field' },\n\n  // \u2500\u2500 First name \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  first_name:           { canonicalName: 'firstName', twentyType: 'TEXT', action: 'field' },\n  fname:                { canonicalName: 'firstName', twentyType: 'TEXT', action: 'field' },\n  given_name:           { canonicalName: 'firstName', twentyType: 'TEXT', action: 'field' },\n  forename:             { canonicalName: 'firstName', twentyType: 'TEXT', action: 'field' },\n\n  // \u2500\u2500 Last name \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  last_name:            { canonicalName: 'lastName', twentyType: 'TEXT', action: 'field' },\n  lname:                { canonicalName: 'lastName', twentyType: 'TEXT', action: 'field' },\n  surname:              { canonicalName: 'lastName', twentyType: 'TEXT', action: 'field' },\n  family_name:          { canonicalName: 'lastName', twentyType: 'TEXT', action: 'field' },\n\n  // \u2500\u2500 Full name (will be split on ingest) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  name:                 { canonicalName: 'fullName', twentyType: 'FULL_NAME', action: 'field' },\n  full_name:            { canonicalName: 'fullName', twentyType: 'FULL_NAME', action: 'field' },\n  contact_name:         { canonicalName: 'fullName', twentyType: 'FULL_NAME', action: 'field' },\n  your_name:            { canonicalName: 'fullName', twentyType: 'FULL_NAME', action: 'field' },\n\n  // \u2500\u2500 Company \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  company:              { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  company_name:         { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  business:             { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  business_name:        { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  organization:         { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  organisation:         { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  employer:             { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n  firm:                 { canonicalName: 'companyName', twentyType: 'TEXT', action: 'field' },\n\n  // \u2500\u2500 Website / Domain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  website:              { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  website_url:          { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  url:                  { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  domain:               { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  homepage:             { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  web:                  { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  site:                 { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n  site_url:             { canonicalName: 'domainName', twentyType: 'LINKS', action: 'field' },\n\n  // \u2500\u2500 Address \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  street:               { canonicalName: 'addressStreet1', twentyType: 'TEXT', action: 'field' },\n  street_address:       { canonicalName: 'addressStreet1', twentyType: 'TEXT', action: 'field' },\n  address_line_1:       { canonicalName: 'addressStreet1', twentyType: 'TEXT', action: 'field' },\n  address1:             { canonicalName: 'addressStreet1', twentyType: 'TEXT', action: 'field' },\n  address_line_2:       { canonicalName: 'addressStreet2', twentyType: 'TEXT', action: 'field' },\n  address2:             { canonicalName: 'addressStreet2', twentyType: 'TEXT', action: 'field' },\n  city:                 { canonicalName: 'addressCity', twentyType: 'TEXT', action: 'field' },\n  address_city:         { canonicalName: 'addressCity', twentyType: 'TEXT', action: 'field' },\n  town:                 { canonicalName: 'addressCity', twentyType: 'TEXT', action: 'field' },\n  state:                { canonicalName: 'addressState', twentyType: 'TEXT', action: 'field' },\n  province:             { canonicalName: 'addressState', twentyType: 'TEXT', action: 'field' },\n  region:               { canonicalName: 'addressState', twentyType: 'TEXT', action: 'field' },\n  address_state:        { canonicalName: 'addressState', twentyType: 'TEXT', action: 'field' },\n  zip:                  { canonicalName: 'addressPostcode', twentyType: 'TEXT', action: 'field' },\n  zip_code:             { canonicalName: 'addressPostcode', twentyType: 'TEXT', action: 'field' },\n  postal_code:          { canonicalName: 'addressPostcode', twentyType: 'TEXT', action: 'field' },\n  postcode:             { canonicalName: 'addressPostcode', twentyType: 'TEXT', action: 'field' },\n  country:              { canonicalName: 'addressCountry', twentyType: 'TEXT', action: 'field' },\n  address_country:      { canonicalName: 'addressCountry', twentyType: 'TEXT', action: 'field' },\n\n  // \u2500\u2500 Social \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  linkedin:             { canonicalName: 'linkedInLink', twentyType: 'LINKS', action: 'field' },\n  linkedin_url:         { canonicalName: 'linkedInLink', twentyType: 'LINKS', action: 'field' },\n  linkedin_profile:     { canonicalName: 'linkedInLink', twentyType: 'LINKS', action: 'field' },\n  twitter:              { canonicalName: 'xLink', twentyType: 'LINKS', action: 'field' },\n  twitter_url:          { canonicalName: 'xLink', twentyType: 'LINKS', action: 'field' },\n  x_profile:            { canonicalName: 'xLink', twentyType: 'LINKS', action: 'field' },\n\n  // \u2500\u2500 Pipeline-specific (Google / business intel) \u2500\u2500\u2500\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  google_places_url:    { canonicalName: 'extGooglePlacesUrl', twentyType: 'LINKS', action: 'field' },\n  places_url:           { canonicalName: 'extGooglePlacesUrl', twentyType: 'LINKS', action: 'field' },\n  google_maps_url:      { canonicalName: 'extGooglePlacesUrl', twentyType: 'LINKS', action: 'field' },\n  maps_url:             { canonicalName: 'extGooglePlacesUrl', twentyType: 'LINKS', action: 'field' },\n  rating:               { canonicalName: 'extGoogleRating', twentyType: 'NUMBER', action: 'field' },\n  google_rating:        { canonicalName: 'extGoogleRating', twentyType: 'NUMBER', action: 'field' },\n  stars:                { canonicalName: 'extGoogleRating', twentyType: 'NUMBER', action: 'field' },\n  review_count:         { canonicalName: 'extReviewCount', twentyType: 'NUMBER', action: 'field' },\n  reviews_count:        { canonicalName: 'extReviewCount', twentyType: 'NUMBER', action: 'field' },\n  total_reviews:        { canonicalName: 'extReviewCount', twentyType: 'NUMBER', action: 'field' },\n  num_reviews:          { canonicalName: 'extReviewCount', twentyType: 'NUMBER', action: 'field' },\n  marketing_score:      { canonicalName: 'extMarketingScore', twentyType: 'NUMBER', action: 'field' },\n  lead_score:           { canonicalName: 'extLeadScore', twentyType: 'NUMBER', action: 'field' },\n  analyzed_url:         { canonicalName: 'extAnalyzedUrl', twentyType: 'LINKS', action: 'field' },\n\n  // \u2500\u2500 UTM \u2014 always captured in note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  utm_source:           { canonicalName: 'utm_source', twentyType: 'TEXT', action: 'note' },\n  utm_medium:           { canonicalName: 'utm_medium', twentyType: 'TEXT', action: 'note' },\n  utm_campaign:         { canonicalName: 'utm_campaign', twentyType: 'TEXT', action: 'note' },\n  utm_content:          { canonicalName: 'utm_content', twentyType: 'TEXT', action: 'note' },\n  utm_term:             { canonicalName: 'utm_term', twentyType: 'TEXT', action: 'note' },\n  ref:                  { canonicalName: 'ref', twentyType: 'TEXT', action: 'note' },\n  referrer:             { canonicalName: 'referrer', twentyType: 'TEXT', action: 'note' },\n  source_page:          { canonicalName: 'source_page', twentyType: 'TEXT', action: 'note' },\n  landing_page:         { canonicalName: 'landing_page', twentyType: 'TEXT', action: 'note' },\n\n  // \u2500\u2500 Known note fields \u2014 always prose \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  message:              { canonicalName: 'message', twentyType: 'RICH_TEXT', action: 'note' },\n  description:          { canonicalName: 'description', twentyType: 'RICH_TEXT', action: 'note' },\n  analysis:             { canonicalName: 'analysis', twentyType: 'RICH_TEXT', action: 'note' },\n  notes:                { canonicalName: 'notes', twentyType: 'RICH_TEXT', action: 'note' },\n  comments:             { canonicalName: 'comments', twentyType: 'RICH_TEXT', action: 'note' },\n  summary:              { canonicalName: 'summary', twentyType: 'RICH_TEXT', action: 'note' },\n  inquiry:              { canonicalName: 'inquiry', twentyType: 'RICH_TEXT', action: 'note' },\n  body:                 { canonicalName: 'body', twentyType: 'RICH_TEXT', action: 'note' },\n  details:              { canonicalName: 'details', twentyType: 'RICH_TEXT', action: 'note' },\n  content:              { canonicalName: 'content', twentyType: 'RICH_TEXT', action: 'note' },\n  text:                 { canonicalName: 'text', twentyType: 'RICH_TEXT', action: 'note' },\n  feedback:             { canonicalName: 'feedback', twentyType: 'RICH_TEXT', action: 'note' },\n  about:                { canonicalName: 'about', twentyType: 'RICH_TEXT', action: 'note' },\n  additional_info:      { canonicalName: 'additional_info', twentyType: 'RICH_TEXT', action: 'note' },\n\n  // \u2500\u2500 System / internal \u2014 skip entirely \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  _id:                  { canonicalName: '_id', twentyType: 'TEXT', action: 'skip' },\n  __v:                  { canonicalName: '__v', twentyType: 'TEXT', action: 'skip' },\n  created_at:           { canonicalName: 'createdAt', twentyType: 'DATE_TIME', action: 'skip' },\n  updated_at:           { canonicalName: 'updatedAt', twentyType: 'DATE_TIME', action: 'skip' },\n  form_id:              { canonicalName: 'form_id', twentyType: 'TEXT', action: 'skip' },\n  submission_id:        { canonicalName: 'submission_id', twentyType: 'TEXT', action: 'skip' },\n  token:                { canonicalName: 'token', twentyType: 'TEXT', action: 'skip' },\n  password:             { canonicalName: 'password', twentyType: 'TEXT', action: 'skip' },\n  secret:               { canonicalName: 'secret', twentyType: 'TEXT', action: 'skip' },\n} as const;\n", "import type { PipelineStage, PipelineContext } from '../pipeline';\nimport type { NormalizedField, TargetObject } from '../normalizer';\nimport type { Result } from '../result';\nimport { ok } from '../result';\nimport { metaApi } from '../rest-client';\nimport { FIELD_MAP } from '../../constants/field-map';\n\n/**\n * Names the app already knows how to place on a person or company.\n *\n * Two groups, and both matter. The literals are the Twenty field names written\n * directly. The FIELD_MAP values are the *pre-composite* canonical names \u2014\n * `email`, `phone`, `addressCity` \u2014 which never appear on the object because\n * assembleComposites folds them into `emails`, `phones` and `address` later.\n * Deriving them from the map rather than restating them is what stops a new\n * built-in mapping from being mistaken for an unknown field and diverted into\n * the note, which would quietly create people with no email address.\n */\nconst STANDARD_FIELDS = new Set<string>([\n  'name', 'emails', 'phones', 'domainName', 'address',\n  'linkedInLink', 'xLink', 'companyName', 'firstName', 'lastName', 'fullName',\n  'jobTitle', 'city', 'employees', 'annualRecurringRevenue', 'idealCustomerProfile',\n  ...Object.values(FIELD_MAP).map((e) => e.canonicalName),\n]);\n\n/** Standard Opportunity fields the upsert stage writes directly. */\nconst STANDARD_OPPORTUNITY_FIELDS = new Set(['name', 'stage', 'amount', 'closeDate']);\n\nconst EXT_RE = /^ext[A-Z]/;\n\nexport class SyncSchemaStage implements PipelineStage {\n  readonly name = 'sync-schema';\n\n  private objectCache = new Map<string, { id: string; fields: Set<string>; at: number }>();\n  private readonly TTL = 5 * 60 * 1000;\n\n  async execute(ctx: PipelineContext): Promise<Result<PipelineContext>> {\n    if (!ctx.crmFields || ctx.crmFields.length === 0) return ok(ctx);\n\n    const primary = this.primaryTarget(ctx);\n    const creationEnabled = process.env['INTAKE_FIELD_CREATION_ENABLED'] !== 'false';\n    if (!creationEnabled) {\n      ctx.warnings.push('Field creation disabled by INTAKE_FIELD_CREATION_ENABLED setting \u2014 ext fields skipped');\n    }\n\n    // Resolve every field's destination up front, so the rest of the pipeline\n    // never has to re-derive it. `auto` collapses onto the primary record.\n    const resolved: NormalizedField[] = ctx.crmFields.map((f) => ({\n      ...f,\n      targetObject: this.resolveTarget(f.targetObject, primary, ctx),\n    }));\n\n    let fieldsCreated = 0;\n    let fieldsMatched = 0;\n    const demoted: NormalizedField[] = [];\n\n    for (const objectName of this.targetObjects(resolved)) {\n      const fields = resolved.filter((f) => f.targetObject === objectName);\n      if (fields.length === 0) continue;\n\n      const standardForObject = objectName === 'opportunity'\n        ? STANDARD_OPPORTUNITY_FIELDS\n        : STANDARD_FIELDS;\n\n      const meta = await this.getObjectMeta(objectName);\n      if (!meta) {\n        for (const f of fields) {\n          if (standardForObject.has(f.canonicalName)) { f.writable = true; fieldsMatched++; continue; }\n          ctx.warnings.push(`Could not read schema for ${objectName} \u2014 \"${f.canonicalName}\" goes to note`);\n          demoted.push(f);\n        }\n        continue;\n      }\n\n      const maxExt = parseInt(process.env['INTAKE_MAX_EXT_FIELDS'] ?? '50', 10);\n      let extCount = [...meta.fields].filter((f) => EXT_RE.test(f)).length;\n\n      for (const field of fields) {\n        const name = field.canonicalName;\n\n        // Standard fields are written by the upsert stage directly.\n        if (standardForObject.has(name)) { field.writable = true; fieldsMatched++; continue; }\n\n        // Already on the object \u2014 whether an ext field from an earlier run or a\n        // field created by hand that a rule now points at.\n        if (meta.fields.has(name)) { field.writable = true; fieldsMatched++; continue; }\n\n        // Not present. Only ext-prefixed names are auto-created: minting a field\n        // for any name a rule happens to contain would turn a typo into a\n        // permanent schema change.\n        if (!EXT_RE.test(name)) {\n          ctx.warnings.push(\n            `Field \"${name}\" does not exist on ${objectName} and is not ext-prefixed \u2014 value routed to note. ` +\n            `Create the field in Twenty first, or rename the rule's canonical name to ext${name.charAt(0).toUpperCase()}${name.slice(1)}.`,\n          );\n          demoted.push(field);\n          continue;\n        }\n\n        if (!creationEnabled) { demoted.push(field); continue; }\n\n        if (extCount >= maxExt) {\n          ctx.warnings.push(`ext field limit (${maxExt}) reached for ${objectName} \u2014 \"${name}\" goes to note`);\n          demoted.push(field);\n          continue;\n        }\n\n        const created = await this.createField(meta.id, name, field.twentyType);\n        if (created) {\n          meta.fields.add(name);\n          this.objectCache.get(objectName)?.fields.add(name);\n          extCount++;\n          fieldsCreated++;\n          field.writable = true;\n        } else {\n          ctx.warnings.push(`Could not create field \"${name}\" on ${objectName} \u2014 will go to note`);\n          demoted.push(field);\n        }\n      }\n    }\n\n    // A field we cannot write is not \"matched\" \u2014 it is note overflow. Moving it\n    // here is what keeps the value from disappearing between the two stages.\n    const demotedSet = new Set(demoted);\n    return ok({\n      ...ctx,\n      crmFields: resolved.filter((f) => !demotedSet.has(f)),\n      noteFields: [...(ctx.noteFields ?? []), ...demoted],\n      fieldsCreated,\n      fieldsMatched,\n    });\n  }\n\n  /** Where an `auto` field lands: the person, or the company for company-only payloads. */\n  private primaryTarget(ctx: PipelineContext): 'person' | 'company' {\n    const t = ctx.source?.targetObject ?? 'AUTO';\n    if (t === 'PERSON') return 'person';\n    if (t === 'COMPANY') return 'company';\n\n    // For structured payloads (pipeline app), extras are company-level data\n    if (ctx.structuredCompany) return 'company';\n\n    const hasPersonData = ctx.crmFields?.some((f) =>\n      ['firstName', 'lastName', 'email', 'phone', 'fullName', 'emails', 'phones', 'name'].includes(f.canonicalName));\n    const hasCompanyData = ctx.crmFields?.some((f) =>\n      ['companyName', 'domainName'].includes(f.canonicalName));\n\n    if (hasPersonData) return 'person';\n    if (hasCompanyData) return 'company';\n    return 'person';\n  }\n\n  private resolveTarget(\n    target: TargetObject,\n    primary: 'person' | 'company',\n    ctx: PipelineContext,\n  ): TargetObject {\n    if (target === 'auto') return primary;\n    // A field routed to the deal has nowhere to go when the source does not open\n    // one, so it falls back to the primary record instead of being lost.\n    if (target === 'opportunity' && !ctx.source?.createOpportunity) {\n      ctx.warnings.push('Field routed to opportunity but this source does not create opportunities \u2014 written to the primary record instead');\n      return primary;\n    }\n    return target;\n  }\n\n  private targetObjects(fields: NormalizedField[]): string[] {\n    const seen = new Set<string>();\n    for (const f of fields) if (f.targetObject !== 'auto') seen.add(f.targetObject);\n    return [...seen];\n  }\n\n  private async getObjectMeta(objectName: string): Promise<{ id: string; fields: Set<string> } | null> {\n    const cached = this.objectCache.get(objectName);\n    if (cached && Date.now() - cached.at < this.TTL) return cached;\n\n    try {\n      // Metadata API returns all objects \u2014 filter client-side by nameSingular\n      const res = await metaApi.get<Array<{ id: string; nameSingular: string; fields: Array<{ name: string }> }>>('/objects');\n      const objects = Array.isArray(res) ? res : (res as { data: typeof res }).data ?? [];\n      const node = (objects as Array<{ id: string; nameSingular: string; fields: Array<{ name: string }> }>)\n        .find(o => o.nameSingular === objectName);\n      if (!node) return null;\n      const fields = new Set<string>((node.fields ?? []).map((f: { name: string }) => f.name));\n      const entry = { id: node.id, fields, at: Date.now() };\n      this.objectCache.set(objectName, entry);\n      return entry;\n    } catch {\n      return null;\n    }\n  }\n\n  private async createField(objectMetadataId: string, name: string, type: string): Promise<boolean> {\n    try {\n      await metaApi.post('/fields', {\n        objectMetadataId,\n        name,\n        label: toLabel(name),\n        type,\n        description: 'Auto-created by Intake',\n        icon: 'IconPlug',\n      });\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n\nfunction toLabel(name: string): string {\n  return name.replace(/^ext_/, '').replace(/_/g, ' ')\n    .replace(/([A-Z])/g, ' $1').split(' ')\n    .map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n    .join(' ').trim();\n}\n", "/**\n * Re-running a payload that was already received.\n *\n * The problem this solves is a mapping added too late. A field arrives for weeks\n * with no rule to place it, goes into the overflow note, and the day someone\n * writes the rule it only applies to what comes next \u2014 everything already in the\n * CRM has to be repaired by hand from note text, if it can be repaired at all.\n * Replay runs the stored payloads back through the rules as they exist now, so\n * the fix reaches the records that needed it.\n *\n * Distinct from retry, which exists for failures and refuses a log that already\n * succeeded. Replay is for logs that succeeded: the run worked, the mapping was\n * simply not there yet.\n */\n\nimport { coreApi } from './rest-client';\nimport { runIngestion } from './ingest';\nimport { replayMaxBatch } from './settings';\n\nexport type StoredLog = {\n  id: string;\n  status: string;\n  rawPayload: string | null;\n  intakeSourceId: string | null;\n  processedAt: string | null;\n};\n\nexport type ReplayResult = {\n  logId: string;\n  ok: boolean;\n  reason?: string;\n  recordId?: string | undefined;\n  personId?: string | undefined;\n  companyId?: string | undefined;\n  opportunityId?: string | undefined;\n  fieldsCreated?: number;\n  warnings?: string[];\n};\n\nexport async function loadLog(logId: string): Promise<StoredLog | null> {\n  try {\n    const res = await coreApi.get<{ data: { intakeLog: StoredLog } }>(`/intakeLogs/${logId}`);\n    return res.data?.intakeLog ?? null;\n  } catch {\n    return null;\n  }\n}\n\nexport async function slugForSource(sourceId: string | null): Promise<string | null> {\n  if (!sourceId) return null;\n  try {\n    const res = await coreApi.get<{ data: { intakeSource: { slug: string } } }>(`/intakeSources/${sourceId}`);\n    return res.data?.intakeSource?.slug ?? null;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Replay one stored log.\n *\n * Deduplication is bypassed, because the payload is by definition one we have\n * seen \u2014 that is the whole point. Spam scoring is not bypassed: a payload that\n * would be quarantined today should still be quarantined when it is replayed.\n */\nexport async function replayLog(log: StoredLog): Promise<ReplayResult> {\n  if (!log.rawPayload) {\n    return {\n      logId: log.id,\n      ok: false,\n      reason: 'No stored payload \u2014 retention was off, or the payload exceeded the size cap when it arrived',\n    };\n  }\n\n  let payload: Record<string, unknown>;\n  try {\n    const parsed: unknown = JSON.parse(log.rawPayload);\n    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n      return { logId: log.id, ok: false, reason: 'Stored payload is not a JSON object' };\n    }\n    payload = parsed as Record<string, unknown>;\n  } catch {\n    return { logId: log.id, ok: false, reason: 'Stored payload is not valid JSON' };\n  }\n\n  const slug = await slugForSource(log.intakeSourceId);\n  if (!slug) {\n    return { logId: log.id, ok: false, reason: 'The source for this log no longer exists' };\n  }\n\n  const outcome = await runIngestion({\n    sourceSlug: slug,\n    rawPayload: payload,\n    // The signature was checked when the payload first arrived; there is no body\n    // to re-verify against and the request is now coming from an authenticated\n    // operator rather than the network.\n    skipDedup: true,\n    replayOfLogId: log.id,\n  });\n\n  if (!outcome.ok) {\n    return { logId: log.id, ok: false, reason: `${outcome.error.code}: ${outcome.error.message}` };\n  }\n\n  return {\n    logId: log.id,\n    ok: true,\n    recordId: outcome.ctx.personId ?? outcome.ctx.companyId,\n    personId: outcome.ctx.personId,\n    companyId: outcome.ctx.companyId,\n    opportunityId: outcome.ctx.opportunityId,\n    fieldsCreated: outcome.ctx.fieldsCreated,\n    warnings: outcome.ctx.warnings,\n  };\n}\n\nexport type BulkQuery = {\n  sourceSlug?: string | undefined;\n  status?: string | undefined;\n  since?: string | undefined;\n  until?: string | undefined;\n  limit?: number | undefined;\n};\n\n/**\n * Select logs for a bulk replay.\n *\n * Capped by INTAKE_REPLAY_MAX_BATCH, and the cap is not negotiable from the\n * request: a replay writes to the CRM for every log it touches, and an\n * unbounded one aimed at a year of history would rewrite a workspace in a single\n * call. Callers wanting more run several batches and can see what each one did.\n */\nexport async function selectLogs(query: BulkQuery): Promise<StoredLog[]> {\n  const max = replayMaxBatch();\n  const limit = Math.min(query.limit ?? max, max);\n\n  const filters: string[] = [];\n  if (query.status) filters.push(`status[eq]:${encodeURIComponent(query.status)}`);\n  if (query.since) filters.push(`processedAt[gte]:${encodeURIComponent(query.since)}`);\n  if (query.until) filters.push(`processedAt[lte]:${encodeURIComponent(query.until)}`);\n\n  if (query.sourceSlug) {\n    const sourceId = await idForSlug(query.sourceSlug);\n    if (!sourceId) return [];\n    filters.push(`intakeSourceId[eq]:${sourceId}`);\n  }\n\n  const qs = [\n    filters.length > 0 ? `filter=${filters.join(',')}` : '',\n    `orderBy=processedAt[AscNullsLast]`,\n    `limit=${limit}`,\n  ].filter(Boolean).join('&');\n\n  try {\n    const res = await coreApi.get<{ data: { intakeLogs: { edges: Array<{ node: StoredLog }> } } }>(\n      `/intakeLogs?${qs}`,\n    );\n    return (res.data?.intakeLogs?.edges ?? []).map((e) => e.node);\n  } catch {\n    return [];\n  }\n}\n\nasync function idForSlug(slug: string): Promise<string | null> {\n  try {\n    const res = await coreApi.get<{ data: { intakeSources: { edges: Array<{ node: { id: string } }> } } }>(\n      `/intakeSources?filter=slug[eq]:${encodeURIComponent(slug)}&first=1`,\n    );\n    return res.data?.intakeSources?.edges?.[0]?.node?.id ?? null;\n  } catch {\n    return null;\n  }\n}\n", "import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define';\nimport { IDS } from '../constants/universal-identifiers';\nimport { coreApi } from '../lib/rest-client';\nimport { loadLog } from '../lib/replay';\n\n/**\n * Mark a held payload as junk.\n *\n * The log is marked DISCARDED, not deleted. Keeping it is what lets the filter\n * be judged later \u2014 a run of discards is evidence the threshold is right, and a\n * discard sitting next to a release is evidence it is not. Deleting the row\n * would throw away the only record of how well the thing is working.\n *\n * `purgePayload` drops the stored body while keeping the row, for anyone who\n * would rather not retain the contents of obvious spam.\n */\nconst handler = async (params: RoutePayload) => {\n  const logId = params.pathParameters?.['logId'];\n  if (!logId) return { statusCode: 400, body: { error: 'Missing logId in URL' } };\n\n  const body = (params.body ?? {}) as Record<string, unknown>;\n  const purgePayload = body['purgePayload'] === true;\n\n  const log = await loadLog(logId);\n  if (!log) return { statusCode: 404, body: { error: `IntakeLog ${logId} not found` } };\n\n  if (log.status !== 'QUARANTINED') {\n    return {\n      statusCode: 400,\n      body: { error: `Log ${logId} is ${log.status}, not QUARANTINED \u2014 nothing to discard`, status: log.status },\n    };\n  }\n\n  try {\n    await coreApi.patch(`/intakeLogs/${logId}`, {\n      status: 'DISCARDED',\n      ...(purgePayload ? { rawPayload: null } : {}),\n    });\n  } catch (e) {\n    return { statusCode: 500, body: { error: `Could not discard log: ${String(e)}` } };\n  }\n\n  return {\n    statusCode: 200,\n    body: {\n      success: true,\n      logId,\n      status: 'DISCARDED',\n      payloadPurged: purgePayload,\n    },\n  };\n};\n\nexport default defineLogicFunction({\n  universalIdentifier: IDS.QUARANTINE_DISCARD_LOGIC_FUNCTION,\n  name: 'intake-quarantine-discard',\n  description: 'Mark a quarantined payload as junk, optionally purging the stored body.',\n  timeoutSeconds: 15,\n  handler,\n  httpRouteTriggerSettings: {\n    path: '/intake/quarantine/:logId/discard',\n    httpMethod: 'POST',\n    isAuthRequired: true,\n  },\n});\n"],
  "mappings": "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",
  "names": []
}
