Services Reference

ecoApiClient

File: frontend/kundkort/services/ecoApiClient.ts

The ECOAPI client provides analytics and enrichment services that complement the main kundkort API. It communicates with a separate ECOAPI service (financial data + insights) and the main backend (gaps + enrichment).


Configuration

const ECO_API_URL = window.__ECOAPI_URL__ || 'http://localhost:3100';
const API_SECRET = 'change-me-to-a-random-secret'; // Bearer token for ECOAPI

Warning

API_SECRET is hardcoded. In production this must be injected at build time or served via secure config.


Types

EcoApiInsights

interface EcoApiInsights {
  org_nr: string;
  financial_trend: {
    years: number[];
    turnover: (number | null)[];
    employees: (number | null)[];
  };
  contact_distribution: Record<string, number>;
  data_completeness: {
    overall: number;
    by_category: Record<string, number>;
  };
  growth_signals: string[];
  risk_signals: string[];
}

DataGap

interface DataGap {
  field: string;
  priority: 'high' | 'medium' | 'low';
  current_value: any;
  fillable_via_enrichment: boolean;
}

GapsResponse

interface GapsResponse {
  org_nr: string;
  total_gaps: number;
  high_priority_gaps: number;
  gaps: DataGap[];
  recommendation: string;
}

Functions

fetchInsights(orgNr, token)

Endpoint: GET ${ECO_API_URL}/api/companies/:orgNr/financials

Auth: Authorization: Bearer ${API_SECRET}, X-Client-Token: ${token}

Purpose: Fetch financial trend data from the ECOAPI service.

Transformations:

  • Reverses financials array (oldest → newest)
  • Extracts fiscal_yearyears
  • Extracts revenue_sekturnover
  • Extracts employeesemployees
  • Builds growth signals from trends.revenueGrowth and trends.profitGrowth

404 handling: Returns empty insights object (no throw).

Returns: EcoApiInsights


fetchGaps(orgNr, token)

Endpoint: GET /api/kundkort/:orgNr (main API)

Auth: Authorization: Bearer ${token}

Purpose: Analyze data completeness and identify gaps.

Gap detection logic:

FieldConditionPriority
financialsNo finansiell_historik AND no omsattning AND no anstalldahigh
contactskontakter array emptyhigh
websiteNo hemsida AND no domainmedium

Returns: GapsResponse with recommendation: 'enrich' (if >2 gaps) or 'minimal_gaps'


triggerEcoEnrichment(orgNr, token)

Endpoint: POST /api/kundkort/:orgNr/enrich

Auth: Authorization: Bearer ${token}

Body: { force_refresh: true }

Purpose: Trigger on-demand enrichment pipeline for a company.

Returns: Enrichment result JSON.


fetchFinancialTrend(orgNr, token)

Purpose: Convenience wrapper around fetchInsights that returns only the financial trend subset.

Returns: { org_nr, financial_trend, has_historical_data }


fetchContactDistribution(orgNr, token)

Endpoint: GET /api/kundkort/:orgNr (main API)

Purpose: Group contacts by role and compute coverage stats.

Returns:

{
  org_nr: string;
  total_contacts: number;
  contact_distribution: Record<string, number>;
  contacts_with_email: number;
  contacts_with_phone: number;
}

Request Helper

function ecoApiFetch(path: string, token: string): Promise<Response>

All ECOAPI calls use this helper. It:

  • Prepends ECO_API_URL to the path
  • Sets Authorization: Bearer ${API_SECRET}
  • Sets X-Client-Token: ${token} for audit/logging

Main API calls (gaps, enrichment, contact distribution) use standard fetch with Authorization: Bearer ${token}.


See also

See also