fix: harden Structural S/R after OHLCV writes and surface cleanup failures
Honor custom S/R tolerance as a transient detect, refresh levels after OHLCV mutations without failing committed price writes, report per-ticker S/R rebuild failures from admin cleanup, and warn in the admin UI when refresh is partial.
This commit is contained in:
@@ -269,9 +269,18 @@ export function acknowledgeSystemEvents(days = 7) {
|
||||
}
|
||||
|
||||
// Data cleanup
|
||||
export interface CleanupResult {
|
||||
ohlcv: number;
|
||||
sentiment: number;
|
||||
fundamentals: number;
|
||||
sr_refresh_ok: number;
|
||||
sr_refresh_failed: number;
|
||||
sr_refresh_failures: { symbol: string; error: string }[];
|
||||
}
|
||||
|
||||
export function cleanupData(olderThanDays: number) {
|
||||
return apiClient
|
||||
.post<{ message: string }>('admin/data/cleanup', {
|
||||
.post<CleanupResult>('admin/data/cleanup', {
|
||||
older_than_days: olderThanDays,
|
||||
})
|
||||
.then((r) => r.data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
type ToastType = 'success' | 'error' | 'info';
|
||||
type ToastType = 'success' | 'error' | 'info' | 'warning';
|
||||
|
||||
interface Toast {
|
||||
id: string;
|
||||
@@ -22,6 +22,7 @@ const typeStyles: Record<ToastType, string> = {
|
||||
error: 'border-red-500/30 bg-red-500/10 text-red-300',
|
||||
success: 'border-emerald-500/30 bg-emerald-500/10 text-emerald-300',
|
||||
info: 'border-blue-500/30 bg-blue-500/10 text-blue-300',
|
||||
warning: 'border-amber-500/30 bg-amber-500/10 text-amber-300',
|
||||
};
|
||||
|
||||
export function ToastProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
@@ -404,7 +404,30 @@ export function useCleanupData() {
|
||||
return useMutation({
|
||||
mutationFn: (olderThanDays: number) => adminApi.cleanupData(olderThanDays),
|
||||
onSuccess: (data) => {
|
||||
addToast('success', (data as { message: string }).message || 'Cleanup completed');
|
||||
const deleted =
|
||||
(data.ohlcv ?? 0) + (data.sentiment ?? 0) + (data.fundamentals ?? 0);
|
||||
const failed = data.sr_refresh_failed ?? 0;
|
||||
if (failed > 0) {
|
||||
const symbols = (data.sr_refresh_failures ?? [])
|
||||
.map((f) => f.symbol)
|
||||
.filter(Boolean);
|
||||
const sample = symbols.slice(0, 8).join(', ');
|
||||
const more = symbols.length > 8 ? ` (+${symbols.length - 8} more)` : '';
|
||||
addToast(
|
||||
'warning',
|
||||
`Cleanup deleted ${deleted} row(s), but Structural S/R refresh failed for ${failed} ticker(s)` +
|
||||
(sample ? `: ${sample}${more}` : '') +
|
||||
'. Re-run the R:R scan or a per-ticker refresh to rebuild levels.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
addToast(
|
||||
'success',
|
||||
`Cleanup completed — deleted ${deleted} row(s)` +
|
||||
(data.sr_refresh_ok
|
||||
? `; rebuilt S/R for ${data.sr_refresh_ok} ticker(s)`
|
||||
: ''),
|
||||
);
|
||||
},
|
||||
onError: (error: Error) => {
|
||||
addToast('error', error.message || 'Failed to cleanup data');
|
||||
|
||||
Reference in New Issue
Block a user