d843f9ff12
fix: add serde rename_all to all enums for correct JSON serialization
...
CI Pipeline / Rust Format Check (push) Failing after 3s
CI Pipeline / Clippy Lints (push) Successful in 45s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 12s
CI Pipeline / Build .deb & Release (push) Has been skipped
All 6 enums in pm-core/src/models.rs had #[sqlx(rename_all)] for
database mapping but were missing #[serde(rename_all)] for JSON.
Backend expected PascalCase (Once, Daily, etc.) but frontend sent
lowercase (once, daily, etc.), causing deserialization errors like:
"unknown variant once, expected Once, Daily, Weekly, Monthly"
Fixed enums:
- HostHealthStatus: serde(rename_all = "lowercase")
- UserRole: serde(rename_all = "lowercase")
- AuthProvider: serde(rename_all = "snake_case")
- JobStatus: serde(rename_all = "lowercase")
- JobKind: serde(rename_all = "snake_case")
- WindowRecurrence: serde(rename_all = "lowercase")
Frontend types already matched - no frontend changes needed.
2026-04-29 01:45:47 +00:00
83c97aa2b1
fix: resolve all startup bugs (BUG-6 through BUG-9)
...
CI Pipeline / Rust Format Check (push) Failing after 36s
CI Pipeline / Clippy Lints (push) Successful in 45s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 11s
CI Pipeline / Build .deb & Release (push) Has been skipped
BUG-6: Add TLS support via axum-server + rustls
- Added axum-server with tls-rustls feature to workspace and pm-web
- pm-web now serves HTTPS when TLS certs exist, falls back to HTTP with warning
- setup.sh generates self-signed ECDSA P-256 TLS cert with SANs
- Config already had web_tls_cert_path/web_tls_key_path fields
BUG-7: Fix audit chain integrity errors
- Migration 005 now TRUNCATEs audit_log after adding prev_hash column
- Existing rows had broken hash chains (inserted before prev_hash existed)
BUG-8: Disable WatchdogSec in patch-manager-web.service
- pm-web does not implement sd_notify, causing systemd to kill the service
BUG-9: Disable WatchdogSec in patch-manager-worker.service
- Same issue as BUG-8, worker does not implement sd_notify
Previous fixes (BUG-1 through BUG-5) also included:
- setup.sh: PostgreSQL 15+ schema GRANTs
- Axum route syntax :param → {param} (19 routes)
- DbUser struct role: String → UserRole enum mapping
- UserRole/AuthProvider Display trait implementations
- Seed admin password hash (Argon2id)
2026-04-28 23:01:03 +00:00
5a4d4d583e
style: Apply rustfmt with stable-only config
...
CI Pipeline / Clippy Lints (push) Failing after 0s
CI Pipeline / Rust Unit Tests (push) Failing after 0s
CI Pipeline / Rust Format Check (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 0s
CI Pipeline / Security Audit (push) Failing after 3s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Fixed rustfmt.toml to only use stable options (removed nightly-only)
- Applied cargo fmt --all to fix formatting violations
- Stable options: edition=2021, max_width=100, reorder_imports/modules, match_block_trailing_comma
2026-04-24 15:32:50 +00:00
a5d52ffab0
feat: M6 maintenance windows + M7 WebSocket relay (real-time job status)
...
M6 - Maintenance Windows:
- routes/maintenance_windows.rs: full CRUD API
- migrations/004_maintenance_windows.sql
- frontend/MaintenanceWindowsPage.tsx
- HostDetailPage.tsx: maintenance window config panel
M7 - WebSocket Relay:
- pm-web: POST /api/v1/ws/ticket (JWT-auth, single-use, 60s TTL)
- pm-web: WS /api/v1/ws/jobs?ticket=... (PgListener -> browser push)
- pm-web: DashMap<String,WsTicket> in AppState, 30s cleanup task
- pm-worker: ws_relay.rs subscribes to agent WS, updates patch_job_hosts,
fires pg_notify(job_update) for real-time fan-out
- frontend: useJobWebSocket hook with auto-reconnect + exponential backoff
- frontend: JobsPage live updates with WS status indicator
- types: JobWsEvent interface
- api/client: wsApi.createTicket()
All tasks marked complete in tasks/todo.md
cargo build: zero errors, zero warnings
2026-04-23 17:42:51 +00:00
6f9c6dc881
M5: Patch Deployment & Job Management
...
Backend:
- migrations/003_jobs_scheduling.sql: retry_next_at/last_error columns,
pg_notify trigger for immediate job dispatch, retry index
- pm-agent-client: ApplyPatchesRequest/Response, AgentJobStatus,
RollbackResponse types; apply_patches/job_status/rollback_job
client methods + generic POST helper
- pm-core/models: JobStatus, JobKind, PatchJob, PatchJobHost,
CreateJobRequest, PatchJobSummary
- pm-web/routes/jobs.rs: POST/GET /api/v1/jobs, GET /jobs/:id,
POST /jobs/:id/cancel, POST /jobs/:id/rollback
- pm-worker/job_executor.rs: NOTIFY listener, periodic scanner,
execute_host_job, poll_running_jobs, handle_host_failure (3-retry
exponential backoff 1m/5m/30m), sync_job_status, retry_pending_jobs
- pm-worker/main.rs: spawn job_executor
Frontend:
- types/index.ts: PatchInfo, PatchJobHost, PatchJob, PatchJobSummary,
CreateJobRequest interfaces
- api/client.ts: jobsApi (list/get/create/cancel/rollback),
patchesApi (getHostPatches)
- pages/PatchDeploymentPage.tsx: 3-step MUI Stepper
(host select → configure → result)
- pages/JobsPage.tsx: job list table, expandable per-host detail,
cancel/rollback actions with confirm dialog, load-more pagination
- App.tsx: /jobs and /deployment routes wired to real pages
cargo check: 0 errors | vite build: 0 errors
2026-04-23 17:08:43 +00:00
a6eb762962
feat(M3): Host Management, Groups, Users, CIDR Discovery
...
- pm-core::models: Host, HostSummary, Group, User, DiscoveryResult
types + request payloads for all CRUD operations
- pm-core::audit: Tamper-evident hash-chained audit log writer
(SHA-256 chain, non-fatal, covers all M3 events)
- pm-web/routes/hosts: Full host CRUD with RBAC scoping;
FQDN DNS resolution on registration; host↔group membership;
operator group-scoped access enforcement; audit on register/remove
- pm-web/routes/groups: Full group CRUD; host↔group and user↔group
membership management; admin-only create/delete/update
- pm-web/routes/users: Full user CRUD (admin); current user profile;
password hashing (Argon2id); role management; session revocation
- pm-web/routes/discovery: CIDR scan with bounded concurrency
(128 workers), TCP probe with 2s timeout, reverse DNS lookup,
scan results table, register-from-discovery flow with audit log
- Frontend: HostsPage (filterable table with health chips),
HostDetailPage, GroupsPage (create/delete dialog),
UsersPage (create/revoke sessions)
- App.tsx updated with all M3 routes wired to real pages
- cargo check --workspace: zero errors
Closes M3.
2026-04-23 16:25:08 +00:00