{
  "version": 3,
  "sources": ["../../../../node_modules/@sniptt/guards/lib/guards/primitives.ts", "../../../../node_modules/@sniptt/guards/lib/guards/structural.ts", "../../../../node_modules/@sniptt/guards/lib/guards/convenience.ts", "../../../../node_modules/@sniptt/guards/lib/index.ts", "twenty-sdk-define-stub:__twenty-sdk-define-stub__", "../../../../src/logic-functions/constants/granola-sync.ts", "../../../../src/constants/universal-identifiers.ts", "../../../../src/logic-functions/handlers/granola-sync-handler.ts", "../../../../src/constants/granola-connection.ts", "../../../../src/logic-functions/utils/run-core-graphql.ts", "../../../../src/utils/is-defined.ts", "../../../../src/logic-functions/utils/granola-connection-store.ts", "../../../../src/logic-functions/utils/list-granola-notes.ts", "../../../../src/logic-functions/utils/granola-api-request.ts", "../../../../src/logic-functions/utils/sync-granola-note-to-call-recording.ts", "../../../../src/logic-functions/constants/call-recording-status.ts", "../../../../src/logic-functions/utils/deterministic-uuid-v4.ts", "../../../../src/logic-functions/utils/compute-call-recording-id-for-granola-meeting.ts", "../../../../src/logic-functions/utils/fetch-granola-note.ts", "../../../../src/logic-functions/utils/find-matching-calendar-event.ts", "../../../../src/logic-functions/utils/map-granola-transcript-to-turns.ts", "../../../../src/logic-functions/utils/resolve-companies.ts", "../../../../src/logic-functions/utils/chunk.ts", "../../../../src/logic-functions/utils/resolve-opportunities.ts", "../../../../src/logic-functions/utils/resolve-people-by-email.ts", "../../../../src/logic-functions/utils/upsert-call-recording.ts", "../../../../src/logic-functions/utils/compute-note-id-for-granola-meeting.ts", "../../../../src/logic-functions/utils/compute-note-target-id.ts", "../../../../src/logic-functions/utils/upsert-note-with-targets.ts", "../../../../src/logic-functions/utils/run-granola-sync.ts", "../../../../src/logic-functions/utils/run-sync-for-all-connections.ts", "../../../../src/logic-functions/granola-sync.ts"],
  "sourcesContent": [null, null, null, null, "\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 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", "// Cron cadence. Must divide 60 evenly so `*/N * * * *` fires on a stable grid.\nexport const GRANOLA_CRON_INTERVAL_MINUTES = 15;\n\n// How far back the post-install backfill reaches.\nexport const GRANOLA_BACKFILL_DAYS = 30;\n\n// Extra look-back added to each incremental run so a note updated between ticks\n// is never missed (idempotent thanks to deterministic ids).\nexport const GRANOLA_SYNC_OVERLAP_MINUTES = 30;\n\n// Once per day the cron widens its window to this many hours to catch notes that\n// were only ever updated during a longer poll gap.\nexport const GRANOLA_RESWEEP_HOURS = 24;\n\n// UTC hour at which the daily wider re-sweep runs.\nexport const GRANOLA_RESWEEP_UTC_HOUR = 0;\n", "export const APPLICATION_UNIVERSAL_IDENTIFIER =\n  '79738d7c-6b48-47fd-949f-de6510e3137d';\n\nexport const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER =\n  '43e9f830-3b8e-4af6-ae29-1520d86f6903';\n\nexport const GRANOLA_SYNC_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER =\n  'e3b3aa22-b36a-4c5b-a02e-4d36e43524d4';\n\nexport const GRANOLA_BACKFILL_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER =\n  'f50358d3-3e94-4933-bbed-f94b05311b7f';\n\n// Per-user Granola API keys. Each workspace member connects their own account;\n// the sync enumerates every connection and pulls that member's meetings.\nexport const GRANOLA_CONNECTION_OBJECT_UNIVERSAL_IDENTIFIER =\n  'fbaf8a1c-c53e-4a86-bfbf-31b773c1a838';\n\nexport const GRANOLA_CONNECTION_FIELD_UNIVERSAL_IDENTIFIERS = {\n  name: '32c08eee-f433-4027-bf7e-f36f2f6b49f6',\n  workspaceMemberId: '6126dadc-9462-4901-b8d0-b9cdf25abd83',\n  apiKey: 'ff502f4b-a889-46fc-8d41-108e78e10827',\n  isActive: '4bbb3104-122c-45d3-a278-d8e72cff031d',\n  lastSyncedAt: '2321678a-f090-4688-bf91-4b57f83a33d8',\n  lastSyncStatus: 'ba88113f-1639-4e8e-af39-da18a695b37f',\n  lastSyncError: '59cea986-0a5b-42e1-ae49-a1a8f8cb982f',\n} as const;\n\nexport const GRANOLA_CONNECTION_LOGIC_FUNCTIONS = {\n  setKey: {\n    universalIdentifier: '04a667fa-07c7-46fa-a589-56f47a9a4131',\n    path: '/granola/connection/set-key',\n  },\n  getConnection: {\n    universalIdentifier: '73535e55-5400-41ce-bd8e-65840e4224ea',\n    path: '/granola/connection/get',\n  },\n  disconnect: {\n    universalIdentifier: '6cc6511f-5b9c-4bd2-b010-75b9ece3d937',\n    path: '/granola/connection/disconnect',\n  },\n} as const;\n\nexport const GRANOLA_CONNECT_COMMAND_MENU_ITEM_UNIVERSAL_IDENTIFIER =\n  '0ac3a91c-76a2-45d9-903d-2d6f18c59c1f';\n\nexport const GRANOLA_CONNECT_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER =\n  'cf44e138-08ba-42bf-8144-a130d3f7448d';\n\n// Shared core CalendarEvent record page layout that apps attach tabs to.\nexport const CALENDAR_EVENT_RECORD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIER =\n  'b9b10e40-9ce2-4704-8ac6-c6e92e2563c1';\n\nexport const CALENDAR_EVENT_SUMMARY_PAGE_LAYOUT_TAB_UNIVERSAL_IDENTIFIER =\n  '73bd93e8-379e-4f04-a7cf-72965f1c1984';\n\nexport const CALENDAR_EVENT_SUMMARY_PAGE_LAYOUT_WIDGET_UNIVERSAL_IDENTIFIER =\n  '04780500-8a23-43de-b8bd-04e0e5f6dac8';\n\nexport const CALENDAR_EVENT_SUMMARY_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER =\n  '0233043a-8284-495c-98cf-9b2380ee063a';\n\nexport const CALENDAR_EVENT_TRANSCRIPT_PAGE_LAYOUT_TAB_UNIVERSAL_IDENTIFIER =\n  '5a57429d-6ade-441d-8c35-512616793a2f';\n\nexport const CALENDAR_EVENT_TRANSCRIPT_PAGE_LAYOUT_WIDGET_UNIVERSAL_IDENTIFIER =\n  '8768103e-b059-44ee-b72e-bc164b954511';\n\nexport const CALENDAR_EVENT_TRANSCRIPT_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER =\n  'bea81361-5df7-4c1f-984d-73274957bd5d';\n", "import { CoreApiClient } from 'twenty-client-sdk/core';\n\nimport {\n  GRANOLA_CRON_INTERVAL_MINUTES,\n  GRANOLA_RESWEEP_HOURS,\n  GRANOLA_RESWEEP_UTC_HOUR,\n  GRANOLA_SYNC_OVERLAP_MINUTES,\n} from 'src/logic-functions/constants/granola-sync';\nimport {\n  type RunSyncForAllConnectionsResult,\n  runSyncForAllConnections,\n} from 'src/logic-functions/utils/run-sync-for-all-connections';\n\nconst MINUTE_MS = 60_000;\nconst HOUR_MS = 3_600_000;\n\n// Incremental window plus, once per day, a wider re-sweep so a note that was only\n// updated during a longer poll gap is still caught without any runtime state.\nexport const computeUpdatedAfter = (now: Date): string => {\n  const incrementalMs =\n    (GRANOLA_CRON_INTERVAL_MINUTES + GRANOLA_SYNC_OVERLAP_MINUTES) * MINUTE_MS;\n  let sinceMs = now.getTime() - incrementalMs;\n\n  const isDailyResweep =\n    now.getUTCHours() === GRANOLA_RESWEEP_UTC_HOUR &&\n    now.getUTCMinutes() < GRANOLA_CRON_INTERVAL_MINUTES;\n\n  if (isDailyResweep) {\n    sinceMs = Math.min(sinceMs, now.getTime() - GRANOLA_RESWEEP_HOURS * HOUR_MS);\n  }\n\n  return new Date(sinceMs).toISOString();\n};\n\nexport const granolaSyncHandler =\n  async (): Promise<RunSyncForAllConnectionsResult> => {\n    const now = new Date();\n\n    return runSyncForAllConnections({\n      client: new CoreApiClient(),\n      updatedAfter: computeUpdatedAfter(now),\n      syncedAtIso: now.toISOString(),\n    });\n  };\n", "// Sync status stamped on each GranolaConnection after a run so admins and the\n// owner can see whether that member's last poll succeeded.\nexport const GRANOLA_SYNC_STATUS = {\n  ok: 'OK',\n  error: 'ERROR',\n} as const;\n\nexport type GranolaSyncStatus =\n  (typeof GRANOLA_SYNC_STATUS)[keyof typeof GRANOLA_SYNC_STATUS];\n", "import { isNonEmptyString } from '@sniptt/guards';\n\n// The generated (Zeus) client is built from the workspace's GraphQL\n// introspection, which does NOT expose this app's own custom object\n// (granolaConnection) \u2014 so client.query({ granolaConnections }) fails client-side\n// with \"type Query does not have a field granolaConnections\". The server DOES\n// have the type, so we talk to it directly with a raw GraphQL request using the\n// application access token the function runs with. Standard objects still use\n// the typed client; only granolaConnection goes through here.\nconst API_URL_ENV = 'TWENTY_API_URL';\nconst TOKEN_ENV_VARS = ['TWENTY_APP_ACCESS_TOKEN', 'TWENTY_API_KEY'] as const;\n\nconst getToken = (): string | undefined => {\n  for (const envVar of TOKEN_ENV_VARS) {\n    const value = process.env[envVar];\n\n    if (isNonEmptyString(value)) {\n      return value;\n    }\n  }\n\n  return undefined;\n};\n\nexport const runCoreGraphql = async <TData>(\n  query: string,\n  variables?: Record<string, unknown>,\n): Promise<TData> => {\n  const apiUrl = process.env[API_URL_ENV]?.replace(/\\/$/, '');\n  const token = getToken();\n\n  if (!isNonEmptyString(apiUrl) || !isNonEmptyString(token)) {\n    throw new Error(\n      'Granola: missing API URL or access token in the function environment.',\n    );\n  }\n\n  const response = await fetch(`${apiUrl}/graphql`, {\n    method: 'POST',\n    headers: {\n      'content-type': 'application/json',\n      authorization: `Bearer ${token}`,\n    },\n    body: JSON.stringify({ query, ...(variables ? { variables } : {}) }),\n  });\n\n  const payload = (await response.json()) as {\n    data?: TData;\n    errors?: unknown;\n  };\n\n  if (payload.errors) {\n    throw new Error(\n      `Granola GraphQL error: ${JSON.stringify(payload.errors).slice(0, 300)}`,\n    );\n  }\n\n  return payload.data as TData;\n};\n", "export const isDefined = <T>(\n  value: T | null | undefined,\n): value is NonNullable<T> => value !== null && value !== undefined;\n", "import { type GranolaSyncStatus } from 'src/constants/granola-connection';\nimport { runCoreGraphql } from 'src/logic-functions/utils/run-core-graphql';\nimport { isDefined } from 'src/utils/is-defined';\n\nexport type GranolaConnectionNode = {\n  id: string;\n  workspaceMemberId: string;\n  apiKey: string;\n  isActive: boolean;\n  lastSyncedAt: string | null;\n  lastSyncStatus: string | null;\n};\n\n// granolaConnection is this app's OWN custom object. The workspace GraphQL\n// introspection the generated client is built from does not expose it, so we\n// query it with raw GraphQL against the server (which does have the type).\nconst CONNECTION_NODE_FRAGMENT = `\n  id\n  workspaceMemberId\n  apiKey\n  isActive\n  lastSyncedAt\n  lastSyncStatus\n`;\n\nconst ACTIVE_CONNECTIONS_PAGE_SIZE = 100;\n\ntype ConnectionEdges = {\n  granolaConnections?: {\n    edges?: { node?: Partial<GranolaConnectionNode> | null }[] | null;\n    pageInfo?: { hasNextPage?: boolean | null; endCursor?: string | null };\n  };\n};\n\nconst toNode = (\n  node: Partial<GranolaConnectionNode> | null | undefined,\n): GranolaConnectionNode | undefined => {\n  if (!isDefined(node) || !isDefined(node.id)) {\n    return undefined;\n  }\n\n  return {\n    id: node.id,\n    workspaceMemberId: node.workspaceMemberId ?? '',\n    apiKey: node.apiKey ?? '',\n    isActive: node.isActive ?? false,\n    lastSyncedAt: node.lastSyncedAt ?? null,\n    lastSyncStatus: node.lastSyncStatus ?? null,\n  };\n};\n\nexport const findConnectionByMemberId = async (\n  workspaceMemberId: string,\n): Promise<GranolaConnectionNode | undefined> => {\n  const result = await runCoreGraphql<ConnectionEdges>(\n    `query FindGranolaConnection($filter: GranolaConnectionFilterInput) {\n      granolaConnections(filter: $filter, first: 1) {\n        edges { node { ${CONNECTION_NODE_FRAGMENT} } }\n      }\n    }`,\n    { filter: { workspaceMemberId: { eq: workspaceMemberId } } },\n  );\n\n  return toNode(result.granolaConnections?.edges?.[0]?.node);\n};\n\n// Lists every active connection, paging through all members so the sync covers\n// the whole workspace.\nexport const listActiveConnections = async (): Promise<\n  GranolaConnectionNode[]\n> => {\n  const connections: GranolaConnectionNode[] = [];\n  let after: string | undefined;\n\n  for (;;) {\n    const result = await runCoreGraphql<ConnectionEdges>(\n      `query ListActiveGranolaConnections($filter: GranolaConnectionFilterInput, $first: Int, $after: String) {\n        granolaConnections(filter: $filter, first: $first, after: $after) {\n          edges { node { ${CONNECTION_NODE_FRAGMENT} } }\n          pageInfo { hasNextPage endCursor }\n        }\n      }`,\n      {\n        filter: { isActive: { eq: true } },\n        first: ACTIVE_CONNECTIONS_PAGE_SIZE,\n        after: after ?? null,\n      },\n    );\n\n    for (const edge of result.granolaConnections?.edges ?? []) {\n      const node = toNode(edge?.node);\n\n      if (isDefined(node)) {\n        connections.push(node);\n      }\n    }\n\n    const pageInfo = result.granolaConnections?.pageInfo;\n\n    if (pageInfo?.hasNextPage !== true || !isDefined(pageInfo.endCursor)) {\n      break;\n    }\n\n    after = pageInfo.endCursor;\n  }\n\n  return connections;\n};\n\nconst updateConnection = async (\n  id: string,\n  data: Record<string, unknown>,\n): Promise<void> => {\n  await runCoreGraphql(\n    `mutation UpdateGranolaConnection($id: UUID!, $data: GranolaConnectionUpdateInput!) {\n      updateGranolaConnection(id: $id, data: $data) { id }\n    }`,\n    { id, data },\n  );\n};\n\nexport const upsertConnection = async ({\n  workspaceMemberId,\n  displayName,\n  apiKey,\n}: {\n  workspaceMemberId: string;\n  displayName: string;\n  apiKey: string;\n}): Promise<void> => {\n  const existing = await findConnectionByMemberId(workspaceMemberId);\n\n  if (isDefined(existing)) {\n    await updateConnection(existing.id, {\n      apiKey,\n      name: displayName,\n      isActive: true,\n    });\n\n    return;\n  }\n\n  await runCoreGraphql(\n    `mutation CreateGranolaConnection($data: GranolaConnectionCreateInput!) {\n      createGranolaConnection(data: $data) { id }\n    }`,\n    { data: { workspaceMemberId, apiKey, name: displayName, isActive: true } },\n  );\n};\n\nexport const deactivateConnection = async (\n  workspaceMemberId: string,\n): Promise<boolean> => {\n  const existing = await findConnectionByMemberId(workspaceMemberId);\n\n  if (!isDefined(existing)) {\n    return false;\n  }\n\n  // Clear the stored key on disconnect so it no longer lives in the workspace,\n  // and flag inactive so the sync skips it.\n  await updateConnection(existing.id, { apiKey: '', isActive: false });\n\n  return true;\n};\n\nexport const stampSyncResult = async (\n  connectionId: string,\n  {\n    syncedAt,\n    status,\n    error,\n  }: { syncedAt: string; status: GranolaSyncStatus; error: string | null },\n): Promise<void> => {\n  await updateConnection(connectionId, {\n    lastSyncedAt: syncedAt,\n    lastSyncStatus: status,\n    lastSyncError: error,\n  });\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { isDefined } from 'src/utils/is-defined';\n\nimport {\n  type GranolaNoteSummary,\n  type GranolaNotesListResponse,\n} from 'src/logic-functions/types/granola-note.type';\nimport {\n  type GranolaApiResult,\n  granolaApiRequest,\n} from 'src/logic-functions/utils/granola-api-request';\n\n// Granola caps page_size at 30.\nconst GRANOLA_MAX_PAGE_SIZE = 30;\n// Safety valve so a pagination bug can never spin forever.\nconst MAX_PAGES = 500;\n\nexport type ListGranolaNotesArgs = {\n  apiKey: string;\n  updatedAfter?: string;\n  createdAfter?: string;\n  folderId?: string;\n  pageSize?: number;\n  // Injectable for tests.\n  sleep?: (milliseconds: number) => Promise<void>;\n};\n\nconst readNotes = (response: GranolaNotesListResponse): GranolaNoteSummary[] =>\n  response.notes ?? [];\n\n// Enumerates every note matching the filters, following the response `cursor`\n// while `hasMore` is set, to exhaustion.\nexport const listGranolaNotes = async ({\n  apiKey,\n  updatedAfter,\n  createdAfter,\n  folderId,\n  pageSize = GRANOLA_MAX_PAGE_SIZE,\n  sleep,\n}: ListGranolaNotesArgs): Promise<GranolaApiResult<GranolaNoteSummary[]>> => {\n  const boundedPageSize = Math.min(\n    Math.max(pageSize, 1),\n    GRANOLA_MAX_PAGE_SIZE,\n  );\n\n  const notes: GranolaNoteSummary[] = [];\n  let cursor: string | undefined;\n  let lastStatus = 200;\n\n  for (let page = 0; page < MAX_PAGES; page += 1) {\n    const result = await granolaApiRequest<GranolaNotesListResponse>({\n      apiKey,\n      path: '/notes',\n      query: {\n        page_size: boundedPageSize,\n        updated_after: updatedAfter,\n        created_after: createdAfter,\n        folder_id: folderId,\n        cursor,\n      },\n      sleep,\n    });\n\n    if (!result.ok) {\n      return result;\n    }\n\n    lastStatus = result.status;\n    notes.push(...readNotes(result.data));\n\n    // Stop when the API signals no further pages.\n    if (result.data.hasMore === false) {\n      break;\n    }\n\n    const nextCursor = result.data.cursor ?? undefined;\n\n    // Guard against a cursor that fails to advance, which would otherwise\n    // spin re-fetching the same page until MAX_PAGES.\n    if (!isNonEmptyString(nextCursor) || nextCursor === cursor) {\n      break;\n    }\n\n    cursor = nextCursor;\n  }\n\n  return { ok: true, status: lastStatus, data: notes };\n};\n\nexport const isListGranolaNotesEmpty = (\n  result: GranolaApiResult<GranolaNoteSummary[]>,\n): boolean => result.ok && (!isDefined(result.data) || result.data.length === 0);\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { isDefined } from 'src/utils/is-defined';\n\nexport const GRANOLA_API_BASE_URL = 'https://public-api.granola.ai/v1';\n\nconst DEFAULT_MAX_RETRIES = 4;\nconst DEFAULT_BACKOFF_BASE_MS = 500;\n// Upper bound on any single retry sleep, whether derived from a\n// server-supplied Retry-After header or from exponential backoff.\nconst MAX_BACKOFF_MS = 30_000;\n\ntype GranolaApiSuccess<TData> = {\n  ok: true;\n  status: number;\n  data: TData;\n};\n\ntype GranolaApiFailure = {\n  ok: false;\n  status: number;\n  errorMessage: string;\n};\n\nexport type GranolaApiResult<TData> =\n  | GranolaApiSuccess<TData>\n  | GranolaApiFailure;\n\nexport type GranolaApiRequestParams = {\n  apiKey: string;\n  // Path relative to the API base, e.g. '/notes' or `/notes/${id}`.\n  path: string;\n  query?: Record<string, string | number | undefined>;\n  maxRetries?: number;\n  backoffBaseMs?: number;\n  // Injectable for tests; defaults to a real timer-based sleep.\n  sleep?: (milliseconds: number) => Promise<void>;\n};\n\nconst realSleep = (milliseconds: number): Promise<void> =>\n  new Promise((resolve) => setTimeout(resolve, milliseconds));\n\nconst buildUrl = (\n  path: string,\n  query: Record<string, string | number | undefined> | undefined,\n): string => {\n  const url = new URL(`${GRANOLA_API_BASE_URL}${path}`);\n\n  if (isDefined(query)) {\n    for (const [key, value] of Object.entries(query)) {\n      if (isDefined(value)) {\n        url.searchParams.set(key, String(value));\n      }\n    }\n  }\n\n  return url.toString();\n};\n\nconst computeBackoffMs = (\n  response: Response,\n  attempt: number,\n  backoffBaseMs: number,\n): number => {\n  const retryAfterHeader = response.headers.get('retry-after');\n  const retryAfterSeconds =\n    retryAfterHeader !== null ? Number(retryAfterHeader) : NaN;\n\n  if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0) {\n    return Math.min(retryAfterSeconds * 1000, MAX_BACKOFF_MS);\n  }\n\n  // Exponential backoff: base * 2^attempt.\n  return Math.min(backoffBaseMs * 2 ** attempt, MAX_BACKOFF_MS);\n};\n\n// Granola error responses carry a structured body { code, message, details }.\n// Surface the message when present, else fall back to the HTTP status.\nconst readGranolaErrorMessage = async (response: Response): Promise<string> => {\n  try {\n    const body = (await response.json()) as { message?: unknown };\n\n    if (isNonEmptyString(body.message)) {\n      return `Granola API error (HTTP ${response.status}): ${body.message}`;\n    }\n  } catch {\n    // Non-JSON error body; fall through to the generic message.\n  }\n\n  return `Granola API responded with HTTP ${response.status}`;\n};\n\n// GET against the Granola REST API with Bearer auth, JSON parsing, and HTTP 429\n// retry-with-backoff. Returns a typed ok/err result.\nexport const granolaApiRequest = async <TData = unknown>({\n  apiKey,\n  path,\n  query,\n  maxRetries = DEFAULT_MAX_RETRIES,\n  backoffBaseMs = DEFAULT_BACKOFF_BASE_MS,\n  sleep = realSleep,\n}: GranolaApiRequestParams): Promise<GranolaApiResult<TData>> => {\n  const url = buildUrl(path, query);\n\n  for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n    let response: Response;\n\n    try {\n      response = await fetch(url, {\n        method: 'GET',\n        headers: {\n          Authorization: `Bearer ${apiKey}`,\n          Accept: 'application/json',\n        },\n      });\n    } catch (error) {\n      return {\n        ok: false,\n        status: 0,\n        errorMessage: `Granola API request failed: ${(error as Error).message}`,\n      };\n    }\n\n    if (response.status === 429) {\n      if (attempt < maxRetries) {\n        await sleep(computeBackoffMs(response, attempt, backoffBaseMs));\n        continue;\n      }\n\n      return {\n        ok: false,\n        status: 429,\n        errorMessage: `Granola API rate limit not cleared after ${maxRetries} retries`,\n      };\n    }\n\n    if (!response.ok) {\n      return {\n        ok: false,\n        status: response.status,\n        errorMessage: await readGranolaErrorMessage(response),\n      };\n    }\n\n    try {\n      const data = (await response.json()) as TData;\n\n      return { ok: true, status: response.status, data };\n    } catch (error) {\n      return {\n        ok: false,\n        status: response.status,\n        errorMessage: `Granola API returned a non-JSON response: ${\n          (error as Error).message\n        }`,\n      };\n    }\n  }\n\n  return {\n    ok: false,\n    status: 429,\n    errorMessage: `Granola API rate limit not cleared after ${maxRetries} retries`,\n  };\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { type CoreApiClient } from 'twenty-client-sdk/core';\nimport { isDefined } from 'src/utils/is-defined';\n\nimport {\n  CALL_RECORDING_REQUEST_STATUS,\n  CALL_RECORDING_STATUS,\n} from 'src/logic-functions/constants/call-recording-status';\nimport {\n  type GranolaAttendee,\n  type GranolaNoteDetail,\n} from 'src/logic-functions/types/granola-note.type';\nimport { computeCallRecordingIdForGranolaMeeting } from 'src/logic-functions/utils/compute-call-recording-id-for-granola-meeting';\nimport { fetchGranolaNote } from 'src/logic-functions/utils/fetch-granola-note';\nimport { findMatchingCalendarEvent } from 'src/logic-functions/utils/find-matching-calendar-event';\nimport { mapGranolaTranscriptToTurns } from 'src/logic-functions/utils/map-granola-transcript-to-turns';\nimport {\n  resolveCompanyIdsByEmailDomain,\n  resolveCompanyIdsForPeople,\n} from 'src/logic-functions/utils/resolve-companies';\nimport { resolveOpportunityIdsForPeople } from 'src/logic-functions/utils/resolve-opportunities';\nimport { resolvePeopleByEmail } from 'src/logic-functions/utils/resolve-people-by-email';\nimport {\n  type CallRecordingWriteFields,\n  upsertCallRecording,\n} from 'src/logic-functions/utils/upsert-call-recording';\nimport { upsertNoteWithTargets } from 'src/logic-functions/utils/upsert-note-with-targets';\n\nconst GRANOLA_NOTE_BASE_URL = 'https://notes.granola.ai/d';\n\nexport type SyncGranolaNoteResult =\n  | {\n      status: 'synced';\n      meetingId: string;\n      noteId: string;\n      noteCreated: boolean;\n      noteTargetCount: number;\n      callRecordingId: string;\n      callRecordingCreated: boolean;\n      calendarEventId?: string;\n    }\n  | { status: 'error'; meetingId: string; error: string };\n\nconst readAttendeeEmails = (\n  attendees: GranolaAttendee[] | null | undefined,\n): string[] =>\n  (attendees ?? [])\n    .map((attendee) => attendee.email)\n    .filter(isNonEmptyString);\n\n// Exported for testing. Granola-supplied URLs are attacker-controllable\n// (synced verbatim from the note), so only http(s) URLs are embedded in the\n// Note markdown link; anything else (or an unparseable URL) falls back to the\n// canonical Granola note URL. encodeURI guards against ')' or whitespace in\n// the URL breaking the surrounding `[View in Granola](...)` markdown syntax.\nexport const resolveWebUrl = (note: GranolaNoteDetail): string => {\n  const candidate = note.web_url;\n  const fallbackUrl = `${GRANOLA_NOTE_BASE_URL}/${encodeURIComponent(note.id)}`;\n\n  if (!isNonEmptyString(candidate)) {\n    return fallbackUrl;\n  }\n\n  try {\n    const parsed = new URL(candidate);\n\n    if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n      return fallbackUrl;\n    }\n\n    return encodeURI(candidate);\n  } catch {\n    return fallbackUrl;\n  }\n};\n\nconst resolveTitle = (note: GranolaNoteDetail): string => {\n  const title = note.title?.trim();\n\n  return isNonEmptyString(title) ? title : 'Granola meeting';\n};\n\nconst buildNoteBodyMarkdown = (note: GranolaNoteDetail): string => {\n  const sections: string[] = [`[View in Granola](${resolveWebUrl(note)})`];\n\n  const summaryMarkdown = note.summary_markdown?.trim();\n\n  if (isNonEmptyString(summaryMarkdown)) {\n    sections.push(summaryMarkdown);\n  }\n\n  return sections.join('\\n\\n');\n};\n\nconst buildTimestampFields = (\n  note: GranolaNoteDetail,\n): Pick<CallRecordingWriteFields, 'startedAt' | 'endedAt'> => {\n  const calendarEvent = note.calendar_event;\n\n  const startCandidate =\n    calendarEvent?.scheduled_start_time ?? note.created_at;\n  const endCandidate = calendarEvent?.scheduled_end_time;\n\n  const fields: Pick<CallRecordingWriteFields, 'startedAt' | 'endedAt'> = {};\n\n  if (isNonEmptyString(startCandidate)) {\n    fields.startedAt = startCandidate;\n  }\n\n  if (isNonEmptyString(endCandidate)) {\n    fields.endedAt = endCandidate;\n  }\n\n  return fields;\n};\n\nconst buildSummaryField = (\n  note: GranolaNoteDetail,\n): Pick<CallRecordingWriteFields, 'summary'> => {\n  const summaryMarkdown = note.summary_markdown?.trim();\n\n  if (!isNonEmptyString(summaryMarkdown)) {\n    return {};\n  }\n\n  return { summary: { markdown: summaryMarkdown, blocknote: null } };\n};\n\n// Orchestrates one meeting: always upserts a Note + NoteTargets for resolved\n// participants, and always upserts a CallRecording (summary + transcript turns),\n// linked to the matched CalendarEvent when one exists.\nexport const syncGranolaNoteToCallRecording = async ({\n  apiKey,\n  client,\n  meetingId,\n  sleep,\n}: {\n  apiKey: string;\n  client: CoreApiClient;\n  meetingId: string;\n  sleep?: (milliseconds: number) => Promise<void>;\n}): Promise<SyncGranolaNoteResult> => {\n  const fetchResult = await fetchGranolaNote({ apiKey, noteId: meetingId, sleep });\n\n  if (!fetchResult.ok) {\n    return { status: 'error', meetingId, error: fetchResult.errorMessage };\n  }\n\n  const note = fetchResult.data;\n\n  try {\n    const emails = readAttendeeEmails(note.attendees);\n    const personIdByEmail = await resolvePeopleByEmail({ client, emails });\n    const personIds = [...new Set(personIdByEmail.values())];\n\n    const [companyIdsFromPeople, companyIdsFromDomains, opportunityIds] =\n      await Promise.all([\n        resolveCompanyIdsForPeople({ client, personIds }),\n        resolveCompanyIdsByEmailDomain({ client, emails }),\n        resolveOpportunityIdsForPeople({ client, personIds }),\n      ]);\n    const companyIds = [\n      ...new Set([...companyIdsFromPeople, ...companyIdsFromDomains]),\n    ];\n\n    const noteResult = await upsertNoteWithTargets({\n      client,\n      meetingId,\n      title: resolveTitle(note),\n      bodyMarkdown: buildNoteBodyMarkdown(note),\n      personIds,\n      companyIds,\n      opportunityIds,\n    });\n\n    const match = await findMatchingCalendarEvent({\n      client,\n      calendarEvent: note.calendar_event,\n    });\n    const calendarEventId = match.matched ? match.calendarEventId : undefined;\n\n    const callRecordingId = computeCallRecordingIdForGranolaMeeting(meetingId);\n    const turns = mapGranolaTranscriptToTurns(\n      note.transcript,\n      note.owner?.name ?? undefined,\n    );\n\n    const sharedFields: CallRecordingWriteFields = {\n      title: resolveTitle(note),\n      externalRecordingId: meetingId,\n      transcript: { turns },\n      ...buildTimestampFields(note),\n      ...buildSummaryField(note),\n      ...(isDefined(calendarEventId) ? { calendarEventId } : {}),\n    };\n\n    const upsertResult = await upsertCallRecording(client, {\n      id: callRecordingId,\n      createFields: {\n        ...sharedFields,\n        recordingRequestStatus: CALL_RECORDING_REQUEST_STATUS.REQUESTED,\n        status: CALL_RECORDING_STATUS.COMPLETED,\n      },\n      updateFields: {\n        ...sharedFields,\n        status: CALL_RECORDING_STATUS.COMPLETED,\n      },\n    });\n\n    return {\n      status: 'synced',\n      meetingId,\n      noteId: noteResult.noteId,\n      noteCreated: noteResult.noteCreated,\n      noteTargetCount: noteResult.noteTargetIds.length,\n      callRecordingId: upsertResult.callRecordingId,\n      callRecordingCreated: upsertResult.created,\n      calendarEventId,\n    };\n  } catch (error) {\n    return {\n      status: 'error',\n      meetingId,\n      error: `Failed to sync Granola note ${meetingId}: ${\n        (error as Error).message\n      }`,\n    };\n  }\n};\n", "// TODO: duplicated from core CallRecording select options \u2014 import once a shared package exists.\nexport const CALL_RECORDING_STATUS = {\n  PROCESSING: 'PROCESSING',\n  COMPLETED: 'COMPLETED',\n} as const;\n\nexport const CALL_RECORDING_REQUEST_STATUS = {\n  REQUESTED: 'REQUESTED',\n} as const;\n", "import { createHash } from 'crypto';\n\n// Hashes the given namespace/id parts into a stable, v4-shaped UUID. Callers\n// join their own namespace prefix (e.g. \"granola:\") into `parts` so distinct\n// entities never collide on the same hash.\nexport const deterministicUuidV4 = (...parts: string[]): string => {\n  const bytes = createHash('sha256').update(parts.join(':')).digest();\n\n  // v4 version/variant bits so server-side UUID validation accepts the hash.\n  bytes[6] = (bytes[6] & 0x0f) | 0x40;\n  bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n  const hex = bytes.subarray(0, 16).toString('hex');\n\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n};\n", "import { deterministicUuidV4 } from 'src/logic-functions/utils/deterministic-uuid-v4';\n\n// Same Granola meeting \u2192 same id, so every sync converges on one CallRecording.\n// Distinct namespace (\"granola:\") from the Fireflies template so the two apps\n// never collide on a shared meeting.\nexport const computeCallRecordingIdForGranolaMeeting = (\n  granolaMeetingId: string,\n): string => deterministicUuidV4('granola', granolaMeetingId);\n", "import { type GranolaNoteDetail } from 'src/logic-functions/types/granola-note.type';\nimport {\n  type GranolaApiResult,\n  granolaApiRequest,\n} from 'src/logic-functions/utils/granola-api-request';\n\nexport type FetchGranolaNoteArgs = {\n  apiKey: string;\n  noteId: string;\n  // Injectable for tests.\n  sleep?: (milliseconds: number) => Promise<void>;\n};\n\n// Fetches one note with its transcript, summary, attendees, and calendar event.\nexport const fetchGranolaNote = async ({\n  apiKey,\n  noteId,\n  sleep,\n}: FetchGranolaNoteArgs): Promise<GranolaApiResult<GranolaNoteDetail>> =>\n  granolaApiRequest<GranolaNoteDetail>({\n    apiKey,\n    path: `/notes/${encodeURIComponent(noteId)}`,\n    query: { include: 'transcript' },\n    sleep,\n  });\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { type CoreApiClient } from 'twenty-client-sdk/core';\nimport { isDefined } from 'src/utils/is-defined';\n\nimport { type GranolaCalendarEvent } from 'src/logic-functions/types/granola-note.type';\n\ntype CalendarChannelEventAssociationsConnection = {\n  edges: Array<{ node: { calendarEventId: string } }>;\n};\n\nconst findByEventExternalId = async (\n  client: CoreApiClient,\n  externalId: string,\n): Promise<string | null> => {\n  const { calendarChannelEventAssociations } = await client.query({\n    calendarChannelEventAssociations: {\n      __args: {\n        filter: {\n          eventExternalId: { eq: externalId },\n        },\n        first: 1,\n      },\n      edges: {\n        node: {\n          calendarEventId: true,\n        },\n      },\n    },\n  });\n\n  const node = (\n    calendarChannelEventAssociations as\n      | CalendarChannelEventAssociationsConnection\n      | undefined\n  )?.edges?.[0]?.node;\n\n  return node?.calendarEventId ?? null;\n};\n\n// Matches a Granola note's meeting to a Twenty CalendarEvent by the provider\n// (Outlook/Google) external event id that Granola exposes as\n// calendar_event.calendar_event_id, joined against\n// CalendarChannelEventAssociation.eventExternalId. Unmatched meetings still get\n// a CallRecording (unlinked) and an always-on Note for Person visibility.\nexport const findMatchingCalendarEvent = async ({\n  client,\n  calendarEvent,\n}: {\n  client: CoreApiClient;\n  calendarEvent: GranolaCalendarEvent | null | undefined;\n}): Promise<\n  | { matched: true; calendarEventId: string }\n  | { matched: false; reason: string }\n> => {\n  const externalId = calendarEvent?.calendar_event_id;\n\n  if (!isNonEmptyString(externalId)) {\n    return {\n      matched: false,\n      reason:\n        'The Granola note has no calendar_event.calendar_event_id, so no CalendarEvent could be matched. The CallRecording is created without a linked calendar event.',\n    };\n  }\n\n  const calendarEventId = await findByEventExternalId(client, externalId);\n\n  if (isDefined(calendarEventId)) {\n    return { matched: true, calendarEventId };\n  }\n\n  return {\n    matched: false,\n    reason:\n      'No CalendarEvent matched the Granola note by external event id. Either the meeting was never on a synced calendar, or its calendar sync (Google/Outlook/CalDAV) is not configured in Twenty. The CallRecording is created without a linked calendar event.',\n  };\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { isDefined } from 'src/utils/is-defined';\n\nimport { type GranolaTranscriptSegment } from 'src/logic-functions/types/granola-note.type';\n\nexport type GranolaTranscriptTurn = {\n  speaker: string;\n  text: string;\n};\n\nconst DEFAULT_LOCAL_SPEAKER = 'You';\nconst REMOTE_SPEAKER = 'Others';\n\n// Granola tags each segment's audio source: \"microphone\" is the note owner's\n// local mic, \"speaker\" is remote audio. There are no per-attendee names, so the\n// owner name (when known) labels the local side and everyone else is \"Others\".\nconst labelForSource = (\n  source: string | null | undefined,\n  ownerName?: string,\n): string => {\n  if (source === 'microphone') {\n    return isNonEmptyString(ownerName) ? ownerName : DEFAULT_LOCAL_SPEAKER;\n  }\n\n  return REMOTE_SPEAKER;\n};\n\n// Groups consecutive transcript segments sharing the same audio source into\n// ordered speaker turns. Null/empty/absent transcript \u2192 [].\nexport const mapGranolaTranscriptToTurns = (\n  transcript: GranolaTranscriptSegment[] | null | undefined,\n  ownerName?: string,\n): GranolaTranscriptTurn[] => {\n  if (!Array.isArray(transcript) || transcript.length === 0) {\n    return [];\n  }\n\n  const turns: GranolaTranscriptTurn[] = [];\n\n  for (const segment of transcript) {\n    const text = segment.text?.trim();\n\n    if (!isNonEmptyString(text)) {\n      continue;\n    }\n\n    const speaker = labelForSource(segment.speaker?.source, ownerName);\n    const lastTurn = turns[turns.length - 1];\n\n    if (isDefined(lastTurn) && lastTurn.speaker === speaker) {\n      lastTurn.text = `${lastTurn.text} ${text}`;\n    } else {\n      turns.push({ speaker, text });\n    }\n  }\n\n  return turns;\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { type CoreApiClient } from 'twenty-client-sdk/core';\n\nimport { chunk } from 'src/logic-functions/utils/chunk';\n\nconst QUERY_BATCH_SIZE = 30;\n\ntype CompanyEdges = { edges?: Array<{ node: { id?: string | null } }> };\ntype PeopleCompanyEdges = {\n  edges?: Array<{ node: { company?: { id?: string | null } | null } }>;\n};\n\nconst emailDomain = (email: string): string => {\n  const atIndex = email.indexOf('@');\n\n  return atIndex >= 0 ? email.slice(atIndex + 1).trim().toLowerCase() : '';\n};\n\n// Companies of the matched participants (Person -> Company relation).\nexport const resolveCompanyIdsForPeople = async ({\n  client,\n  personIds,\n}: {\n  client: CoreApiClient;\n  personIds: string[];\n}): Promise<string[]> => {\n  const companyIds = new Set<string>();\n\n  for (const batch of chunk(personIds, QUERY_BATCH_SIZE)) {\n    const result = (await client.query({\n      people: {\n        __args: { filter: { id: { in: batch } }, first: batch.length },\n        edges: { node: { company: { id: true } } },\n      },\n    })) as { people?: PeopleCompanyEdges };\n\n    for (const edge of result.people?.edges ?? []) {\n      const companyId = edge.node.company?.id;\n\n      if (isNonEmptyString(companyId)) {\n        companyIds.add(companyId);\n      }\n    }\n  }\n\n  return [...companyIds];\n};\n\n// Companies whose primary domain contains an attendee's email domain, so an\n// account is associated even when the attendee is not yet a Person record.\nexport const resolveCompanyIdsByEmailDomain = async ({\n  client,\n  emails,\n}: {\n  client: CoreApiClient;\n  emails: string[];\n}): Promise<string[]> => {\n  const domains = [\n    ...new Set(emails.map(emailDomain).filter((domain) => domain.length > 0)),\n  ];\n\n  const companyIds = new Set<string>();\n\n  for (const domain of domains) {\n    const result = (await client.query({\n      companies: {\n        __args: {\n          filter: { domainName: { primaryLinkUrl: { ilike: `%${domain}%` } } },\n          first: 5,\n        },\n        edges: { node: { id: true } },\n      },\n    })) as { companies?: CompanyEdges };\n\n    for (const edge of result.companies?.edges ?? []) {\n      if (isNonEmptyString(edge.node.id)) {\n        companyIds.add(edge.node.id);\n      }\n    }\n  }\n\n  return [...companyIds];\n};\n", "// Splits a list into fixed-size chunks so `in` filter lists stay bounded.\nexport const chunk = <TItem>(items: TItem[], size: number): TItem[][] => {\n  const chunks: TItem[][] = [];\n\n  for (let index = 0; index < items.length; index += size) {\n    chunks.push(items.slice(index, index + size));\n  }\n\n  return chunks;\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { type CoreApiClient } from 'twenty-client-sdk/core';\n\nimport { chunk } from 'src/logic-functions/utils/chunk';\n\nconst QUERY_BATCH_SIZE = 30;\n\ntype OpportunityEdges = { edges?: Array<{ node: { id?: string | null } }> };\n\n// Opportunities whose point of contact is one of the matched participants.\nexport const resolveOpportunityIdsForPeople = async ({\n  client,\n  personIds,\n}: {\n  client: CoreApiClient;\n  personIds: string[];\n}): Promise<string[]> => {\n  const opportunityIds = new Set<string>();\n\n  for (const batch of chunk(personIds, QUERY_BATCH_SIZE)) {\n    const result = (await client.query({\n      opportunities: {\n        __args: { filter: { pointOfContactId: { in: batch } }, first: 100 },\n        edges: { node: { id: true } },\n      },\n    })) as { opportunities?: OpportunityEdges };\n\n    for (const edge of result.opportunities?.edges ?? []) {\n      if (isNonEmptyString(edge.node.id)) {\n        opportunityIds.add(edge.node.id);\n      }\n    }\n  }\n\n  return [...opportunityIds];\n};\n", "import { isNonEmptyString } from '@sniptt/guards';\nimport { type CoreApiClient } from 'twenty-client-sdk/core';\n\ntype PersonNode = {\n  id: string;\n  emails?: { primaryEmail?: string | null } | null;\n};\n\ntype PeopleConnection = {\n  edges?: Array<{ node: PersonNode }>;\n};\n\n// People are queried in batches to keep the `in` filter list bounded.\nconst EMAIL_QUERY_BATCH_SIZE = 30;\n\nconst chunk = <T>(items: T[], size: number): T[][] => {\n  const chunks: T[][] = [];\n\n  for (let index = 0; index < items.length; index += size) {\n    chunks.push(items.slice(index, index + size));\n  }\n\n  return chunks;\n};\n\nconst normalizeEmail = (email: string): string => email.trim().toLowerCase();\n\n// Resolves attendee emails to existing Person ids. Returns a map keyed by the\n// normalized (lowercased) email so callers can look up per attendee. Emails\n// with no matching Person are simply absent from the map.\nexport const resolvePeopleByEmail = async ({\n  client,\n  emails,\n}: {\n  client: CoreApiClient;\n  emails: string[];\n}): Promise<Map<string, string>> => {\n  const normalizedEmails = [\n    ...new Set(\n      emails\n        .filter(isNonEmptyString)\n        .map(normalizeEmail)\n        .filter((email) => email.length > 0),\n    ),\n  ];\n\n  const personIdByEmail = new Map<string, string>();\n\n  if (normalizedEmails.length === 0) {\n    return personIdByEmail;\n  }\n\n  for (const batch of chunk(normalizedEmails, EMAIL_QUERY_BATCH_SIZE)) {\n    const queryResult = (await client.query({\n      people: {\n        __args: {\n          filter: { emails: { primaryEmail: { in: batch } } },\n          // Multiple Person rows can share the same email, so cap at 2x the\n          // batch size rather than batch.length to avoid silently truncating\n          // matches when duplicates exist.\n          first: batch.length * 2,\n        },\n        edges: {\n          node: {\n            id: true,\n            emails: { primaryEmail: true },\n          },\n        },\n      },\n    })) as { people?: PeopleConnection };\n\n    for (const edge of queryResult.people?.edges ?? []) {\n      const primaryEmail = edge.node.emails?.primaryEmail;\n\n      if (isNonEmptyString(primaryEmail) && isNonEmptyString(edge.node.id)) {\n        personIdByEmail.set(normalizeEmail(primaryEmail), edge.node.id);\n      }\n    }\n  }\n\n  return personIdByEmail;\n};\n", "import { type CoreApiClient } from 'twenty-client-sdk/core';\nimport { isDefined } from 'src/utils/is-defined';\n\nexport type CallRecordingWriteFields = {\n  title?: string;\n  status?: string;\n  recordingRequestStatus?: string;\n  externalRecordingId?: string;\n  startedAt?: string;\n  endedAt?: string;\n  transcript?: unknown;\n  summary?: { markdown: string; blocknote: null };\n  calendarEventId?: string;\n};\n\ntype UpsertCallRecordingResult = {\n  callRecordingId: string;\n  created: boolean;\n};\n\nconst findCallRecordingId = async (\n  client: CoreApiClient,\n  id: string,\n): Promise<string | undefined> => {\n  const queryResult = await client.query({\n    callRecordings: {\n      __args: {\n        filter: { id: { eq: id } },\n        first: 1,\n      },\n      edges: {\n        node: {\n          id: true,\n        },\n      },\n    },\n  });\n\n  return queryResult.callRecordings?.edges?.[0]?.node?.id ?? undefined;\n};\n\nconst updateCallRecording = async (\n  client: CoreApiClient,\n  id: string,\n  data: CallRecordingWriteFields,\n): Promise<void> => {\n  await client.mutation({\n    updateCallRecording: {\n      __args: { id, data },\n      id: true,\n    },\n  });\n};\n\nexport const upsertCallRecording = async (\n  client: CoreApiClient,\n  {\n    id,\n    createFields,\n    updateFields,\n  }: {\n    id: string;\n    createFields: CallRecordingWriteFields;\n    updateFields: CallRecordingWriteFields;\n  },\n): Promise<UpsertCallRecordingResult> => {\n  const existingId = await findCallRecordingId(client, id);\n\n  if (isDefined(existingId)) {\n    await updateCallRecording(client, id, updateFields);\n\n    return { callRecordingId: id, created: false };\n  }\n\n  try {\n    await client.mutation({\n      createCallRecording: {\n        __args: { data: { id, ...createFields } },\n        id: true,\n      },\n    });\n\n    return { callRecordingId: id, created: true };\n  } catch (error) {\n    // A concurrent create on the same deterministic id may have won the race.\n    const raceWinnerId = await findCallRecordingId(client, id);\n\n    if (!isDefined(raceWinnerId)) {\n      throw error;\n    }\n\n    await updateCallRecording(client, id, updateFields);\n\n    return { callRecordingId: id, created: false };\n  }\n};\n", "import { deterministicUuidV4 } from 'src/logic-functions/utils/deterministic-uuid-v4';\n\n// Deterministic Note id per Granola meeting so re-syncs update the same Note.\n// Distinct namespace (\"granola-note:\") from the CallRecording and NoteTarget ids.\nexport const computeNoteIdForGranolaMeeting = (\n  granolaMeetingId: string,\n): string => deterministicUuidV4('granola-note', granolaMeetingId);\n", "import { deterministicUuidV4 } from 'src/logic-functions/utils/deterministic-uuid-v4';\n\nexport type NoteTargetKind = 'person' | 'company' | 'opportunity';\n\n// Deterministic NoteTarget id per (meeting, kind, target) so re-syncs never\n// duplicate a link. Distinct namespace (\"granola-notetarget\") from the Note and\n// CallRecording ids; the kind keeps person/company/opportunity links disjoint.\nexport const computeNoteTargetId = (\n  granolaMeetingId: string,\n  kind: NoteTargetKind,\n  targetId: string,\n): string =>\n  deterministicUuidV4('granola-notetarget', kind, granolaMeetingId, targetId);\n", "import { type CoreApiClient } from 'twenty-client-sdk/core';\nimport { isDefined } from 'src/utils/is-defined';\n\nimport { computeNoteIdForGranolaMeeting } from 'src/logic-functions/utils/compute-note-id-for-granola-meeting';\nimport {\n  computeNoteTargetId,\n  type NoteTargetKind,\n} from 'src/logic-functions/utils/compute-note-target-id';\n\nexport type UpsertNoteWithTargetsArgs = {\n  client: CoreApiClient;\n  meetingId: string;\n  title: string;\n  bodyMarkdown: string;\n  personIds: string[];\n  companyIds: string[];\n  opportunityIds: string[];\n};\n\nexport type UpsertNoteWithTargetsResult = {\n  noteId: string;\n  noteCreated: boolean;\n  noteTargetIds: string[];\n};\n\ntype NoteTargetLink = { kind: NoteTargetKind; value: string };\n\ntype NoteWriteFields = {\n  title: string;\n  bodyV2: { markdown: string; blocknote: null };\n};\n\nconst findNoteId = async (\n  client: CoreApiClient,\n  id: string,\n): Promise<string | undefined> => {\n  const queryResult = await client.query({\n    notes: {\n      __args: { filter: { id: { eq: id } }, first: 1 },\n      edges: { node: { id: true } },\n    },\n  });\n\n  return queryResult.notes?.edges?.[0]?.node?.id ?? undefined;\n};\n\nconst updateNote = async (\n  client: CoreApiClient,\n  id: string,\n  data: NoteWriteFields,\n): Promise<void> => {\n  await client.mutation({\n    updateNote: {\n      __args: { id, data },\n      id: true,\n    },\n  });\n};\n\nconst upsertNote = async (\n  client: CoreApiClient,\n  id: string,\n  data: NoteWriteFields,\n): Promise<{ noteId: string; created: boolean }> => {\n  const existingId = await findNoteId(client, id);\n\n  if (isDefined(existingId)) {\n    await updateNote(client, id, data);\n\n    return { noteId: id, created: false };\n  }\n\n  try {\n    await client.mutation({\n      createNote: {\n        __args: { data: { id, ...data } },\n        id: true,\n      },\n    });\n\n    return { noteId: id, created: true };\n  } catch (error) {\n    // A concurrent create on the same deterministic id may have won the race.\n    const raceWinnerId = await findNoteId(client, id);\n\n    if (!isDefined(raceWinnerId)) {\n      throw error;\n    }\n\n    await updateNote(client, id, data);\n\n    return { noteId: id, created: false };\n  }\n};\n\nconst findNoteTargetId = async (\n  client: CoreApiClient,\n  id: string,\n): Promise<string | undefined> => {\n  const queryResult = await client.query({\n    noteTargets: {\n      __args: { filter: { id: { eq: id } }, first: 1 },\n      edges: { node: { id: true } },\n    },\n  });\n\n  return queryResult.noteTargets?.edges?.[0]?.node?.id ?? undefined;\n};\n\nconst createNoteTarget = async (\n  client: CoreApiClient,\n  id: string,\n  noteId: string,\n  link: NoteTargetLink,\n): Promise<void> => {\n  if (link.kind === 'person') {\n    await client.mutation({\n      createNoteTarget: {\n        __args: { data: { id, noteId, targetPersonId: link.value } },\n        id: true,\n      },\n    });\n\n    return;\n  }\n\n  if (link.kind === 'company') {\n    await client.mutation({\n      createNoteTarget: {\n        __args: { data: { id, noteId, targetCompanyId: link.value } },\n        id: true,\n      },\n    });\n\n    return;\n  }\n\n  await client.mutation({\n    createNoteTarget: {\n      __args: { data: { id, noteId, targetOpportunityId: link.value } },\n      id: true,\n    },\n  });\n};\n\n// Query-then-create so re-syncing a meeting leaves the NoteTarget count stable.\nconst ensureNoteTarget = async (\n  client: CoreApiClient,\n  { id, noteId, link }: { id: string; noteId: string; link: NoteTargetLink },\n): Promise<void> => {\n  const existingId = await findNoteTargetId(client, id);\n\n  if (isDefined(existingId)) {\n    return;\n  }\n\n  try {\n    await createNoteTarget(client, id, noteId, link);\n  } catch (error) {\n    const raceWinnerId = await findNoteTargetId(client, id);\n\n    if (!isDefined(raceWinnerId)) {\n      throw error;\n    }\n  }\n};\n\nconst buildLinks = (\n  personIds: string[],\n  companyIds: string[],\n  opportunityIds: string[],\n): NoteTargetLink[] => [\n  ...[...new Set(personIds)].map(\n    (value): NoteTargetLink => ({ kind: 'person', value }),\n  ),\n  ...[...new Set(companyIds)].map(\n    (value): NoteTargetLink => ({ kind: 'company', value }),\n  ),\n  ...[...new Set(opportunityIds)].map(\n    (value): NoteTargetLink => ({ kind: 'opportunity', value }),\n  ),\n];\n\n// Upserts a Note (deterministic id) and one NoteTarget per resolved\n// Person / Company / Opportunity, idempotently: re-runs update the Note body and\n// never duplicate NoteTargets.\nexport const upsertNoteWithTargets = async ({\n  client,\n  meetingId,\n  title,\n  bodyMarkdown,\n  personIds,\n  companyIds,\n  opportunityIds,\n}: UpsertNoteWithTargetsArgs): Promise<UpsertNoteWithTargetsResult> => {\n  const noteId = computeNoteIdForGranolaMeeting(meetingId);\n\n  const { created } = await upsertNote(client, noteId, {\n    title,\n    bodyV2: { markdown: bodyMarkdown, blocknote: null },\n  });\n\n  const links = buildLinks(personIds, companyIds, opportunityIds);\n  const noteTargetIds: string[] = [];\n\n  for (const link of links) {\n    const noteTargetId = computeNoteTargetId(meetingId, link.kind, link.value);\n\n    await ensureNoteTarget(client, { id: noteTargetId, noteId, link });\n\n    noteTargetIds.push(noteTargetId);\n  }\n\n  return { noteId, noteCreated: created, noteTargetIds };\n};\n", "import { type CoreApiClient } from 'twenty-client-sdk/core';\n\nimport { listGranolaNotes } from 'src/logic-functions/utils/list-granola-notes';\nimport { syncGranolaNoteToCallRecording } from 'src/logic-functions/utils/sync-granola-note-to-call-recording';\n\nexport type RunGranolaSyncResult = {\n  notesSeen: number;\n  synced: number;\n  errors: number;\n  errorMessages: string[];\n};\n\n// Lists every note updated since `updatedAfter` and syncs each sequentially\n// (sequential keeps request rate under the Granola limit; 429s are absorbed by\n// the request helper's backoff). Idempotent via deterministic ids.\nexport const runGranolaSync = async ({\n  apiKey,\n  client,\n  updatedAfter,\n}: {\n  apiKey: string;\n  client: CoreApiClient;\n  updatedAfter: string;\n}): Promise<RunGranolaSyncResult> => {\n  const listResult = await listGranolaNotes({ apiKey, updatedAfter });\n\n  if (!listResult.ok) {\n    return {\n      notesSeen: 0,\n      synced: 0,\n      errors: 1,\n      errorMessages: [listResult.errorMessage],\n    };\n  }\n\n  const notes = listResult.data;\n  const errorMessages: string[] = [];\n  let synced = 0;\n\n  for (const note of notes) {\n    const result = await syncGranolaNoteToCallRecording({\n      apiKey,\n      client,\n      meetingId: note.id,\n    });\n\n    if (result.status === 'error') {\n      errorMessages.push(result.error);\n    } else {\n      synced += 1;\n    }\n  }\n\n  return {\n    notesSeen: notes.length,\n    synced,\n    errors: errorMessages.length,\n    errorMessages,\n  };\n};\n", "import { type CoreApiClient } from 'twenty-client-sdk/core';\n\nimport { GRANOLA_SYNC_STATUS } from 'src/constants/granola-connection';\nimport {\n  listActiveConnections,\n  stampSyncResult,\n} from 'src/logic-functions/utils/granola-connection-store';\nimport { runGranolaSync } from 'src/logic-functions/utils/run-granola-sync';\n\nexport type RunSyncForAllConnectionsResult = {\n  connectionsProcessed: number;\n  notesSeen: number;\n  synced: number;\n  errors: number;\n  errorMessages: string[];\n};\n\n// Enumerates every active per-member connection and syncs each one with that\n// member's own Granola key. A single member's failure (bad key, Granola\n// outage) is isolated: it is stamped on that connection and the loop continues.\n// Deterministic ids keep the whole run idempotent even when two members\n// attended the same meeting.\nexport const runSyncForAllConnections = async ({\n  client,\n  updatedAfter,\n  syncedAtIso,\n}: {\n  client: CoreApiClient;\n  updatedAfter: string;\n  syncedAtIso: string;\n}): Promise<RunSyncForAllConnectionsResult> => {\n  const connections = await listActiveConnections();\n\n  const aggregate: RunSyncForAllConnectionsResult = {\n    connectionsProcessed: connections.length,\n    notesSeen: 0,\n    synced: 0,\n    errors: 0,\n    errorMessages: [],\n  };\n\n  for (const connection of connections) {\n    const result = await runGranolaSync({\n      apiKey: connection.apiKey,\n      client,\n      updatedAfter,\n    });\n\n    aggregate.notesSeen += result.notesSeen;\n    aggregate.synced += result.synced;\n    aggregate.errors += result.errors;\n    aggregate.errorMessages.push(...result.errorMessages);\n\n    const status =\n      result.errors > 0 ? GRANOLA_SYNC_STATUS.error : GRANOLA_SYNC_STATUS.ok;\n\n    await stampSyncResult(connection.id, {\n      syncedAt: syncedAtIso,\n      status,\n      error: result.errorMessages[0] ?? null,\n    });\n  }\n\n  return aggregate;\n};\n", "import { defineLogicFunction } from 'twenty-sdk/define';\n\nimport { GRANOLA_CRON_INTERVAL_MINUTES } from 'src/logic-functions/constants/granola-sync';\nimport { GRANOLA_SYNC_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers';\nimport { granolaSyncHandler } from 'src/logic-functions/handlers/granola-sync-handler';\n\nexport default defineLogicFunction({\n  universalIdentifier: GRANOLA_SYNC_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER,\n  name: 'granola-sync',\n  description:\n    'Polls the Granola REST API on a schedule for notes updated within the overlap window (and once per day re-sweeps the last 24h), upserting a Note + NoteTargets on participants and a CallRecording with the summary and transcript for each meeting.',\n  timeoutSeconds: 300,\n  cronTriggerSettings: {\n    pattern: `*/${GRANOLA_CRON_INTERVAL_MINUTES} * * * *`,\n  },\n  handler: granolaSyncHandler,\n});\n"],
  "mappings": "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",
  "names": ["isNonEmptyString", "import_guards", "import_guards", "import_guards", "import_guards", "import_guards", "import_guards", "import_guards", "QUERY_BATCH_SIZE", "import_guards", "chunk"]
}
