================================================================================ QA #21 — Enhance Matching Results & AI Assistant (Company Enrichment + Insights) Agent : QA manuelle (#25) Date : 2026-06-11 Worktree : .worktrees/redmine-21-insights-ui Branche : feat/redmine-21-insights-ui PR #239 (base dev) Commits : 6775adb #58, de4b286 #61+#63, aa371db #64, d33026c #66, cd2d2c4 #67 ================================================================================ RESULTAT GLOBAL : FAIL (regression i18n bloquante introduite par #66) -------------------------------------------------------------------------------- COMMANDES EXECUTEES -------------------------------------------------------------------------------- $ npx prisma generate -> OK (client genere) $ npx vitest run <7 suites de l'epic> -> 7 fichiers / 43 tests PASS $ npx tsc --noEmit -> erreurs (voir analyse) $ node (transpile en.ts/fr.ts + resolution runtime) -> preuve de collision de cle Secrets : aucun secret (cle Mistral, DB URL, tokens) n'apparait dans cette preuve. -------------------------------------------------------------------------------- TESTS UNITAIRES AJOUTES PAR L'EPIC -> 43/43 PASS -------------------------------------------------------------------------------- PASS src/domain/services/__tests__/MarketInsightsService.test.ts (11) PASS src/app/api/market-insights/__tests__/route.test.ts ( 8) PASS src/components/molecules/__tests__/CompanyEnrichmentCard.test.tsx ( 5) PASS src/components/molecules/__tests__/MarketInsightsSection.test.tsx ( 5) PASS src/infrastructure/ai/__tests__/assistantCompanyAndInsights.test.ts ( 5) PASS src/application/use-cases/__tests__/SendAssistantMessageUseCase.prompt.test.ts (4) PASS src/lib/__tests__/attachCompanyData.enrichment.test.ts ( 5) -------------------------------------------------------------------------------- ACCEPTANCE — inspection source + tests -------------------------------------------------------------------------------- AC1 Carte entreprise inline (#64/#58) : OK (code + tests) - CompanyEnrichmentCard.tsx : rendu present-only, retourne null si aucune enrichment (pas de champ invente), lien /companies/, expand/collapse. - attachCompanyData.ts : objet companyEnrichment construit uniquement a partir des champs non-null ; omis entierement si vide. NO-FAKE-DATA respecte. - Rendu dans OfferMatchDetail.tsx (l.776/792) + MatchedOfferCard.tsx. AC2 Section Market Insights (#66/#61/#63) : KO <-- voir REGRESSION - Logique d'agregation (MarketInsightsService.computeMarketInsights) correcte : compte reel par offre, % work-mode sur lignes classifiables seulement, corpus vide -> agregats vides (pas de chiffre invente). Endpoint GET /api/market-insights?role=&location= present, filtre active-offer canonique (findActiveMarketInsightRows / buildWhereClause), cache 30 min. - MAIS la livraison #66 introduit une REGRESSION i18n bloquante (ci-dessous). AC3 Assistant (#67) : OK (cablage outils) - Outils get_company_data / get_market_insights declares dans AssistantToolRegistry.ts et implementes dans AssistantToolExecutor.ts (present-only, "donnee indisponible" si absent ; agregat reel sinon). - System prompt (SendAssistantMessageUseCase) : sections "Donnees entreprise (proactif)" + "Competences AVANT localisation (priorite)" avec consigne "aucune valeur inventee". Tests prompt + tool-wiring PASS. -------------------------------------------------------------------------------- REGRESSION BLOQUANTE — collision de cle i18n "marketInsights" (#66, commit d33026c) -------------------------------------------------------------------------------- Fichiers : src/infrastructure/i18n/translations/en.ts et fr.ts tsc : en.ts(3114,3): error TS1117: An object literal cannot have multiple properties with the same name. fr.ts(3123,3): error TS1117: (idem) Cause : Il existe DEJA un bloc top-level `marketInsights:` (en.ts l.2771 / fr.ts l.2780) = toute la page "Market Statistics" (title, subtitle, tabs, kpi, compensation...). #66 a ajoute un SECOND bloc top-level `marketInsights:` (en.ts l.3114 / fr.ts l.3123) avec seulement ~14 cles pour la nouvelle section. En litteral objet JS, la DERNIERE cle dupliquee ECRASE la premiere. Preuve de resolution runtime (transpile + eval) : EN marketInsights.title => "Market insights" (attendu "Market Statistics") EN marketInsights.tabs => undefined (bloc d'origine ecrase) EN marketInsights.kpi => undefined FR marketInsights.title => "Tendances du marche" FR marketInsights.tabs => undefined FR marketInsights.kpi => undefined Impact : La page existante /profile/developer/market-insights consomme ~40+ cles t('marketInsights.title' | '.tabs.*' | '.kpi.*' | '.compensation.*' ...). Toutes ces cles renvoient desormais undefined / la cle brute a l'execution. => page Market Statistics cassee (titres, onglets, labels) en EN et FR. Correctif attendu : Renommer le nouveau bloc (ex. `marketInsightsSection:`) ou fusionner ses cles DANS le bloc existant (l.2771) plutot que de creer un 2e top-level. Mettre a jour MarketInsightsSection.tsx en consequence. Idem en.ts ET fr.ts. -------------------------------------------------------------------------------- NOTE tsc : le reste des erreurs tsc du projet (remotion/, importer mappers, scripts/, subscription-limits, companyPageData...) sont pre-existantes et hors scope de cet epic. Seules les 2 erreurs i18n ci-dessus + l'erreur de type MatchOffersForDeveloperUseCase l.369 touchent les fichiers de l'epic ; la collision i18n est la regression fonctionnelle bloquante. ================================================================================