core/analyzers/rate.analyzer.ts
core/analyzers/rate.analyzer.ts is a file in Project Scripts. 46 lines of code and 9 definitions.
import type { GroupSummary, PeerGroup, RateRecord } from "#types/rate.types";
import {
HALF,
NINE_TENTHS,
PERCENT,
QUARTER,
SECONDS_PER_MONTH,
THREE_QUARTERS,
} from "#configuration/constants/rate.constants";
const inGroup = function inGroup(record: RateRecord, group: PeerGroup): boolean {
const titled = group.titles.length === 0 || record.titles.some((title) => group.titles.includes(title));
const senior =
group.seniorities.length === 0 || record.seniorities.some((level) => group.seniorities.includes(level));
return titled && senior;
};
const quantile = function quantile(sorted: readonly number[], share: number): number {
return sorted[Math.min(sorted.length - 1, Math.floor(share * (sorted.length - 1)))] ?? 0;
};
export const summarize = function summarize(
records: readonly RateRecord[],
group: PeerGroup,
rate: number | null,
): GroupSummary {
const sorted = records
.filter((record) => inGroup(record, group))
.map((record) => record.rate)
.toSorted((left, right) => left - right);
const below = rate === null || sorted.length === 0 ? null : sorted.filter((value) => value < rate).length;
return {
below: below === null ? null : Math.round((below / sorted.length) * PERCENT),
count: sorted.length,
highest: sorted.at(-1) ?? 0,
label: group.label,
median: quantile(sorted, HALF),
p25: quantile(sorted, QUARTER),
p75: quantile(sorted, THREE_QUARTERS),
p90: quantile(sorted, NINE_TENTHS),
};
};
export const withinMonths = function withinMonths(
records: readonly RateRecord[],
months: number,
): readonly RateRecord[] {
const newest = Math.max(...records.map((record) => record.createdAt));
return records.filter((record) => record.createdAt >= newest - months * SECONDS_PER_MONTH);
};