feat: enhance project structure with server and workflow management

- Introduced a new server package with Fastify for handling API requests and workflows.
- Implemented user authentication and authorization with JWT and cookie management.
- Added endpoints for managing workflows, runs, and user accounts.
- Established a dashboard for monitoring workflow status and statistics.
- Included a script sandbox for executing user-defined scripts securely.
- Updated README with setup instructions and API documentation.
- Configured database migrations for user management.
- Enhanced logging capabilities for better traceability.
This commit is contained in:
2026-08-14 14:25:37 +07:00
parent 5574d6f723
commit 023cf83cfa
48 changed files with 6127 additions and 359 deletions
+60
View File
@@ -0,0 +1,60 @@
import { useEffect } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { useQueryClient } from "@tanstack/react-query";
import { useBootstrap, useMe } from "./api/hooks.js";
import { Layout } from "./components/Layout.jsx";
import { AuthPage } from "./pages/AuthPage.jsx";
import { HomePage } from "./pages/HomePage.jsx";
import { ScriptsPage } from "./pages/ScriptsPage.jsx";
import { WorkflowsPage } from "./pages/WorkflowsPage.jsx";
import { EventsPage } from "./pages/EventsPage.jsx";
import { EventDetailPage } from "./pages/EventDetailPage.jsx";
import { UsersPage } from "./pages/UsersPage.jsx";
export function App() {
const qc = useQueryClient();
const bootstrap = useBootstrap();
const me = useMe();
useEffect(() => {
function onUnauthorized() {
qc.setQueryData(["me"], null);
}
window.addEventListener("scrunner:unauthorized", onUnauthorized);
return () => window.removeEventListener("scrunner:unauthorized", onUnauthorized);
}, [qc]);
const user = me.data?.user;
const loading =
bootstrap.isLoading || (me.isLoading && !me.isError && me.data === undefined);
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
<span className="loading loading-spinner loading-lg" />
</div>
);
}
if (!user) {
return <AuthPage needsSetup={Boolean(bootstrap.data?.needsSetup)} />;
}
return (
<Layout user={user}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/scripts" element={<ScriptsPage />} />
<Route path="/workflows" element={<WorkflowsPage />} />
<Route path="/events" element={<EventsPage />} />
<Route path="/events/:id" element={<EventDetailPage />} />
{user.role === "admin" ? (
<Route path="/users" element={<UsersPage />} />
) : (
<Route path="/users" element={<Navigate to="/" replace />} />
)}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Layout>
);
}