Skip to main content

reinhardt_admin/server/
detail.rs

1//! Detail view Server Function
2//!
3//! Provides detail view operations for admin models.
4
5#[cfg(server)]
6use super::admin_auth::AdminAuthenticatedUser;
7use crate::adapters::{AdminDatabase, AdminRecord, AdminSite, DetailResponse};
8#[cfg(server)]
9use crate::core::{AdminDatabaseKey, AdminSiteKey};
10#[cfg(server)]
11use reinhardt_di::Depends;
12#[cfg(server)]
13use reinhardt_pages::server_fn::ServerFnRequest;
14use reinhardt_pages::server_fn::{ServerFnError, server_fn};
15
16#[cfg(server)]
17use super::error::{AdminAuth, MapServerFnError, ModelPermission};
18
19/// Get detail view data for a single model instance
20///
21/// Retrieves a single record by model name and ID, returning all fields
22/// as a HashMap of field names to JSON values.
23///
24/// # Server Function
25///
26/// This function is automatically exposed as an HTTP endpoint by the `#[server_fn]` macro.
27/// AdminSite and AdminDatabase dependencies are automatically injected via the DI system.
28///
29/// # Authentication
30///
31/// Requires staff (admin) permission and view permission for the model.
32///
33/// # Example
34///
35/// ```ignore
36/// use reinhardt_admin::server::get_detail;
37///
38/// // Client-side usage (automatically generates HTTP request)
39/// let response = get_detail("User".to_string(), "42".to_string()).await?;
40/// println!("User data: {:?}", response.data);
41/// ```
42#[server_fn]
43pub async fn get_detail(
44	model_name: String,
45	id: String,
46	#[inject] site: Depends<AdminSiteKey, AdminSite>,
47	#[inject] db: Depends<AdminDatabaseKey, AdminDatabase>,
48	#[inject] http_request: ServerFnRequest,
49	#[inject] AdminAuthenticatedUser(user): AdminAuthenticatedUser,
50) -> Result<DetailResponse, ServerFnError> {
51	// Authentication and authorization check
52	let auth = AdminAuth::from_request(&http_request);
53	let model_admin = site.get_model_admin(&model_name).map_server_fn_error()?;
54	auth.require_model_permission(model_admin.as_ref(), user.as_ref(), ModelPermission::View)
55		.await?;
56	let table_name = model_admin.table_name();
57	let pk_field = model_admin.pk_field();
58
59	let data = db
60		.get::<AdminRecord>(table_name, pk_field, &id)
61		.await
62		.map_server_fn_error()?
63		.ok_or_else(|| {
64			ServerFnError::server(404, format!("{} with id '{}' not found", model_name, id))
65		})?;
66
67	Ok(DetailResponse { model_name, data })
68}