fix: InstitutionalReports — signal-aware category filter + Agri/Crypto/Bonds/Indices pills + Specialist Desks link

- Backend: category filter now ORs signal column so multi-category reports (category='multi') appear when filtering by Forex/Energy/Metals/Indices — fixes blank results
- Frontend: category pills expanded to match desk taxonomy (agri, crypto, bonds, indices added; equities kept for compatibility)
- Frontend: banner pointing to /specialist-desks clarifies the split between auto-fetched reports and manual desk report scheduling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-23 10:13:40 +02:00
parent 2fb683eec5
commit 2f9d067a94
2 changed files with 48 additions and 7 deletions

View File

@@ -114,7 +114,19 @@ def list_reports(
conditions.append("report_type = ?")
params.append(report_type)
if category:
conditions.append("category = ?")
# For categories that map to a signal column, also match reports
# where that signal is non-neutral (most reports have category='multi')
_signal_col = {
'forex': 'signal_forex',
'energy': 'signal_energy',
'metals': 'signal_metals',
'equities': 'signal_indices',
'indices': 'signal_indices',
}.get(category)
if _signal_col:
conditions.append(f"(category = ? OR {_signal_col} != 'neutral')")
else:
conditions.append("category = ?")
params.append(category)
if importance:
conditions.append("importance >= ?")

View File

@@ -1,7 +1,8 @@
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { useInstitutionalReports, useInstitutionalStats, useRefreshInstitutionalReports } from '../hooks/useApi'
import { useQueryClient } from '@tanstack/react-query'
import { RefreshCw, TrendingUp, TrendingDown, Minus, AlertTriangle, Star, CheckCircle, Clock } from 'lucide-react'
import { RefreshCw, TrendingUp, TrendingDown, Minus, AlertTriangle, Star, CheckCircle, Clock, Users, ExternalLink } from 'lucide-react'
import clsx from 'clsx'
import { format } from 'date-fns'
@@ -285,6 +286,21 @@ export default function InstitutionalReports() {
</div>
)}
{/* Specialist Desks link */}
<div className="flex items-center gap-3 bg-indigo-900/20 border border-indigo-700/40 rounded-lg px-4 py-2.5 text-xs text-indigo-300">
<Users className="w-3.5 h-3.5 shrink-0 text-indigo-400" />
<span className="flex-1">
Ces rapports sont <strong>analysés automatiquement</strong> (fetch + scoring IA). Pour gérer le <strong>calendrier des rapports par desk</strong> ajouter un rapport custom (ex. broyage cacao), planifier les prochaines dates, lier à un desk specialist
</span>
<Link
to="/specialist-desks"
className="flex items-center gap-1 bg-indigo-700/40 hover:bg-indigo-600/50 border border-indigo-600/50 rounded px-2.5 py-1 font-medium text-indigo-200 transition-colors shrink-0"
>
<ExternalLink className="w-3 h-3" />
Specialist Desks
</Link>
</div>
{/* Filters */}
<div className="flex flex-wrap gap-3 bg-dark-800 border border-slate-700/40 rounded-lg p-3">
<div className="flex items-center gap-2 flex-wrap">
@@ -310,18 +326,31 @@ export default function InstitutionalReports() {
<div className="flex items-center gap-2 flex-wrap">
<span className="text-xs text-slate-500">Category:</span>
<div className="flex flex-wrap gap-1">
{['', 'energy', 'metals', 'equities', 'forex', 'volatility', 'macro', 'sentiment', 'multi'].map(c => (
{([
{ v: '', label: 'All' },
{ v: 'energy', label: 'Energy' },
{ v: 'metals', label: 'Metals' },
{ v: 'agri', label: 'Agri' },
{ v: 'equities', label: 'Equities' },
{ v: 'forex', label: 'Forex' },
{ v: 'crypto', label: 'Crypto' },
{ v: 'bonds', label: 'Bonds' },
{ v: 'volatility',label: 'Volatility'},
{ v: 'macro', label: 'Macro' },
{ v: 'sentiment', label: 'Sentiment'},
{ v: 'multi', label: 'Multi' },
]).map(({ v, label }) => (
<button
key={c}
onClick={() => setFilterCategory(c)}
key={v}
onClick={() => setFilterCategory(v)}
className={clsx(
'px-2.5 py-1 rounded text-xs font-medium border transition-colors',
filterCategory === c
filterCategory === v
? 'bg-blue-600 text-white border-blue-500'
: 'bg-dark-700 text-slate-400 border-slate-700/40 hover:border-slate-600'
)}
>
{c === '' ? 'All' : c.charAt(0).toUpperCase() + c.slice(1)}
{label}
</button>
))}
</div>