//! Bot configuration endpoints — GET/PUT for .huskies/bot.toml credentials. use crate::http::context::{AppContext, OpenApiResult, bad_request}; use poem_openapi::{Object, OpenApi, Tags, payload::Json}; use serde::{Deserialize, Serialize}; use std::sync::Arc; #[derive(Tags)] enum BotConfigTags { BotConfig, } #[derive(Object, Serialize, Deserialize, Default)] struct BotConfigPayload { pub transport: Option, pub enabled: Option, pub homeserver: Option, pub username: Option, pub password: Option, pub room_ids: Option>, pub slack_bot_token: Option, pub slack_signing_secret: Option, pub slack_channel_ids: Option>, } /// OpenAPI endpoint group for reading and writing bot configuration. pub struct BotConfigApi { pub ctx: Arc, } #[OpenApi(tag = "BotConfigTags::BotConfig")] impl BotConfigApi { /// Read current bot credentials from .huskies/bot.toml. #[oai(path = "/bot/config", method = "get")] async fn get_config(&self) -> OpenApiResult> { let root = self.ctx.state.get_project_root().map_err(bad_request)?; let path = root.join(".huskies").join("bot.toml"); let config: BotConfigPayload = std::fs::read_to_string(&path) .ok() .and_then(|s| toml::from_str(&s).ok()) .unwrap_or_default(); Ok(Json(config)) } /// Persist bot credentials to .huskies/bot.toml. #[oai(path = "/bot/config", method = "put")] async fn put_config( &self, payload: Json, ) -> OpenApiResult> { let root = self.ctx.state.get_project_root().map_err(bad_request)?; let path = root.join(".huskies").join("bot.toml"); let content = toml::to_string(&payload.0).map_err(|e| bad_request(e.to_string()))?; std::fs::write(&path, content).map_err(|e| bad_request(e.to_string()))?; Ok(payload) } }