add initial crates and apps
This commit is contained in:
parent
5c87ba3519
commit
1ca300098f
113 changed files with 28169 additions and 0 deletions
84
crates/chattyness-db/src/pool.rs
Normal file
84
crates/chattyness-db/src/pool.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
//! Database connection pool and RLS context management.
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use sqlx::{postgres::PgPoolOptions, PgPool};
|
||||
use uuid::Uuid;
|
||||
|
||||
use chattyness_error::AppError;
|
||||
|
||||
/// Create a new database connection pool for the owner interface.
|
||||
///
|
||||
/// Uses the `chattyness_owner` role which has full database access.
|
||||
pub async fn create_owner_pool(database_url: &str) -> Result<PgPool, AppError> {
|
||||
let pool = PgPoolOptions::new()
|
||||
.max_connections(5)
|
||||
.acquire_timeout(Duration::from_secs(5))
|
||||
.connect(database_url)
|
||||
.await?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
/// Create a new database connection pool for the public app.
|
||||
///
|
||||
/// Uses the `chattyness_app` role which has Row-Level Security (RLS) policies.
|
||||
pub async fn create_app_pool(database_url: &str) -> Result<PgPool, AppError> {
|
||||
let pool = PgPoolOptions::new()
|
||||
.max_connections(10)
|
||||
.acquire_timeout(Duration::from_secs(5))
|
||||
.connect(database_url)
|
||||
.await?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
/// Set the current user context for Row-Level Security.
|
||||
///
|
||||
/// This should be called at the start of each request to enable RLS policies
|
||||
/// that depend on the current user ID.
|
||||
pub async fn set_user_context(pool: &PgPool, user_id: Option<Uuid>) -> Result<(), AppError> {
|
||||
if let Some(id) = user_id {
|
||||
sqlx::query("SELECT public.set_current_user_id($1)")
|
||||
.bind(id)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
} else {
|
||||
// Clear the user context for anonymous requests
|
||||
sqlx::query("SELECT public.clear_current_user_id()")
|
||||
.execute(pool)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clear the current user context.
|
||||
///
|
||||
/// Called at the end of a request to ensure the connection is clean
|
||||
/// before returning to the pool.
|
||||
pub async fn clear_user_context(pool: &PgPool) -> Result<(), AppError> {
|
||||
sqlx::query("SELECT public.clear_current_user_id()")
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the current guest session context for Row-Level Security.
|
||||
///
|
||||
/// This should be called for guest users to enable RLS policies
|
||||
/// that depend on the current guest session ID.
|
||||
pub async fn set_guest_context(pool: &PgPool, guest_session_id: Uuid) -> Result<(), AppError> {
|
||||
sqlx::query("SELECT public.set_current_guest_session_id($1)")
|
||||
.bind(guest_session_id)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clear the current guest session context.
|
||||
pub async fn clear_guest_context(pool: &PgPool) -> Result<(), AppError> {
|
||||
sqlx::query("SELECT public.set_current_guest_session_id(NULL)")
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue