L’objectif est simple : évaluer vos compétences en architecture backend, en gestion de données, et en développement frontend autour d’un petit projet de Business Intelligence.
👉 Ce test est conçu pour être réalisé en une demi-journée maximum.
👉 Une fois terminé, merci de le remettre dans un dépôt GitHub privé et de nous y inviter.
Lexique :
- CPC (coût par clic) : coût moyen d'un clic sur une période et/ou un segment donnée (jour, client, canal...).
Pour gagner du temps, un starter kit vous est fourni avec :
-
Backend
- API fonctionnelle avec Fastify
- DuckDB pour requêter les données (Fichier Parquet) en SQL
- Vitest pour les tests unitaires
-
Frontend
- Next.js (React 18 + TypeScript)
- shadcn/ui (UI kit basé sur Radix + Tailwind)
- React Query déjà connecté à l’API
Le Figma est fourni à titre indicatif, vous êtes libre d'intégrer le design de votre choix.
Priorité au backend : architecture modulaire (Collectors / Calculators / Requests), validation, tests, performance.
Vous n’avez pas besoin de tout réinventer : le but est d’étendre et d’architecturer proprement.
- shadcn/ui → composants UI (cards, table, date picker, etc.)
- Recharts → graphiques (bar/line chart)
- Zustand → gestion d’état simple et scalable côté frontend
- React Table → tableaux filtrables/paginés
- React Query → data fetching (déjà intégré au starter)
- Zod → validation données au runtime
- DuckDB → pour requêter les données (Fichier Parquet) en SQL
👉 Vous êtes libre d’utiliser les librairies de votre choix, tant que l’architecture et les fonctionnalités demandées sont respectées.
- Un fichier parquet (
data/clicks.parquet
) - Clients : Nike, Adidas, Hoka, On, Brooks
- Canaux : Instagram, Tiktok, Facebook, Google
- Période : 2024-01-01 → 2025-09-01
- Entre 50 et 200 clics par jour et par client
- Format : client,canal,cost,datetime
- cost ∈ [0.30 ; 10.00] (€/clic)
// Pour chacunes de ces interfaces, des paramètres peuvent être passés dans le constructeur
export interface Collector<TData> { load(): Promise<TData>; }
export interface Calculator<TInput, TOutput> { compute(input: TInput): Promise<TOutput>; }
export interface Request<TResponse> { execute(params: RequestParams): Promise<TResponse>; }
Request.execute(params)
:
- appelle un Collector (lecture parquet + pré-filtres),
- appelle un Calculator (logique métier / KPIs),
- renvoie un DTO stable qui sera directement retourné par la route.
GET /cpc/series?date_from=&date_to=&client=
- date_from : obligatoire
- date_to : obligatoire
- client : optionnel, si non précisé tous les clients sont aggrégés
[
{"date":"2024-01-01","cpc":1.84,"count":1245},
{"date":"2024-01-02","cpc":1.73,"count":1180}
]
GET /cpc/by-client?date_from=&date_to=&canal=
- date_from : obligatoire
- date_to : obligatoire
- canal : optionnel, si non précisé tous les canaux sont aggrégés
[
{"client":"On","cpc":1.62,"count":982},
{"client":"Adidas","cpc":1.87,"count":1011},
{"client":"Hoka","cpc":0.95,"count":940}
]
GET /clicks?date_from=&date_to=
[
{"client":"Nike","canal":"Instagram","cost":5.40,"datetime":"2024-01-01 14:53:00"},
{"client":"Hoka","canal":"Facebook","cost":5.40,"datetime":"2024-01-01 14:53:00"}
]
- Date range picker (par défaut : 01/01/2025 → 31/01/2025).
- Line chart (CPC) :
GET /cpc/series?date_from=&date_to=&client=
- Bar chart (CPC par client) :
GET /cpc/by-client?date_from=&date_to=&canal=
- Table “Clics” :
GET /clicks?date_from=&date_to=
- recherche côté client sur client/canal
- pagination
- colonnes : Client / Canal / Coût / Date.
- 1 test unitaire de Calculator
- 1 test unitaire de Request
- Repo GitHub privé contenant :
- FEEDBACK.md (explications de l'architecture, des choix techniques, avis sur le test et commentaires).
- Les modifications effectuées sur le code.
- Commits progressifs.
- Invitez-nous en tant que collaborateurs sur le dépôt privé.
- Architecture & DIC (35)
- Calcul & exactitude (20)
- Qualité code (15)
- Frontend & data-viz (15)
- Tests (10)
- Doc (5)
-
Cloner le repo :
git clone https://github.com/YieldStudio/react-node-bi-technical-test.git cd react-node-bi-technical-test
-
Lancer le projet :
pnpm install pnpm run dev
-
Vérifier que le front-end est accessible à l’adresse
http://localhost:3000
. -
Vérifier que le back-end est accessible à l’adresse
http://localhost:3001
. -
Vérifier que les tests fonctionnent :
pnpm run test # Vous pouvez lancer les tests en mode watch depuis le dossier apps/api cd apps/api pnpm run test:watch
-
Commencer à implémenter les fonctionnalités demandées.
-
Créer un dépôt privé sur GitHub depuis votre compte.
-
Changer l’origine Git pour pointer vers votre dépôt privé :
git remote remove origin git remote add origin git@github.com:<votre-compte>/<votre-repo-prive>.git
-
Pousser votre travail :
git push -u origin main
-
Invitez-nous en tant que collaborateurs sur ce dépôt privé (vous recevrez nos identifiants GitHub par email).