Klark
Plateforme SaaS B2B d'agrégation de données business
10K+
Utilisateurs
< 200ms
Temps de réponse
99.9%
Uptime
Stack technologique
Contexte
Klark Industries est une entreprise industrielle qui jonglait avec une dizaine de sources de données hétérogènes : ERP SAP, fichiers Excel partagés, exports CSV de plusieurs outils SaaS métier, et bases de données internes legacy. Les équipes passaient chaque semaine plusieurs heures à consolider manuellement ces données pour produire leurs rapports de pilotage. La direction ne disposait pas d'une vision temps réel de ses indicateurs clés.
La mission : construire une plateforme centralisée qui agrège, normalise et expose ces données à travers des dashboards interactifs, avec une couche IA pour répondre en langage naturel aux questions métier.
Défis techniques
Intégration de sources hétérogènes
Chaque source de données avait ses propres formats, fréquences de mise à jour et niveaux de fiabilité. L'ERP SAP exposait une API SOAP héritée, les exports CSV n'avaient pas de schéma fixe, et certains systèmes legacy ne supportaient que le polling via FTP.
// lib/connectors/base-connector.ts
export abstract class BaseConnector {
abstract readonly sourceId: string;
abstract readonly pollingInterval: number;
abstract fetchRawData(): Promise<RawDataPayload>;
abstract transform(raw: RawDataPayload): Promise<NormalizedRecord[]>;
async sync(): Promise<SyncResult> {
const raw = await this.fetchRawData();
const records = await this.transform(raw);
await this.upsertToMongoDB(records);
return { count: records.length, sourceId: this.sourceId };
}
private async upsertToMongoDB(records: NormalizedRecord[]) {
const ops = records.map((r) => ({
updateOne: {
filter: { externalId: r.externalId, sourceId: this.sourceId },
update: { $set: { ...r, syncedAt: new Date() } },
upsert: true,
},
}));
await db.collection("records").bulkWrite(ops, { ordered: false });
}
}Performance des dashboards
Avec des millions d'enregistrements, les agrégations MongoDB devaient être soigneusement optimisées. Nous avons mis en place un système de pre-aggregation qui calcule les métriques toutes les 5 minutes et les stocke dans des collections dédiées.
// jobs/aggregate-metrics.ts
export async function aggregateSalesMetrics(orgId: string, period: "day" | "week" | "month") {
const pipeline = [
{ $match: { organizationId: orgId, type: "sale", date: { $gte: getPeriodStart(period) } } },
{
$group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
totalRevenue: { $sum: "$amount" },
orderCount: { $sum: 1 },
avgOrderValue: { $avg: "$amount" },
},
},
{ $sort: { _id: 1 } },
];
const results = await db.collection("records").aggregate(pipeline).toArray();
await db.collection("metrics_cache").replaceOne(
{ orgId, type: "sales", period },
{ orgId, type: "sales", period, data: results, computedAt: new Date() },
{ upsert: true }
);
}Assistant IA en langage naturel
La fonctionnalité la plus stratégique est un assistant capable de répondre à des questions comme « Quel est mon chiffre d'affaires du mois comparé à l'an dernier ? » en générant et exécutant dynamiquement des requêtes MongoDB.
// lib/ai/query-agent.ts
async function answerBusinessQuestion(question: string, orgContext: OrgContext) {
const schemaDescription = await buildSchemaDescription(orgContext.orgId);
const { query } = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "system",
content: `You are a MongoDB query generator. Given the schema: ${schemaDescription}
Generate a valid MongoDB aggregation pipeline as JSON. Only output JSON.`,
},
{ role: "user", content: question },
],
response_format: { type: "json_object" },
});
const pipeline = JSON.parse(query.choices[0].message.content!);
const results = await db.collection("records")
.aggregate([{ $match: { organizationId: orgContext.orgId } }, ...pipeline])
.toArray();
return results;
}Solution déployée
L'architecture finale repose sur Next.js 15 pour le front-end et les API routes, MongoDB Atlas pour la persistence et les recherches vectorielles, AWS Lambda pour les jobs de synchronisation périodiques, et CloudFront pour la distribution des assets statiques. Les connecteurs tournent sur AWS EventBridge avec des schedules configurables par client.
La plateforme supporte le multi-tenant avec isolation complète des données par organisation, gestion des rôles (admin, éditeur, lecteur) et audit log de toutes les actions sensibles.
Résultats
Le déploiement initial a couvert 8 connecteurs (SAP, Salesforce, HubSpot, Shopify, QuickBooks, et trois bases internes). En production depuis décembre 2025, la plateforme traite plus de 2 millions d'enregistrements par jour avec un temps de réponse médian de 145ms sur les dashboards pré-agrégés.
Les équipes opérationnelles ont réduit leur temps de reporting hebdomadaire de 6 heures à moins de 30 minutes. Le ROI annoncé par le client à 6 mois de déploiement est de 4x le coût du projet.