From 8fe88b335a4f887dd8a2ae7faccd1b2c3cec4684 Mon Sep 17 00:00:00 2001 From: Daniel Mader Date: Thu, 11 Dec 2025 21:33:29 +0100 Subject: [PATCH] feat: set PIN code requirement in template --- agent_api_rest/src/library/mod.rs | 10 ++++-- agent_api_rest/src/library/templates/mod.rs | 27 +++++++++++++++ agent_library/src/template/aggregate.rs | 38 +++++++++++++++++++++ agent_library/src/template/command.rs | 5 +++ agent_library/src/template/event.rs | 6 ++++ agent_library/src/template/views/mod.rs | 10 ++++++ 6 files changed, 93 insertions(+), 3 deletions(-) diff --git a/agent_api_rest/src/library/mod.rs b/agent_api_rest/src/library/mod.rs index bf6ab91b..f6047629 100644 --- a/agent_api_rest/src/library/mod.rs +++ b/agent_api_rest/src/library/mod.rs @@ -2,10 +2,13 @@ pub mod error; pub mod templates; use agent_library::state::LibraryState; -use axum::{routing::get, Router}; +use axum::{ + routing::{get, post}, + Router, +}; use crate::{ - library::templates::{get_template, get_templates, patch_template, post_templates}, + library::templates::{get_template, get_templates, patch_template, post_templates, require_pin_code}, API_VERSION, }; @@ -15,7 +18,8 @@ pub fn router(library_state: LibraryState) -> Router { API_VERSION, Router::new() .route("/templates", get(get_templates).post(post_templates)) - .route("/templates/{template_id}", get(get_template).patch(patch_template)), + .route("/templates/{template_id}", get(get_template).patch(patch_template)) + .route("/templates/require-pin-code", post(require_pin_code)), ) .with_state(library_state) } diff --git a/agent_api_rest/src/library/templates/mod.rs b/agent_api_rest/src/library/templates/mod.rs index bf7f809c..508d1aba 100644 --- a/agent_api_rest/src/library/templates/mod.rs +++ b/agent_api_rest/src/library/templates/mod.rs @@ -23,6 +23,7 @@ pub struct PostTemplatesEndpointRequest { pub holder_type: Option, pub tags: Vec, pub status: Status, + pub require_pin_code: Option, pub visibility: Visibility, pub description: Option, pub r#type: Vec, @@ -40,6 +41,7 @@ pub(crate) async fn post_templates( holder_type, tags, status, + require_pin_code, visibility, description, r#type, @@ -57,6 +59,7 @@ pub(crate) async fn post_templates( holder_type, tags, status, + require_pin_code, visibility, description, r#type, @@ -205,6 +208,30 @@ pub(crate) async fn patch_template( Ok(StatusCode::NO_CONTENT.into_response()) } +#[derive(Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct RequirePinCodeRequest { + pub template_id: String, + pub require_pin_code: bool, +} + +#[axum_macros::debug_handler] +pub(crate) async fn require_pin_code( + State(state): State, + Json(RequirePinCodeRequest { + template_id, + require_pin_code, + }): Json, +) -> Result { + let command = TemplateCommand::RequirePinCode { + template_id: template_id.clone(), + require_pin_code, + }; + command_handler(&template_id, &state.command.template, command).await?; + + Ok(StatusCode::NO_CONTENT.into_response()) +} + #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct GetTemplatesEndpointRequest { diff --git a/agent_library/src/template/aggregate.rs b/agent_library/src/template/aggregate.rs index c9c49b55..214e0e47 100644 --- a/agent_library/src/template/aggregate.rs +++ b/agent_library/src/template/aggregate.rs @@ -1,3 +1,5 @@ +use std::pin::Pin; + use async_trait::async_trait; use cqrs_es::Aggregate; use serde::{Deserialize, Serialize}; @@ -70,6 +72,7 @@ pub struct Template { pub modified_at: Option, pub tags: Vec, pub status: Status, + pub require_pin_code: Option, pub visibility: Visibility, pub description: Option, pub r#type: Vec, @@ -107,6 +110,7 @@ impl Aggregate for Template { holder_type, tags, status, + require_pin_code, visibility, description, r#type, @@ -127,6 +131,7 @@ impl Aggregate for Template { modified_at, tags, status, + require_pin_code, visibility, description, r#type, @@ -277,6 +282,21 @@ impl Aggregate for Template { modified_at, }]) } + RequirePinCode { + template_id, + require_pin_code, + } => { + #[cfg(not(test))] + let modified_at = chrono::Utc::now().to_rfc3339(); + #[cfg(test)] + let modified_at = test_utils::modified_at(); + + Ok(vec![PinCodeRequired { + template_id, + require_pin_code, + modified_at, + }]) + } } } @@ -296,6 +316,7 @@ impl Aggregate for Template { modified_at, tags, status, + require_pin_code, visibility, description, r#type, @@ -310,6 +331,7 @@ impl Aggregate for Template { self.modified_at.replace(modified_at); self.tags = tags; self.status = status; + self.require_pin_code = require_pin_code; self.visibility = visibility; self.description = description; self.r#type = r#type; @@ -403,6 +425,14 @@ impl Aggregate for Template { self.schema = Some(schema); self.modified_at.replace(modified_at); } + PinCodeRequired { + template_id: _, + require_pin_code, + modified_at, + } => { + self.require_pin_code = Some(require_pin_code); + self.modified_at.replace(modified_at); + } } } } @@ -429,6 +459,7 @@ pub mod document_tests { modified_at: String, tags: Vec, status: Status, + require_pin_code: Option, visibility: Visibility, description: Option, r#type: Vec, @@ -445,6 +476,7 @@ pub mod document_tests { holder_type: holder_type.clone(), tags: tags.clone(), status: status.clone(), + require_pin_code: require_pin_code.clone(), visibility: visibility.clone(), description: description.clone(), r#type: r#type.clone(), @@ -460,6 +492,7 @@ pub mod document_tests { modified_at, tags, status, + require_pin_code, visibility, description, r#type, @@ -521,6 +554,11 @@ pub mod test_utils { Status::Draft } + #[fixture] + pub fn require_pin_code() -> Option { + Some(true) + } + #[fixture] pub fn visibility() -> Visibility { Visibility::Private diff --git a/agent_library/src/template/command.rs b/agent_library/src/template/command.rs index f0a75e3a..2e759a3e 100644 --- a/agent_library/src/template/command.rs +++ b/agent_library/src/template/command.rs @@ -13,6 +13,7 @@ pub enum TemplateCommand { holder_type: Option, tags: Vec, status: Status, + require_pin_code: Option, visibility: Visibility, description: Option, r#type: Vec, @@ -62,4 +63,8 @@ pub enum TemplateCommand { template_id: String, schema: serde_json::Value, }, + RequirePinCode { + template_id: String, + require_pin_code: bool, + }, } diff --git a/agent_library/src/template/event.rs b/agent_library/src/template/event.rs index dce4706e..c9e33380 100644 --- a/agent_library/src/template/event.rs +++ b/agent_library/src/template/event.rs @@ -16,6 +16,7 @@ pub enum TemplateEvent { modified_at: String, tags: Vec, status: Status, + require_pin_code: Option, visibility: Visibility, description: Option, r#type: Vec, @@ -76,6 +77,11 @@ pub enum TemplateEvent { schema: serde_json::Value, modified_at: String, }, + PinCodeRequired { + template_id: String, + require_pin_code: bool, + modified_at: String, + }, } impl DomainEvent for TemplateEvent { diff --git a/agent_library/src/template/views/mod.rs b/agent_library/src/template/views/mod.rs index b4e6228d..8186abc2 100644 --- a/agent_library/src/template/views/mod.rs +++ b/agent_library/src/template/views/mod.rs @@ -21,6 +21,7 @@ impl View