business-as-code
Version:
Primitives for expressing business logic and processes as code
448 lines • 9.38 kB
TypeScript
/**
* Standardized SaaS Metrics
*
* First-class types for common SaaS/subscription business metrics
* with auto-calculation over time periods.
*
* @packageDocumentation
*/
import type { Currency, TimePeriod } from './types.js';
/**
* Date range for metric calculations
*/
export interface DateRange {
start: Date;
end: Date;
}
/**
* Time period with explicit dates
*/
export interface MetricPeriod {
period: TimePeriod;
range: DateRange;
label?: string;
}
/**
* Time-series data point
*/
export interface DataPoint<T = number> {
timestamp: Date;
value: T;
metadata?: Record<string, unknown>;
}
/**
* Time series of metric values
*/
export interface TimeSeries<T = number> {
metric: string;
unit: string;
dataPoints: DataPoint<T>[];
aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'last' | 'first';
}
/**
* Monthly Recurring Revenue (MRR)
*/
export interface MRR {
total: number;
newMRR: number;
expansionMRR: number;
contractionMRR: number;
churnedMRR: number;
reactivationMRR: number;
netNewMRR: number;
currency: Currency;
period: MetricPeriod;
}
/**
* Annual Recurring Revenue (ARR)
*/
export interface ARR {
total: number;
fromMRR?: number;
contracted?: number;
currency: Currency;
asOf: Date;
}
/**
* Net Revenue Retention (NRR) / Dollar-based Net Retention (DBNR)
*/
export interface NRR {
rate: number;
startingMRR: number;
endingMRR: number;
expansion: number;
contraction: number;
churn: number;
period: MetricPeriod;
}
/**
* Gross Revenue Retention (GRR)
*/
export interface GRR {
rate: number;
startingMRR: number;
endingMRR: number;
contraction: number;
churn: number;
period: MetricPeriod;
}
/**
* Average Revenue Per User/Account
*/
export interface ARPU {
value: number;
totalRevenue: number;
totalUsers: number;
currency: Currency;
period: MetricPeriod;
segment?: string;
}
/**
* Revenue by segment/cohort
*/
export interface RevenueSegment {
name: string;
mrr: number;
arr: number;
customers: number;
arpu: number;
growth: number;
currency: Currency;
}
/**
* Customer Acquisition Cost (CAC)
*/
export interface CAC {
value: number;
totalSalesMarketingSpend: number;
newCustomersAcquired: number;
currency: Currency;
period: MetricPeriod;
byChannel?: Record<string, number>;
}
/**
* Customer Lifetime Value (LTV/CLV)
*/
export interface LTV {
value: number;
arpu: number;
grossMargin: number;
churnRate: number;
averageLifetimeMonths: number;
currency: Currency;
}
/**
* LTV:CAC Ratio
*/
export interface LTVtoCAC {
ratio: number;
ltv: number;
cac: number;
paybackMonths: number;
healthy: boolean;
}
/**
* Churn metrics
*/
export interface Churn {
customerChurnRate: number;
customersLost: number;
customersStart: number;
revenueChurnRate: number;
mrrChurned: number;
netRevenueChurnRate: number;
period: MetricPeriod;
}
/**
* Retention cohort
*/
export interface RetentionCohort {
cohortDate: Date;
cohortLabel: string;
initialCustomers: number;
initialMRR: number;
retentionByMonth: number[];
revenueByMonth: number[];
}
/**
* Growth rate metrics
*/
export interface GrowthRate {
mom: number;
qoq: number;
yoy: number;
cagr?: number;
metric: string;
period: MetricPeriod;
}
/**
* Quick ratio (growth efficiency)
* (New MRR + Expansion MRR) / (Churned MRR + Contraction MRR)
*/
export interface QuickRatio {
ratio: number;
newMRR: number;
expansionMRR: number;
churnedMRR: number;
contractionMRR: number;
healthy: boolean;
period: MetricPeriod;
}
/**
* Magic Number
* Net New ARR / Sales & Marketing Spend (previous quarter)
*/
export interface MagicNumber {
value: number;
netNewARR: number;
salesMarketingSpend: number;
efficient: boolean;
period: MetricPeriod;
}
/**
* Burn Multiple
* Net Burn / Net New ARR
*/
export interface BurnMultiple {
value: number;
netBurn: number;
netNewARR: number;
efficient: boolean;
period: MetricPeriod;
}
/**
* Rule of 40
* Growth Rate + Profit Margin >= 40%
*/
export interface RuleOf40 {
score: number;
revenueGrowthRate: number;
profitMargin: number;
passing: boolean;
period: MetricPeriod;
}
/**
* SaaS Efficiency Score
* Combines multiple efficiency metrics
*/
export interface EfficiencyScore {
overall: number;
components: {
ltvCacRatio: number;
magicNumber: number;
quickRatio: number;
nrr: number;
ruleOf40: number;
};
period: MetricPeriod;
}
/**
* Sales pipeline metrics
*/
export interface Pipeline {
totalValue: number;
weightedValue: number;
stages: PipelineStage[];
velocity: number;
conversionRate: number;
currency: Currency;
asOf: Date;
}
/**
* Pipeline stage
*/
export interface PipelineStage {
name: string;
value: number;
count: number;
probability: number;
averageDaysInStage: number;
}
/**
* Sales velocity
* (Opportunities * Win Rate * Average Deal Size) / Sales Cycle Length
*/
export interface SalesVelocity {
value: number;
opportunities: number;
winRate: number;
averageDealSize: number;
salesCycleLength: number;
currency: Currency;
period: MetricPeriod;
}
/**
* Net Promoter Score
*/
export interface NPS {
score: number;
promoters: number;
passives: number;
detractors: number;
responses: number;
responseRate?: number;
asOf: Date;
}
/**
* Customer health score
*/
export interface CustomerHealth {
averageScore: number;
healthy: number;
atRisk: number;
critical: number;
factors: HealthFactor[];
asOf: Date;
}
/**
* Health factor
*/
export interface HealthFactor {
name: string;
weight: number;
score: number;
}
/**
* Comprehensive SaaS metrics snapshot
*/
export interface SaaSMetrics {
mrr: MRR;
arr: ARR;
nrr: NRR;
grr: GRR;
arpu: ARPU;
cac: CAC;
ltv: LTV;
ltvCac: LTVtoCAC;
churn: Churn;
growthRate: GrowthRate;
quickRatio: QuickRatio;
magicNumber?: MagicNumber;
burnMultiple?: BurnMultiple;
ruleOf40?: RuleOf40;
nps?: NPS;
customerHealth?: CustomerHealth;
period: MetricPeriod;
generatedAt: Date;
}
/**
* Calculate MRR from components
*/
export declare function calculateMRR(input: {
newMRR: number;
expansionMRR: number;
contractionMRR: number;
churnedMRR: number;
reactivationMRR?: number;
previousMRR: number;
currency?: Currency;
period: MetricPeriod;
}): MRR;
/**
* Calculate ARR from MRR
*/
export declare function calculateARRFromMRR(mrr: number, currency?: Currency): ARR;
/**
* Calculate NRR
*/
export declare function calculateNRR(input: {
startingMRR: number;
expansion: number;
contraction: number;
churn: number;
period: MetricPeriod;
}): NRR;
/**
* Calculate GRR
*/
export declare function calculateGRR(input: {
startingMRR: number;
contraction: number;
churn: number;
period: MetricPeriod;
}): GRR;
/**
* Calculate CAC
*/
export declare function calculateCACMetric(input: {
salesMarketingSpend: number;
newCustomers: number;
currency?: Currency;
period: MetricPeriod;
byChannel?: Record<string, {
spend: number;
customers: number;
}>;
}): CAC;
/**
* Calculate LTV
*/
export declare function calculateLTVMetric(input: {
arpu: number;
grossMargin: number;
churnRate: number;
currency?: Currency;
}): LTV;
/**
* Calculate LTV:CAC ratio
*/
export declare function calculateLTVtoCACRatio(ltv: LTV, cac: CAC): LTVtoCAC;
/**
* Calculate Quick Ratio
*/
export declare function calculateQuickRatioMetric(mrr: MRR): QuickRatio;
/**
* Calculate Magic Number
*/
export declare function calculateMagicNumberMetric(input: {
netNewARR: number;
salesMarketingSpend: number;
period: MetricPeriod;
}): MagicNumber;
/**
* Calculate Burn Multiple
*/
export declare function calculateBurnMultipleMetric(input: {
netBurn: number;
netNewARR: number;
period: MetricPeriod;
}): BurnMultiple;
/**
* Calculate Rule of 40
*/
export declare function calculateRuleOf40Metric(input: {
revenueGrowthRate: number;
profitMargin: number;
period: MetricPeriod;
}): RuleOf40;
/**
* Calculate growth rates
*/
export declare function calculateGrowthRates(input: {
current: number;
previousMonth?: number;
previousQuarter?: number;
previousYear?: number;
metric: string;
period: MetricPeriod;
}): GrowthRate;
/**
* Calculate churn metrics
*/
export declare function calculateChurnMetrics(input: {
customersStart: number;
customersLost: number;
mrrStart: number;
mrrChurned: number;
expansionMRR: number;
period: MetricPeriod;
}): Churn;
/**
* Aggregate time series data by period
*/
export declare function aggregateTimeSeries<T extends number>(series: TimeSeries<T>, targetPeriod: TimePeriod): TimeSeries<T>;
/**
* Create metric period from dates
*/
export declare function createMetricPeriod(period: TimePeriod, start: Date, end: Date, label?: string): MetricPeriod;
//# sourceMappingURL=metrics.d.ts.map