Add PostgreSQL database persistence

- Add connect_machines, connect_sessions, connect_session_events, connect_support_codes tables
- Implement db module with connection pooling (sqlx)
- Add machine persistence across server restarts
- Add audit logging for session/viewer events
- Support codes now persisted to database

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 19:51:01 -07:00
parent 448d3b75ac
commit f6bf0cfd26
10 changed files with 788 additions and 36 deletions

View File

@@ -1,45 +1,52 @@
//! Database module
//! Database module for GuruConnect
//!
//! Handles session logging and persistence.
//! Optional for MVP - sessions are kept in memory only.
//! Handles persistence for machines, sessions, and audit logging.
//! Optional - server works without database if DATABASE_URL not set.
pub mod machines;
pub mod sessions;
pub mod events;
pub mod support_codes;
use anyhow::Result;
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
use tracing::info;
/// Database connection pool (placeholder)
pub use machines::*;
pub use sessions::*;
pub use events::*;
pub use support_codes::*;
/// Database connection pool wrapper
#[derive(Clone)]
pub struct Database {
// TODO: Add sqlx pool when PostgreSQL is needed
_placeholder: (),
pool: PgPool,
}
impl Database {
/// Initialize database connection
pub async fn init(_database_url: &str) -> Result<Self> {
// TODO: Initialize PostgreSQL connection pool
Ok(Self { _placeholder: () })
/// Initialize database connection pool
pub async fn connect(database_url: &str, max_connections: u32) -> Result<Self> {
info!("Connecting to database...");
let pool = PgPoolOptions::new()
.max_connections(max_connections)
.connect(database_url)
.await?;
info!("Database connection established");
Ok(Self { pool })
}
}
/// Session event for audit logging
#[derive(Debug)]
pub struct SessionEvent {
pub session_id: String,
pub event_type: SessionEventType,
pub details: Option<String>,
}
#[derive(Debug)]
pub enum SessionEventType {
Started,
ViewerJoined,
ViewerLeft,
Ended,
}
impl Database {
/// Log a session event (placeholder)
pub async fn log_session_event(&self, _event: SessionEvent) -> Result<()> {
// TODO: Insert into connect_session_events table
/// Run database migrations
pub async fn migrate(&self) -> Result<()> {
info!("Running database migrations...");
sqlx::migrate!("./migrations").run(&self.pool).await?;
info!("Migrations complete");
Ok(())
}
/// Get reference to the connection pool
pub fn pool(&self) -> &PgPool {
&self.pool
}
}