Skip to main content

az_config_center_contract/
lib.rs

1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3
4use az_derive_aliases::{apply, serde_code_default_ord_display_enum, serde_eq_default};
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9/// Shell 组件默认渲染输出路径。
10pub const DEFAULT_SHELL_OUTPUT_PATH: &str = "~/.add_fn";
11/// 桌面本地后端请求头中的会话令牌字段名。
12pub const DESKTOP_SESSION_TOKEN_HEADER: &str = "x-aio-desktop-token";
13
14/// 配置中心 API 的统一响应信封。
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
16pub struct ApiResponse<T> {
17    pub success: bool,
18    pub message: String,
19    pub data: Option<T>,
20}
21
22/// 配置中心 API 的错误响应体。
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
24pub struct ErrorBody {
25    pub success: bool,
26    pub message: String,
27}
28
29/// 配置中心健康状态响应数据。
30#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
31pub struct StatusPayload {
32    pub ok: bool,
33    pub database: String,
34}
35
36/// 配置中心登录请求。
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
38pub struct LoginRequest {
39    pub username: String,
40    pub password: String,
41}
42
43/// 配置中心登录成功后返回的会话信息。
44#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
45pub struct LoginPayload {
46    pub token: String,
47    pub username: String,
48}
49
50/// 配置中心中的单条配置快照。
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
52pub struct ConfigItem {
53    pub id: Uuid,
54    pub namespace: String,
55    pub config_key: String,
56    pub config_value: String,
57    pub value_type: String,
58    pub description: String,
59    pub enabled: bool,
60    pub version: i32,
61    pub updated_by: String,
62    pub created_at: DateTime<Utc>,
63    pub updated_at: DateTime<Utc>,
64}
65
66/// 配置列表查询参数。
67#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
68pub struct ListQuery {
69    pub namespace: Option<String>,
70    pub keyword: Option<String>,
71    pub include_disabled: Option<bool>,
72}
73
74/// 按命名空间和配置键读取配置的查询参数。
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
76pub struct GetQuery {
77    pub namespace: String,
78    pub key: String,
79}
80
81/// 创建或更新配置的请求。
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
83pub struct UpsertRequest {
84    pub namespace: String,
85    pub key: String,
86    pub value: String,
87    #[serde(default = "default_config_value_type")]
88    pub value_type: String,
89    #[serde(default)]
90    pub description: String,
91    #[serde(default = "default_enabled")]
92    pub enabled: bool,
93    #[serde(default = "default_updated_by")]
94    pub updated_by: String,
95}
96
97/// 修改配置启停状态的请求。
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99pub struct ToggleRequest {
100    pub namespace: String,
101    pub key: String,
102    pub enabled: bool,
103    #[serde(default = "default_updated_by")]
104    pub updated_by: String,
105}
106
107/// 删除配置的请求。
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
109pub struct DeleteRequest {
110    pub namespace: String,
111    pub key: String,
112}
113
114/// 删除配置后的影响行数。
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
116pub struct DeleteResult {
117    pub deleted: u64,
118}
119
120fn default_config_value_type() -> String {
121    "text".to_owned()
122}
123
124fn default_enabled() -> bool {
125    true
126}
127
128fn default_updated_by() -> String {
129    String::new()
130}
131
132/// Shell 组件类型。
133///
134/// wire value 由 `strum(serialize = "...")` 固定为 `export`、`alias`、`function`、
135/// `snippet`;`Display` 则返回渲染文件中的分组名。两者用途不同,不要互相替换。
136#[apply(serde_code_default_ord_display_enum)]
137pub enum ShellComponentKind {
138    #[strum(serialize = "export")]
139    #[display("exports")]
140    Export,
141    #[strum(serialize = "alias")]
142    #[display("aliases")]
143    Alias,
144    #[strum(serialize = "function")]
145    #[display("functions")]
146    Function,
147    #[default]
148    #[strum(serialize = "snippet")]
149    #[display("snippets")]
150    Snippet,
151}
152
153/// Shell 组件注册表中的完整组件快照。
154///
155/// 该类型既用于 API 返回,也用于前端编辑态展示;具体 shell 输出由构建流程重新生成。
156#[apply(serde_eq_default)]
157pub struct ShellComponent {
158    pub name: String,
159    pub kind: ShellComponentKind,
160    pub summary: String,
161    pub enabled: bool,
162    pub render_to_output: bool,
163    pub export_value: Option<String>,
164    pub alias_command: Option<String>,
165    pub body: Option<String>,
166    pub preview: String,
167}
168
169/// 创建或整体更新 Shell 组件的请求。
170#[apply(serde_eq_default)]
171pub struct ShellComponentUpsert {
172    pub name: String,
173    pub kind: ShellComponentKind,
174    pub summary: String,
175    pub enabled: bool,
176    pub render_to_output: bool,
177    pub export_value: Option<String>,
178    pub alias_command: Option<String>,
179    pub body: Option<String>,
180}
181
182/// 局部修改 Shell 组件启用状态和摘要的请求。
183#[apply(serde_eq_default)]
184pub struct ShellComponentPatch {
185    pub name: String,
186    pub summary: Option<String>,
187    pub enabled: Option<bool>,
188    pub render_to_output: Option<bool>,
189}
190
191/// 删除 Shell 组件的请求。
192#[apply(serde_eq_default)]
193pub struct ShellComponentRemove {
194    pub name: String,
195}
196
197/// Shell 注册表构建配置。
198#[apply(serde_eq_default)]
199pub struct ShellComponentBuildConfig {
200    pub output_path: String,
201    pub resolved_output_path: String,
202}
203
204/// Shell 组件注册表快照。
205#[apply(serde_eq_default)]
206pub struct ShellComponentRegistry {
207    pub config_path: String,
208    pub build: ShellComponentBuildConfig,
209    pub components: Vec<ShellComponent>,
210}
211
212/// 修改 Shell 组件构建配置的请求。
213#[apply(serde_eq_default)]
214pub struct ShellComponentConfigUpdate {
215    pub output_path: Option<String>,
216}
217
218/// 触发 Shell 组件构建的请求。
219///
220/// `write = false` 表示只预览生成内容,不写入输出文件。
221#[apply(serde_eq_default)]
222pub struct ShellComponentBuildRequest {
223    pub output_path: Option<String>,
224    pub write: bool,
225}
226
227/// Shell 组件构建结果。
228#[apply(serde_eq_default)]
229pub struct ShellComponentBuildResult {
230    pub config_path: String,
231    pub output_path: String,
232    pub written: bool,
233    pub total_components: usize,
234    pub included_components: usize,
235    pub skipped_components: usize,
236    pub included_names: Vec<String>,
237    pub content: String,
238}
239
240/// 桌面后端健康状态和 Shell 注册表路径信息。
241#[apply(serde_eq_default)]
242pub struct DesktopBackendStatus {
243    pub ok: bool,
244    pub bind: String,
245    pub desktop_mode: bool,
246    pub shell_registry_path: String,
247    pub output_path: String,
248    pub resolved_output_path: String,
249}
250
251#[cfg(test)]
252mod tests {
253    use super::ShellComponentKind;
254
255    #[test]
256    fn shell_component_kind_keeps_wire_codes() {
257        assert_eq!(ShellComponentKind::Alias.code(), "alias");
258        assert_eq!(
259            ShellComponentKind::from_code("function"),
260            Some(ShellComponentKind::Function)
261        );
262        assert_eq!(ShellComponentKind::Export.to_string(), "exports");
263        assert!(ShellComponentKind::Export < ShellComponentKind::Alias);
264        assert_eq!(
265            serde_json::to_string(&ShellComponentKind::Snippet)
266                .expect("shell component kind should serialize"),
267            "\"snippet\""
268        );
269    }
270}