spb/datacenterindex
Public
HTML 53.9%
TypeScript 44.5%
JavaScript 0.6%
SQL 0.5%
1import { describe, expect, it } from "vitest";2import { compareFacilityCodes, extractFacilityCodes } from "@dci/core";3import { AUTO_MERGE_THRESHOLD, PENDING_THRESHOLD, bestMatch, completenessScore, decide, facilityConfidence, scoreFacilityMatch, shouldReplace, shouldReplaceGeo, shouldReplaceMw, type FacilityCandidate } from "./match.js";45const equinix = "op_equinix";6const digital = "op_digitalrealty";78const dc12: FacilityCandidate = { id: "fac_dc12", name: "Equinix DC12", normalizedName: "equinix dc12", operatorId: equinix, countryIso2: "US", city: "Ashburn", address: "21721 Filigree Court, Ashburn, VA 20147", lat: 39.0223, lng: -77.4646, geoPrecision: "exact" };9const dc13: FacilityCandidate = { id: "fac_dc13", name: "Equinix DC13", normalizedName: "equinix dc13", operatorId: equinix, countryIso2: "US", city: "Ashburn", address: "21711 Filigree Court, Ashburn, VA 20147", lat: 39.0227, lng: -77.4652, geoPrecision: "exact" };1011describe("facility matching", () => {12 it("merges 'Equinix DC12 Data Center' into 'Equinix DC12' (same operator, code, location)", () => {13 const m = scoreFacilityMatch({ name: "Equinix DC12 Data Center", operatorId: equinix, countryIso2: "US", lat: 39.0224, lng: -77.4647, geoPrecision: "exact" }, dc12);14 expect(m.score).toBeGreaterThanOrEqual(AUTO_MERGE_THRESHOLD);15 expect(decide(m.score)).toBe("merge");16 expect(m.reasons).toContain("name:exact");17 });1819 it("merges a bare code 'DC12' when the operator matches and the site is within the match radius", () => {20 const m = scoreFacilityMatch({ name: "DC12", operatorId: equinix, countryIso2: "US", lat: 39.0225, lng: -77.4648, geoPrecision: "exact" }, dc12);21 expect(m.reasons).toContain("rule:operator+code");22 expect(decide(m.score)).toBe("merge");23 });2425 it("does not confuse DC12 with DC13 next door (code conflict)", () => {26 const m = scoreFacilityMatch({ name: "Equinix DC12", operatorId: equinix, countryIso2: "US", lat: 39.0224, lng: -77.4647, geoPrecision: "exact" }, dc13);27 expect(m.reasons).toContain("codes:conflict");28 expect(m.score).toBeLessThan(AUTO_MERGE_THRESHOLD);29 const best = bestMatch({ name: "Equinix DC12", operatorId: equinix, countryIso2: "US", lat: 39.0224, lng: -77.4647, geoPrecision: "exact" }, [dc13, dc12]);30 expect(best?.candidate.id).toBe("fac_dc12");31 });3233 it("never merges facilities of different known operators, even at the same coordinates", () => {34 const m = scoreFacilityMatch({ name: "Digital Realty DC12", operatorId: digital, countryIso2: "US", lat: 39.0223, lng: -77.4646, geoPrecision: "exact" }, dc12);35 expect(m.blocked).toBe(true);36 expect(m.score).toBeLessThan(PENDING_THRESHOLD);37 expect(decide(m.score)).toBe("create");38 });3940 it("allows different operators only when name and address are exact (change of operator)", () => {41 const m = scoreFacilityMatch({ name: "Equinix DC12", operatorId: digital, countryIso2: "US", address: "21721 Filigree Ct, Ashburn VA 20147", lat: 39.0223, lng: -77.4646, geoPrecision: "exact" }, dc12);42 expect(m.blocked).toBe(false);43 });4445 it("returns a pending decision for a similar name with no operator and city-level coordinates", () => {46 const m = scoreFacilityMatch({ name: "Equinix Ashburn DC12 Campus Building", countryIso2: "US", city: "Ashburn", lat: 39.04, lng: -77.49, geoPrecision: "city" }, { ...dc12, operatorId: null });47 expect(m.score).toBeGreaterThanOrEqual(PENDING_THRESHOLD);48 expect(m.score).toBeLessThan(AUTO_MERGE_THRESHOLD);49 expect(decide(m.score)).toBe("pending");50 });5152 it("does not match across countries", () => {53 const m = scoreFacilityMatch({ name: "Equinix DC12", operatorId: equinix, countryIso2: "CA", lat: 39.0223, lng: -77.4646, geoPrecision: "exact" }, dc12);54 expect(m.score).toBeLessThanOrEqual(0.3);55 });5657 it("treats far-apart precise coordinates as different buildings even with similar names", () => {58 const m = scoreFacilityMatch({ name: "Equinix DC12", operatorId: equinix, countryIso2: "US", lat: 38.9, lng: -77.0, geoPrecision: "exact" }, dc12);59 expect(m.reasons).toContain("distance:too-far");60 expect(decide(m.score)).not.toBe("merge");61 });62});6364describe("field merge policy", () => {65 const operatorObs = (value: unknown) => ({ value, sourceKind: "operator", confidence: "high", isEstimate: false, observedAt: "2026-09-01T00:00:00Z", sourceId: "src_op" });66 const newsObs = (value: unknown) => ({ value, sourceKind: "news", confidence: "moderate", isEstimate: false, observedAt: "2026-09-10T00:00:00Z", sourceId: "src_news" });6768 it("fills an empty field from any source", () => {69 expect(shouldReplace(newsObs(36), null).replace).toBe(true);70 });71 it("lets a source correct its own earlier value", () => {72 expect(shouldReplace({ ...operatorObs(48), observedAt: "2026-09-11T00:00:00Z" }, operatorObs(36)).reason).toBe("same-source");73 });74 it("does not churn between two pages of the same source that disagree (fresh value kept, stale value replaced)", () => {75 const pageA = { ...operatorObs("Equinix DC12"), url: "https://x/a", observedAt: "2026-09-10T00:00:00Z" };76 const pageB = { ...operatorObs("Equinix DC12 Data Center"), url: "https://x/b", observedAt: "2026-09-11T00:00:00Z" };77 expect(shouldReplace(pageB, pageA).replace).toBe(false);78 expect(shouldReplace({ ...pageB, observedAt: "2026-12-01T00:00:00Z" }, pageA).reason).toBe("equal-authority-stale");79 expect(shouldReplace({ ...pageA, value: "Equinix DC12 (Ashburn)", observedAt: "2026-09-11T00:00:00Z" }, pageA).reason).toBe("same-source");80 });81 it("does not let a news figure overwrite an operator figure", () => {82 const d = shouldReplace(newsObs(60), operatorObs(36));83 expect(d.replace).toBe(false);84 expect(d.reason).toBe("lower-authority");85 });86 it("lets an operator figure overwrite a news figure", () => {87 expect(shouldReplace(operatorObs(36), newsObs(60)).replace).toBe(true);88 });89 it("prefers a measured MW over an estimate regardless of source authority", () => {90 expect(shouldReplaceMw(newsObs(40), { ...operatorObs(50), isEstimate: true }).replace).toBe(true);91 expect(shouldReplaceMw({ ...newsObs(40), isEstimate: true }, operatorObs(50)).replace).toBe(false);92 });93 it("MW: a dataset never overwrites a filing/operator figure", () => {94 const d = shouldReplaceMw({ value: 45, sourceKind: "dataset", confidence: "moderate", isEstimate: false, sourceId: "src_ds" }, operatorObs(36));95 expect(d.replace).toBe(false);96 });97 it("never degrades coordinate precision", () => {98 expect(shouldReplaceGeo("city", "exact", true)).toBe(false);99 expect(shouldReplaceGeo("exact", "city", true)).toBe(true);100 expect(shouldReplaceGeo("city", "unknown", false)).toBe(true);101 expect(shouldReplaceGeo("exact", "exact", true)).toBe(true);102 });103});104105describe("completeness and confidence", () => {106 it("scores a fully described facility at 100 and an empty one at 0", () => {107 expect(completenessScore({ hasCoords: false })).toBe(0);108 expect(109 completenessScore({ hasCoords: true, geoPrecision: "exact", operatorId: "op", address: "21721 Filigree Court", status: "operational", itCapacityMw: 36, facilityType: "colocation", openedOn: "2016", website: "https://x", description: "A".repeat(60), carriersCount: 40 }),110 ).toBe(100);111 });112 it("gives less credit for city-level geo and for estimated MW", () => {113 const exact = completenessScore({ hasCoords: true, geoPrecision: "exact", itCapacityMw: 10 });114 const city = completenessScore({ hasCoords: true, geoPrecision: "city", itCapacityMw: 10 });115 const est = completenessScore({ hasCoords: true, geoPrecision: "exact", itCapacityMw: 10, mwIsEstimate: true });116 expect(exact).toBeGreaterThan(city);117 expect(exact).toBeGreaterThan(est);118 });119 it("confidence: single operator source is high, two authoritative kinds verified, single community/news source unverified", () => {120 expect(facilityConfidence({ sourceKinds: ["operator"] })).toBe("high");121 expect(facilityConfidence({ sourceKinds: ["government"] })).toBe("high");122 expect(facilityConfidence({ sourceKinds: ["operator", "government"] })).toBe("verified");123 expect(facilityConfidence({ sourceKinds: ["news"], sourceCount: 1 })).toBe("unverified");124 expect(facilityConfidence({ sourceKinds: ["community"], sourceCount: 1 })).toBe("unverified");125 expect(facilityConfidence({ sourceKinds: ["community", "dataset"], sourceCount: 2 })).toBe("moderate");126 // a registry or dataset alone never reaches "high"127 expect(facilityConfidence({ sourceKinds: ["registry"], sourceCount: 1 })).toBe("moderate");128 expect(facilityConfidence({ sourceKinds: ["dataset"], sourceCount: 1 })).toBe("moderate");129 expect(facilityConfidence({ sourceKinds: [] })).toBe("unverified");130 expect(facilityConfidence({ sourceKinds: ["operator"], onlyEstimates: true })).toBe("estimated");131 });132});133134describe("reconciliation noise (entity_matches queue, 2026-09-11)", () => {135 const virtus = "op_virtus", gswitch = "op_globalswitch", telehouse = "op_telehouse", colt = "op_colt", google = "op_google", nextdc = "op_nextdc", pulsant = "op_pulsant";136 const cand = (name: string, op: string | null, opName: string | null, lat: number, lng: number, extra: Partial<FacilityCandidate> = {}): FacilityCandidate => ({ id: `fac_${name.replace(/\W+/g, "").toLowerCase()}`, name, normalizedName: name.toLowerCase(), operatorId: op, operatorName: opName, countryIso2: "GB", lat, lng, geoPrecision: "exact", ...extra });137138 it("LONDON6 vs LONDON5: differing facility codes are a hard negative (< pending)", () => {139 const m = scoreFacilityMatch({ name: "Virtus LONDON6", operatorId: virtus, operatorName: "Virtus", countryIso2: "GB", lat: 51.5105687, lng: -0.4538102, geoPrecision: "exact" }, cand("Virtus LONDON5", virtus, "Virtus", 51.5095441, -0.4542871));140 expect(m.reasons).toContain("codes:conflict");141 expect(m.score).toBeLessThan(PENDING_THRESHOLD);142 });143 it("Colt DCS Tokyo Inzai 4 vs Inzai 3 / Sify Chennai 01 vs 02 / NEXTDC S3 vs S1: numbered siblings create", () => {144 expect(decide(scoreFacilityMatch({ name: "Colt DCS Tokyo Inzai 4 Data Centre", operatorId: colt, operatorName: "Colt Data Centre Services", countryIso2: "JP" }, { ...cand("Colt DCS Tokyo Inzai 3 Data Centre", colt, "Colt Data Centre Services", 35.8, 140.1), countryIso2: "JP", lat: null, lng: null }).score)).toBe("create");145 expect(decide(scoreFacilityMatch({ name: "Sify Chennai 02", operatorId: "op_sify", operatorName: "Sify Technologies", countryIso2: "IN", city: "Chennai" }, { ...cand("Sify Chennai 01", "op_sify", "Sify Technologies", 13, 80), countryIso2: "IN", city: "Chennai", lat: null, lng: null }).score)).toBe("create");146 expect(decide(scoreFacilityMatch({ name: "NEXTDC S3 Sydney", operatorId: nextdc, operatorName: "NEXTDC", countryIso2: "AU", city: "Sydney" }, { ...cand("NEXTDC S1 Sydney", nextdc, "NEXTDC", -33.8, 151.2), countryIso2: "AU", city: "Sydney", lat: null, lng: null }).score)).toBe("create");147 });148 it("Global Switch London East vs London North, Telehouse West vs East, Telehouse North Two vs North: directional / ordinal siblings create", () => {149 const north = cand("Global Switch London North", gswitch, "Global Switch", 51.511119, -0.005573);150 const east = scoreFacilityMatch({ name: "Global Switch London East", operatorId: gswitch, operatorName: "Global Switch", countryIso2: "GB", lat: 51.5109396, lng: -0.003425, geoPrecision: "exact" }, north);151 expect(east.reasons).toContain("rule:siblings");152 expect(east.score).toBeLessThan(PENDING_THRESHOLD);153 const tEast = cand("Telehouse East", telehouse, "Telehouse Europe", 51.5115297, -0.001266);154 expect(scoreFacilityMatch({ name: "Telehouse West", operatorId: telehouse, operatorName: "Telehouse Europe", countryIso2: "GB", lat: 51.5111949, lng: -0.0023135, geoPrecision: "exact" }, tEast).score).toBeLessThan(PENDING_THRESHOLD);155 const tNorth = cand("Telehouse North", telehouse, "Telehouse Europe", 51.512052, -0.0019544);156 expect(scoreFacilityMatch({ name: "Telehouse North Two", operatorId: telehouse, operatorName: "Telehouse Europe", countryIso2: "GB", lat: 51.5121049, lng: -0.0005474, geoPrecision: "exact" }, tNorth).score).toBeLessThan(PENDING_THRESHOLD);157 // "Campus II" and "Campus 2" are the same building, not siblings158 expect(scoreFacilityMatch({ name: "CyrusOne Frankfurt II", operatorId: "op_c1", operatorName: "CyrusOne", countryIso2: "DE", lat: 50.1, lng: 8.6, geoPrecision: "exact" }, { ...cand("CyrusOne Frankfurt 2", "op_c1", "CyrusOne", 50.1, 8.6), countryIso2: "DE" }).reasons).toContain("name:exact");159 });160 it("Pulsant Reading SE-3 vs 'Pulsant', 'BCX NDC2' vs 'BCX', 'Switch' vs 'Switch Las Vegas 8': brand-only names never carry a match", () => {161 const m = scoreFacilityMatch({ name: "Pulsant Reading SE-3", operatorId: pulsant, operatorName: "Pulsant", countryIso2: "GB" }, { ...cand("Pulsant", pulsant, "Pulsant", 51.4, -0.9), lat: null, lng: null });162 expect(m.reasons).toContain("name:operator-only");163 expect(decide(m.score)).toBe("create");164 expect(decide(scoreFacilityMatch({ name: "BCX NDC2", operatorId: "op_bcx", operatorName: "BCX", countryIso2: "ZA", lat: -26.1, lng: 28.1, geoPrecision: "exact" }, { ...cand("BCX", "op_bcx", "BCX", -26.1001, 28.1001), countryIso2: "ZA" }).score)).toBe("create");165 expect(decide(scoreFacilityMatch({ name: "Switch", operatorId: "op_switch", operatorName: "Switch", countryIso2: "US", lat: 36.07, lng: -115.1, geoPrecision: "exact" }, { ...cand("Switch Las Vegas 8", "op_switch", "Switch", 36.075, -115.105), countryIso2: "US" }).score)).not.toBe("merge");166 });167 it("names in a non-Latin script are compared verbatim, never 'equal because both normalize to nothing'", () => {168 const m = scoreFacilityMatch({ name: "ساختمان مهندسین مهرزاد", countryIso2: "IR", lat: 35.7, lng: 51.4, geoPrecision: "exact" }, { ...cand("شرکت فناوری رایان افزار پارسان", null, null, 35.7, 51.4), countryIso2: "IR" });169 expect(m.reasons).toContain("name:0.00");170 expect(decide(m.score)).toBe("create");171 expect(scoreFacilityMatch({ name: "سرورفارم", countryIso2: "IR", lat: 35.7, lng: 51.4, geoPrecision: "exact" }, { ...cand("سرورفارم", null, null, 35.7, 51.4), countryIso2: "IR" }).reasons).toContain("name:exact");172 });173 it("Wikidata 'Google Data Center Fredericia' vs Google page 'Fredericia, Denmark' 6 km apart at city level → merge", () => {174 const page = cand("Google Fredericia, Denmark data center", google, "Google", 55.57, 9.75, { countryIso2: "DK", city: "Fredericia", geoPrecision: "city" });175 const withOperator = scoreFacilityMatch({ name: "Google Data Center Fredericia", operatorId: google, operatorName: "Google", countryIso2: "DK", lat: 55.5579737, lng: 9.6531741, geoPrecision: "exact" }, page);176 expect(withOperator.reasons).toContain("rule:operator+site");177 expect(withOperator.score).toBeGreaterThanOrEqual(AUTO_MERGE_THRESHOLD);178 // without an operator on the Wikidata side the name still implies Google → at least pending, never create179 const implied = scoreFacilityMatch({ name: "Google Data Center Fredericia", countryIso2: "DK", lat: 55.5579737, lng: 9.6531741, geoPrecision: "exact" }, page);180 expect(implied.reasons).toContain("operator:name-implied");181 expect(implied.score).toBeGreaterThanOrEqual(PENDING_THRESHOLD);182 // but "Google" alone next to Eemshaven is not a specific building183 expect(decide(scoreFacilityMatch({ name: "Google", operatorId: google, operatorName: "Google", countryIso2: "NL", lat: 53.44, lng: 6.83, geoPrecision: "exact" }, cand("Google Eemshaven, Netherlands data center", google, "Google", 53.45, 6.86, { countryIso2: "NL", geoPrecision: "city" })).score)).not.toBe("merge");184 });185 it("'Meta Odense Data Center' twice, same city, operator unknown on one side → merge; 'Adeo Datacenter ApS' at 0 m → merge", () => {186 const m = scoreFacilityMatch({ name: "Meta Odense Data Center", countryIso2: "DK", city: "Odense Municipality", lat: 55.36668, lng: 10.48479, geoPrecision: "street" }, cand("Meta Odense Data Center", "op_meta", "Meta", 55.4, 10.39, { countryIso2: "DK", city: "Odense", geoPrecision: "city" }));187 expect(m.reasons).toContain("rule:exact-name+site");188 expect(decide(m.score)).toBe("merge");189 expect(decide(scoreFacilityMatch({ name: "Adeo Datacenter ApS", countryIso2: "DK", lat: 55.7, lng: 12.5, geoPrecision: "exact" }, cand("Adeo Datacenter ApS", null, null, 55.7, 12.5, { countryIso2: "DK" })).score)).toBe("merge");190 // exact name from two sources at 80 m with an address that only differs in formatting → merge191 expect(decide(scoreFacilityMatch({ name: "Equinix ZRH5", operatorId: "op_eq", operatorName: "Equinix", countryIso2: "CH", address: "Sägereistrasse 35, 8152 Glattbrugg", lat: 47.43, lng: 8.56, geoPrecision: "exact" }, cand("Equinix ZRH5", "op_eq", "Equinix", 47.4307, 8.5605, { countryIso2: "CH", address: "Sägereistrasse 35, Opfikon" })).score)).toBe("merge");192 // exact but brand-only OSM names 230 m apart with different house numbers stay separate193 expect(decide(scoreFacilityMatch({ name: "Digital Realty Data Center", countryIso2: "US", address: "100 Main St", lat: 41.88, lng: -87.63, geoPrecision: "exact" }, cand("Digital Realty Data Center", null, null, 41.882, -87.631, { countryIso2: "US", address: "350 Cermak Rd" })).score)).not.toBe("merge");194 });195 it("Meta Henrico vs Meta Cheyenne: a brand-only alias ('meta') never links two sites", () => {196 const m = scoreFacilityMatch({ name: "Meta Henrico Data Center", aliases: ["Meta Data Center"], countryIso2: "US", lat: 37.55, lng: -77.4, geoPrecision: "approximate" }, { ...cand("Meta Cheyenne Data Center", "op_meta", "Meta", 37.55, -77.4, { countryIso2: "US", geoPrecision: "approximate" }), aliases: ["Meta Data Center", "Meta Beaver Dam Data Center"] });197 expect(m.reasons).not.toContain("name:alias");198 expect(decide(m.score)).not.toBe("merge");199 });200 it("extractFacilityCodes covers LONDON6 / LON6 / DC-12 / FRA01A / IAD12 / SYD01 / SC-2 / S3 and ignores units and tiers", () => {201 expect(extractFacilityCodes("Virtus LONDON6")).toEqual(["LONDON6"]);202 expect(extractFacilityCodes("Equinix DC-12")).toEqual(["DC12"]);203 expect(extractFacilityCodes("FRA01A")).toEqual(["FRA1A"]);204 expect(extractFacilityCodes("AirTrunk SYD01")).toEqual(["SYD1"]);205 expect(extractFacilityCodes("Pulsant Edinburgh SC-2")).toEqual(["SC2"]);206 expect(extractFacilityCodes("NEXTDC S3 Sydney")).toEqual(["S3"]);207 expect(extractFacilityCodes("Colt DCS Tokyo Inzai 3 Data Centre")).toEqual(["INZAI3"]);208 expect(extractFacilityCodes("Tier 3 facility with 50 MW on Route 7")).toEqual([]);209 expect(compareFacilityCodes(["LONDON6"], ["LONDON5"])).toBe(0);210 expect(compareFacilityCodes(["SYD1"], ["MEL1"])).toBeNull();211 expect(compareFacilityCodes(["SY5B"], ["SY5"])).toBe(1);212 expect(compareFacilityCodes(["DATA4", "MAD1"], ["DATA4", "MAD2"])).toBe(0);213 });214});215