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 ECOAPIWarning
API_SECRETis 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_year→years - Extracts
revenue_sek→turnover - Extracts
employees→employees - Builds growth signals from
trends.revenueGrowthandtrends.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:
| Field | Condition | Priority |
|---|---|---|
financials | No finansiell_historik AND no omsattning AND no anstallda | high |
contacts | kontakter array empty | high |
website | No hemsida AND no domain | medium |
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_URLto 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
- Hooks Reference —
useEcoApiconsumes these functions - Kundkort Overview — Where ECOAPI fits in the data flow