Integration fixes: job url forwarding, search hit coordinates, fetcher heuristic, core browser entry
4 changed files +13 −7
modified
apps/api/src/repositories/search.ts
+4 −4
@@ -12,12 +12,12 @@ const MAX_HITS = 30; | ||
| 12 | 12 | async function facilityHits(text: string, limit = 12): Promise<SearchHit[]> { |
| 13 | 13 | const sql = pg(); |
| 14 | 14 | const rows = await sql<Row[]>` |
| 15 | − select f.id, f.slug, f.name, f.city, f.country_iso2, f.status, o.name as op_name, | |
| 15 | + select f.id, f.slug, f.name, f.city, f.country_iso2, f.status, f.lat, f.lng, o.name as op_name, | |
| 16 | 16 | greatest(ts_rank(f.search, plainto_tsquery('simple', ${text})), similarity(f.name, ${text}), case when lower(f.name) = lower(${text}) then 1.2 when f.name ilike ${likePattern(text)} then 0.7 else 0 end) as score |
| 17 | 17 | from facilities f left join operators o on o.id = f.operator_id |
| 18 | 18 | where f.merged_into is null and (f.search @@ plainto_tsquery('simple', ${text}) or f.name % ${text} or f.name ilike ${likePattern(text)} or exists (select 1 from facility_aliases a where a.facility_id = f.id and a.alias ilike ${likePattern(text)})) |
| 19 | 19 | order by score desc, f.completeness desc limit ${limit}`; |
| 20 | − return rows.map((r) => ({ type: "facility", id: reqStr(r.id), slug: reqStr(r.slug), title: reqStr(r.name), subtitle: [str(r.op_name), str(r.city), str(r.country_iso2)].filter(Boolean).join(" · ") || null, href: hrefFor("facility", reqStr(r.slug)), score: Math.min(1, 0.55 + 0.4 * (num(r.score) ?? 0)), meta: { status: str(r.status), countryIso2: str(r.country_iso2) } })); | |
| 20 | + return rows.map((r) => ({ type: "facility", id: reqStr(r.id), slug: reqStr(r.slug), title: reqStr(r.name), subtitle: [str(r.op_name), str(r.city), str(r.country_iso2)].filter(Boolean).join(" · ") || null, href: hrefFor("facility", reqStr(r.slug)), score: Math.min(1, 0.55 + 0.4 * (num(r.score) ?? 0)), meta: { status: str(r.status), countryIso2: str(r.country_iso2), lat: num(r.lat), lng: num(r.lng) } })); | |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | async function operatorHits(text: string, limit = 5): Promise<SearchHit[]> { |
@@ -34,12 +34,12 @@ async function operatorHits(text: string, limit = 5): Promise<SearchHit[]> { | ||
| 34 | 34 | async function metroHits(text: string, limit = 4): Promise<SearchHit[]> { |
| 35 | 35 | const sql = pg(); |
| 36 | 36 | const rows = await sql<Row[]>` |
| 37 | − select m.id, m.slug, m.name, m.country_iso2, greatest(similarity(m.name, ${text}), case when lower(m.name) = lower(${text}) then 1.2 when m.name ilike ${likePattern(text)} then 0.8 else 0 end) as score, | |
| 37 | + select m.id, m.slug, m.name, m.country_iso2, m.lat, m.lng, m.radius_km, greatest(similarity(m.name, ${text}), case when lower(m.name) = lower(${text}) then 1.2 when m.name ilike ${likePattern(text)} then 0.8 else 0 end) as score, | |
| 38 | 38 | (select count(*)::int from facilities f where f.metro_id = m.id and f.merged_into is null) as n |
| 39 | 39 | from metros m |
| 40 | 40 | where m.name % ${text} or m.name ilike ${likePattern(text)} or exists (select 1 from unnest(m.aliases) a where a ilike ${likePattern(text)}) |
| 41 | 41 | order by score desc, n desc limit ${limit}`; |
| 42 | − return rows.map((r) => ({ type: "metro", id: reqStr(r.id), slug: reqStr(r.slug), title: reqStr(r.name), subtitle: `${reqStr(r.country_iso2)} market${int(r.n) ? ` · ${int(r.n)} facilities` : ""}`, href: hrefFor("metro", reqStr(r.slug)), score: Math.min(1, 0.65 + 0.3 * (num(r.score) ?? 0)), meta: { facilityCount: int(r.n), countryIso2: str(r.country_iso2) } })); | |
| 42 | + return rows.map((r) => ({ type: "metro", id: reqStr(r.id), slug: reqStr(r.slug), title: reqStr(r.name), subtitle: `${reqStr(r.country_iso2)} market${int(r.n) ? ` · ${int(r.n)} facilities` : ""}`, href: hrefFor("metro", reqStr(r.slug)), score: Math.min(1, 0.65 + 0.3 * (num(r.score) ?? 0)), meta: { facilityCount: int(r.n), countryIso2: str(r.country_iso2), lat: num(r.lat), lng: num(r.lng), radiusKm: num(r.radius_km) } })); | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | async function cloudRegionHits(text: string, limit = 4): Promise<SearchHit[]> { |
modified
apps/worker/src/main.ts
+1 −1
@@ -129,7 +129,7 @@ export async function startWorker(opts: { withScheduler?: boolean } = {}): Promi | ||
| 129 | 129 | const d = job.data; |
| 130 | 130 | running.set(String(job.id), { id: String(job.id), name: job.name, connectorId: d.connectorId, task: d.task, group: d.group, since: new Date().toISOString() }); |
| 131 | 131 | try { |
| 132 | − const r = await runConnector(d.connectorId, { task: d.task, group: d.group, limit: d.limit, force: d.force }); | |
| 132 | + const r = await runConnector(d.connectorId, { task: d.task, group: d.group, limit: d.limit, force: d.force, urls: d.urls }); | |
| 133 | 133 | accountRun(r); |
| 134 | 134 | if (r.status === "failed") throw new Error(r.error ?? "run failed"); |
| 135 | 135 | return { runId: r.runId, status: r.status, stats: r.stats }; |
modified
apps/worker/src/scheduler.ts
+1 −1
@@ -25,7 +25,7 @@ export const MAINTENANCE_QUEUE = "maintenance"; | ||
| 25 | 25 | export const WORKER_STATUS_KEY = "dci:worker:status"; |
| 26 | 26 | const SCHEDULER_LOCK_KEY = "dci:scheduler:lock"; |
| 27 | 27 | |
| 28 | −export interface CrawlJobData { connectorId: string; task: RunTask; group?: string; limit?: number; force?: boolean; requestedBy?: string } | |
| 28 | +export interface CrawlJobData { connectorId: string; task: RunTask; group?: string; limit?: number; force?: boolean; urls?: string[]; requestedBy?: string } | |
| 29 | 29 | export type MaintenanceKind = "rankings" | "metrics" | "refresh-stats" | "cleanup"; |
| 30 | 30 | export interface MaintenanceJobData { kind: MaintenanceKind; requestedBy?: string } |
| 31 | 31 | |
modified
docs/connectors/peeringdb.md
+7 −1
@@ -75,7 +75,13 @@ TOTAL 13 020 entities, 13 020 valid, 0 rejected, 0 warnings, 11 fetches, 26 s (2 | ||
| 75 | 75 | Facilities coverage: 5 255 / 5 860 with coordinates (`exact`), 5 860 with a country, 3 720 with ≥ 1 carrier/NSP present, 2 158 with ≥ 1 IX present, 206 attached to a campus; 57 typed `carrier_hotel` (ix_count ≥ 3 and net_count ≥ 150), 5 803 `colocation`. |
| 76 | 76 | Sample: `peeringdb:fac:1` "Equinix DC1-DC15,DC21-DC22 - Ashburn" — operator Equinix, Inc. (`peeringdb:org:2`), campus "Equinix Ashburn" (`peeringdb:campus:14`), 21715 Filigree Ct, Building F, Ashburn VA 20147-6205 US, geo 39.016363/−77.459023 exact, `carrier_hotel`, carriers list (123NET, AT&T US, Angola Cables…), facts networkCount 516 / ixCount 8 / carrierCount 14. |
| 77 | 77 | |
| 78 | −IX document: re-verified separately once the hourly window reopened — see the end of this section (1 323 exchanges expected, `status: ok`, with `facilityKeys` from 4 521 ixfac rows). | |
| 78 | +IX document, re-verified once the hourly window reopened (03:48 EDT, `--url https://www.peeringdb.com/api/ix?depth=0`, group inferred from the path): | |
| 79 | + | |
| 80 | +``` | |
| 81 | +ix?depth=0 200 0.3 s → 1 323 records → 1 323 IXPs, 1 323 valid, 0 rejected (2 fetches: ix + ixfac) | |
| 82 | +``` | |
| 83 | +Coverage: 1 323 with a country, 1 318 with a website, 1 226 with `networkCount`, 960 with ≥ 1 `facilityKeys` (from 4 521 ixfac rows). | |
| 84 | +Sample: `peeringdb:ix:1` "Equinix Ashburn" (nameLong "Equinix Internet Exchange Ashburn", US, North America, 347 networks, facilityKeys `peeringdb:fac:1`, `peeringdb:fac:710`, `peeringdb:fac:15438`, externalIds peeringdb_ix 1 / peeringdb_org 2). | |
| 79 | 85 | |
| 80 | 86 | ## Quirks / gaps |
| 81 | 87 | |
| 82 | 88 | |