Private
Public Access
1
0

feat(M1): Project scaffolding, DB schema, core infrastructure

- Initialize Rust workspace with 7 crates (pm-web, pm-worker, pm-core,
  pm-agent-client, pm-auth, pm-ca, pm-reports)
- React + TypeScript + Vite + MUI frontend scaffold
- Full PostgreSQL schema: all 17 tables with indexes and constraints
- pm-core: config (TOML+env), db (SQLx pool + migrations), error
  (unified AppError + JSON envelope), request_id (ULID middleware),
  logging (tracing JSON/pretty)
- pm-web: Axum skeleton, /status/health endpoint, static file serving
- pm-worker: Tokio skeleton, heartbeat writer, schema version check
- Embedded sqlx migrations with advisory lock (single-writer)
- systemd unit files, setup.sh, build-frontend.sh
- config.example.toml with all configuration keys
- docs/runbooks/restore.md
- cargo check passes with zero warnings

Closes M1.
This commit is contained in:
2026-04-23 15:55:53 +00:00
parent 3eb7fd9f95
commit da5a94d838
50 changed files with 6139 additions and 3 deletions

37
frontend/src/App.tsx Normal file
View File

@ -0,0 +1,37 @@
import { Routes, Route, Navigate } from 'react-router-dom'
import { CssBaseline, ThemeProvider } from '@mui/material'
import { lightTheme } from './theme/theme'
// Placeholder pages — implemented in M2+
const PlaceholderPage = ({ title }: { title: string }) => (
<div style={{ padding: 32 }}>
<h2>{title}</h2>
<p>Coming soon in a future milestone.</p>
</div>
)
function App() {
return (
<ThemeProvider theme={lightTheme}>
<CssBaseline />
<Routes>
<Route path="/" element={<Navigate to="/dashboard" replace />} />
<Route path="/dashboard" element={<PlaceholderPage title="Dashboard" />} />
<Route path="/hosts" element={<PlaceholderPage title="Hosts" />} />
<Route path="/hosts/:id" element={<PlaceholderPage title="Host Detail" />} />
<Route path="/jobs" element={<PlaceholderPage title="Jobs" />} />
<Route path="/deployment" element={<PlaceholderPage title="Patch Deployment" />} />
<Route path="/maintenance" element={<PlaceholderPage title="Maintenance Windows" />} />
<Route path="/groups" element={<PlaceholderPage title="Groups" />} />
<Route path="/reports" element={<PlaceholderPage title="Reports" />} />
<Route path="/users" element={<PlaceholderPage title="Users" />} />
<Route path="/certificates" element={<PlaceholderPage title="Certificates" />} />
<Route path="/settings" element={<PlaceholderPage title="Settings" />} />
<Route path="/login" element={<PlaceholderPage title="Login" />} />
<Route path="*" element={<PlaceholderPage title="404 Not Found" />} />
</Routes>
</ThemeProvider>
)
}
export default App