Outbox dispatcher (background thread, FOR UPDATE SKIP LOCKED claim, exponential backoff, no transaction held during HTTP I/O). n8n callback endpoint with shared-secret auth and idempotency by event ID. Automation nav + UI with manual retry. 49 backend tests passing, ruff clean. Fixed a crash-on-redelivery bug in seeded outbox payloads and made the dispatcher defensive against malformed payloads. Verified the full live round trip against a real n8n instance: return -> outbox -> dispatcher -> n8n workflow -> callback -> succeeded, including the S5 failed-retry demo scenario.
44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import { Navigate, Route, Routes } from "react-router-dom";
|
|
import { AuthProvider } from "./context/AuthContext";
|
|
import { Layout } from "./components/Layout";
|
|
import { RequireAuth } from "./components/RequireAuth";
|
|
import { Login } from "./pages/Login";
|
|
import { Dashboard } from "./pages/Dashboard";
|
|
import { Vehicles } from "./pages/Vehicles";
|
|
import { VehicleDetail } from "./pages/VehicleDetail";
|
|
import { Bookings } from "./pages/Bookings";
|
|
import { BookingDetail } from "./pages/BookingDetail";
|
|
import { DataQuality } from "./pages/DataQuality";
|
|
import { DataQualityIssueDetail } from "./pages/DataQualityIssueDetail";
|
|
import { Automation } from "./pages/Automation";
|
|
import { Audit } from "./pages/Audit";
|
|
|
|
export function App() {
|
|
return (
|
|
<AuthProvider>
|
|
<Routes>
|
|
<Route path="/login" element={<Login />} />
|
|
<Route
|
|
element={
|
|
<RequireAuth>
|
|
<Layout />
|
|
</RequireAuth>
|
|
}
|
|
>
|
|
<Route path="/dashboard" element={<Dashboard />} />
|
|
<Route path="/vehicles" element={<Vehicles />} />
|
|
<Route path="/vehicles/:publicRef" element={<VehicleDetail />} />
|
|
<Route path="/bookings" element={<Bookings />} />
|
|
<Route path="/bookings/:publicRef" element={<BookingDetail />} />
|
|
<Route path="/data-quality" element={<DataQuality />} />
|
|
<Route path="/data-quality/:publicRef" element={<DataQualityIssueDetail />} />
|
|
<Route path="/automation" element={<Automation />} />
|
|
<Route path="/audit" element={<Audit />} />
|
|
</Route>
|
|
<Route path="/" element={<Navigate to="/dashboard" replace />} />
|
|
<Route path="*" element={<Navigate to="/dashboard" replace />} />
|
|
</Routes>
|
|
</AuthProvider>
|
|
);
|
|
}
|