reinhardt_admin/server/
update.rs1#[cfg(server)]
6use super::admin_auth::AdminAuthenticatedUser;
7use crate::adapters::{AdminDatabase, AdminRecord, AdminSite};
8#[cfg(server)]
9use crate::core::{AdminDatabaseKey, AdminSiteKey};
10use crate::types::MutationResponse;
11#[cfg(server)]
12use reinhardt_di::Depends;
13#[cfg(server)]
14use reinhardt_pages::server_fn::ServerFnRequest;
15use reinhardt_pages::server_fn::{ServerFnError, server_fn};
16
17#[cfg(server)]
18use super::audit;
19#[cfg(server)]
20use super::error::{AdminAuth, MapServerFnError, ModelPermission, require_object_filters};
21#[cfg(server)]
22use super::security::{require_csrf_token, sanitize_mutation_values};
23#[cfg(server)]
24use super::validation::validate_mutation_data;
25
26#[server_fn]
56pub async fn update_record(
57 model_name: String,
58 id: String,
59 request: crate::types::MutationRequest,
60 #[inject] site: Depends<AdminSiteKey, AdminSite>,
61 #[inject] db: Depends<AdminDatabaseKey, AdminDatabase>,
62 #[inject] http_request: ServerFnRequest,
63 #[inject] AdminAuthenticatedUser(user): AdminAuthenticatedUser,
64) -> Result<crate::types::MutationResponse, ServerFnError> {
65 require_csrf_token(&request.csrf_token, &http_request.inner().headers)?;
67
68 let auth = AdminAuth::from_request(&http_request);
70 let model_admin = site.get_model_admin(&model_name).map_server_fn_error()?;
71 auth.require_model_permission(model_admin.as_ref(), user.as_ref(), ModelPermission::Change)
72 .await?;
73
74 let table_name = model_admin.table_name();
75 let pk_field = model_admin.pk_field();
76 let object_filters = require_object_filters(model_admin.as_ref(), user.as_ref())?;
77
78 validate_mutation_data(&request.data, model_admin.as_ref(), true).map_server_fn_error()?;
80
81 let mut sanitized_data = request.data;
83 sanitize_mutation_values(&mut sanitized_data);
84
85 super::create::inject_auto_now_timestamps(&mut sanitized_data, table_name);
87
88 let user_id = auth.user_id().unwrap_or("unknown").to_string();
89
90 let result = db
91 .update_with_filters::<AdminRecord>(
92 table_name,
93 pk_field,
94 &id,
95 sanitized_data.clone(),
96 object_filters,
97 )
98 .await
99 .map_server_fn_error();
100
101 let affected = match result {
103 Err(e) => {
104 audit::log_update(&user_id, &model_name, &id, &sanitized_data, false);
105 return Err(e);
106 }
107 Ok(n) => n,
108 };
109
110 if affected == 0 {
113 audit::log_update(&user_id, &model_name, &id, &sanitized_data, false);
114 return Err(ServerFnError::server(
115 404,
116 format!("{} not found", model_name),
117 ));
118 }
119
120 audit::log_update(&user_id, &model_name, &id, &sanitized_data, true);
121
122 Ok(MutationResponse {
123 success: true,
124 message: format!("{} updated successfully", model_name),
125 affected: Some(affected),
126 data: None,
127 })
128}