The API returns macro_enabled/competitive_enabled but the TypeScript
interfaces expected 'enabled'. The toggles always showed disabled.
Now handles both field names with fallback.
The SQL Explorer was querying Trino which has zero tables. Rewrote to
use PostgreSQL directly:
Backend:
- GET /api/analytics/pg-schema: returns all public tables with column
names, types, and nullability from information_schema
- POST /api/analytics/pg-query: read-only SQL execution against
PostgreSQL with SELECT-only enforcement, auto LIMIT, and descriptive
error messages for syntax/table/query errors
Frontend:
- Schema browser shows all PostgreSQL tables with columns and types
- Click a table name → generates SELECT * FROM table LIMIT 100
- Pre-built Queries section with 12 seeded queries covering companies,
recommendations, trends, market prices, documents, global events,
trading decisions, ingestion health, reserve pool, sector exposure
- User-saved queries shown separately with delete buttons
- Chart builder, Monaco editor, and save functionality preserved
Migration 021: seeds 12 pre-built saved queries
The Trino/Iceberg lakehouse has zero tables, so all Trino-backed
dashboards showed 'No data available'. Rewrote all four to use
existing PostgreSQL-backed API endpoints:
- Sentiment Heatmap: useTrends + useCompanies → sector and ticker
trend strength bar charts (30k trend_windows in DB)
- Prediction Accuracy: useRecommendations → confidence distribution
and action distribution charts (30k recommendations in DB)
- Paper PnL: useTradingMetrics + useTradingMetricsHistory → equity
curve, daily returns, win/loss stats from trading engine
- Model Quality: useModelPerformance + useModelFailures → success
rate, latency, retries, and failure table from ops API
Removed unused Trino query function and ScatterChart imports.
The throughput API returns one row per source_type per time bucket,
but the chart was mapping each row as a separate bar. With 5 source
types × 24 hours, the bars were tiny and overlapping. Now aggregates
completed/failed/items across source types per time bucket so the
chart shows meaningful totals.
When on /trading/engine, the /trading nav item also matched via
startsWith. Now checks if a more specific child route matches
first and uses exact match in that case.
TypeScript strict mode in CI rejects explicit parameter types on
Recharts formatter/tickFormatter callbacks. Use inference with
'as number' casts on the value instead. Also fix unsafe cast in
PortfolioComposition and handle possibly-undefined percent.