query( "SELECT COUNT(*) AS total, SUM(rating = 'positive') AS positive, SUM(rating = 'negative') AS negative FROM tool_feedback" )->fetch(); $byTool = $db->query( "SELECT tool, COUNT(*) AS total, SUM(rating = 'positive') AS positive, SUM(rating = 'negative') AS negative, MAX(created_at) AS last_at FROM tool_feedback GROUP BY tool ORDER BY total DESC, tool ASC" )->fetchAll(); $byEngine = $db->query( "SELECT COALESCE(NULLIF(engine, ''), '(unknown)') AS engine, COUNT(*) AS total, SUM(rating = 'positive') AS positive, SUM(rating = 'negative') AS negative FROM tool_feedback GROUP BY engine ORDER BY total DESC, engine ASC" )->fetchAll(); $recent = $db->query( "SELECT tool, rating, engine, missed_or_wrong, created_at FROM tool_feedback WHERE missed_or_wrong IS NOT NULL AND missed_or_wrong <> '' ORDER BY created_at DESC LIMIT 50" )->fetchAll(); $toInt = static fn($v): int => (int) ($v ?? 0); dbnToolsRespond([ 'ok' => true, 'totals' => [ 'total' => $toInt($totalsRow['total'] ?? 0), 'positive' => $toInt($totalsRow['positive'] ?? 0), 'negative' => $toInt($totalsRow['negative'] ?? 0), ], 'by_tool' => array_map(static fn(array $r): array => [ 'tool' => $r['tool'], 'total' => $toInt($r['total']), 'positive' => $toInt($r['positive']), 'negative' => $toInt($r['negative']), 'last_at' => $r['last_at'], ], $byTool), 'by_engine' => array_map(static fn(array $r): array => [ 'engine' => $r['engine'], 'total' => $toInt($r['total']), 'positive' => $toInt($r['positive']), 'negative' => $toInt($r['negative']), ], $byEngine), 'recent' => array_map(static fn(array $r): array => [ 'tool' => $r['tool'], 'rating' => $r['rating'], 'engine' => $r['engine'], 'missed_or_wrong' => $r['missed_or_wrong'], 'created_at' => $r['created_at'], ], $recent), ]); } catch (DbnToolsHttpException $e) { dbnToolsError($e->getMessage(), $e->status, $e->errorCode, $e->extra ?? []); } catch (Throwable $e) { error_log('[dbn-feedback] ' . $e->getMessage()); dbnToolsError('Feedback review failed.', 500, 'op_failed'); }