From d2580e26d45f401873c918ea87e60bdaa58c2445 Mon Sep 17 00:00:00 2001 From: Koen Bok Date: Fri, 11 Sep 2026 09:43:55 +0000 Subject: [PATCH] fix(ashby): fall back to compensationTierSummary for non-yearly compensation --- plugins/ashby/src/api-types.ts | 2 +- plugins/ashby/src/dataSources.test.ts | 35 ++++++++++++++++++++++++++- plugins/ashby/src/dataSources.ts | 23 ++++++++---------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/plugins/ashby/src/api-types.ts b/plugins/ashby/src/api-types.ts index 6f90e1084..02df247dd 100644 --- a/plugins/ashby/src/api-types.ts +++ b/plugins/ashby/src/api-types.ts @@ -39,7 +39,7 @@ export const SecondaryLocationSchema = v.object({ address: JobAddressSchema, }) -const CompensationSchema = v.object({ +export const CompensationSchema = v.object({ compensationTierSummary: v.nullable(v.string()), scrapeableCompensationSalarySummary: v.nullable(v.string()), compensationTiers: v.array(CompensationTiersSchema), diff --git a/plugins/ashby/src/dataSources.test.ts b/plugins/ashby/src/dataSources.test.ts index 355577ccb..6240d694d 100644 --- a/plugins/ashby/src/dataSources.test.ts +++ b/plugins/ashby/src/dataSources.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest" -import { extractLocation } from "./dataSources" +import { extractCompensationSummary, extractLocation } from "./dataSources" describe("extractLocation", () => { it("extracts location with full address", () => { @@ -88,3 +88,36 @@ describe("extractLocation", () => { expect(result.name).toBe("東京") }) }) + +const emptyCompensation = { + compensationTierSummary: null, + scrapeableCompensationSalarySummary: null, + compensationTiers: [], + summaryComponents: [], +} + +describe("extractCompensationSummary", () => { + it("prefers the scrapeable salary summary", () => { + const result = extractCompensationSummary({ + ...emptyCompensation, + scrapeableCompensationSalarySummary: "€100K - €150K", + compensationTierSummary: "€100K - €150K • Offers Equity", + }) + + expect(result).toBe("€100K - €150K") + }) + + it("falls back to the tier summary when the scrapeable summary is null", () => { + const result = extractCompensationSummary({ + ...emptyCompensation, + compensationTierSummary: "€8K - €12K / month", + }) + + expect(result).toBe("€8K - €12K / month") + }) + + it("returns null when no summary is available", () => { + expect(extractCompensationSummary(emptyCompensation)).toBeNull() + expect(extractCompensationSummary(null)).toBeNull() + }) +}) diff --git a/plugins/ashby/src/dataSources.ts b/plugins/ashby/src/dataSources.ts index dcc9d3c60..a4b9b498f 100644 --- a/plugins/ashby/src/dataSources.ts +++ b/plugins/ashby/src/dataSources.ts @@ -1,6 +1,7 @@ import type { ManagedCollectionFieldInput } from "framer-plugin" import * as v from "valibot" import { + CompensationSchema, type DataItem, type Job, type JobAddress, @@ -71,6 +72,14 @@ function getLocationId(entry: unknown): string | null { return null } +export function extractCompensationSummary(value: unknown): string | null { + if (typeof value !== "object" || value === null) return null + + const compensation = v.parse(CompensationSchema, value) + + return compensation.scrapeableCompensationSalarySummary ?? compensation.compensationTierSummary +} + export function extractLocation(locationName: string, address: JobAddress | null): Location { const postalAddress = address?.postalAddress const parts = [ @@ -169,19 +178,7 @@ const jobsDataSource = createDataSource( id: "compensation", name: "Compensation", type: "string", - getValue: value => { - if (typeof value !== "object" || value === null) return null - - if ("scrapeableCompensationSalarySummary" in value) { - return value.scrapeableCompensationSalarySummary - } - - if ("compensationTierSummary" in value) { - return value.compensationTierSummary - } - - return null - }, + getValue: extractCompensationSummary, }, { id: "address",