Skip to main content

routa_core/rpc/methods/
notes.rs

1//! RPC methods for note management.
2//!
3//! Methods:
4//! - `notes.list`   — list notes with optional filters
5//! - `notes.get`    — get a single note
6//! - `notes.create` — create or update a note
7//! - `notes.delete` — delete a note
8
9use serde::{Deserialize, Serialize};
10
11use crate::models::note::{Note, NoteMetadata, NoteType};
12use crate::rpc::error::RpcError;
13use crate::state::AppState;
14
15// ---------------------------------------------------------------------------
16// notes.list
17// ---------------------------------------------------------------------------
18
19#[derive(Debug, Deserialize)]
20#[serde(rename_all = "camelCase")]
21pub struct ListParams {
22    #[serde(default = "default_workspace_id")]
23    pub workspace_id: String,
24    #[serde(rename = "type")]
25    pub note_type: Option<String>,
26}
27
28fn default_workspace_id() -> String {
29    "default".into()
30}
31
32#[derive(Debug, Serialize)]
33pub struct ListResult {
34    pub notes: Vec<Note>,
35}
36
37pub async fn list(state: &AppState, params: ListParams) -> Result<ListResult, RpcError> {
38    let notes = if let Some(type_str) = &params.note_type {
39        let note_type = NoteType::from_str(type_str);
40        state
41            .note_store
42            .list_by_type(&params.workspace_id, &note_type)
43            .await?
44    } else {
45        state
46            .note_store
47            .list_by_workspace(&params.workspace_id)
48            .await?
49    };
50
51    Ok(ListResult { notes })
52}
53
54// ---------------------------------------------------------------------------
55// notes.get
56// ---------------------------------------------------------------------------
57
58#[derive(Debug, Deserialize)]
59#[serde(rename_all = "camelCase")]
60pub struct GetParams {
61    pub note_id: String,
62    #[serde(default = "default_workspace_id")]
63    pub workspace_id: String,
64}
65
66pub async fn get(state: &AppState, params: GetParams) -> Result<Note, RpcError> {
67    state
68        .note_store
69        .get(&params.note_id, &params.workspace_id)
70        .await?
71        .ok_or_else(|| RpcError::NotFound(format!("Note {} not found", params.note_id)))
72}
73
74// ---------------------------------------------------------------------------
75// notes.create
76// ---------------------------------------------------------------------------
77
78#[derive(Debug, Deserialize)]
79#[serde(rename_all = "camelCase")]
80pub struct CreateParams {
81    pub note_id: Option<String>,
82    pub title: String,
83    pub content: Option<String>,
84    #[serde(default = "default_workspace_id")]
85    pub workspace_id: String,
86    #[serde(rename = "type")]
87    pub note_type: Option<String>,
88    pub metadata: Option<NoteMetadata>,
89}
90
91#[derive(Debug, Serialize)]
92pub struct CreateResult {
93    pub note: Note,
94}
95
96pub async fn create(state: &AppState, params: CreateParams) -> Result<CreateResult, RpcError> {
97    let note_id = params
98        .note_id
99        .unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
100
101    let metadata = params.metadata.unwrap_or(NoteMetadata {
102        note_type: params
103            .note_type
104            .as_deref()
105            .map(NoteType::from_str)
106            .unwrap_or(NoteType::General),
107        ..Default::default()
108    });
109
110    let note = Note::new(
111        note_id,
112        params.title,
113        params.content.unwrap_or_default(),
114        params.workspace_id,
115        Some(metadata),
116    );
117
118    state.note_store.save(&note).await?;
119    Ok(CreateResult { note })
120}
121
122// ---------------------------------------------------------------------------
123// notes.delete
124// ---------------------------------------------------------------------------
125
126#[derive(Debug, Deserialize)]
127#[serde(rename_all = "camelCase")]
128pub struct DeleteParams {
129    pub note_id: String,
130    #[serde(default = "default_workspace_id")]
131    pub workspace_id: String,
132}
133
134#[derive(Debug, Serialize)]
135#[serde(rename_all = "camelCase")]
136pub struct DeleteResult {
137    pub deleted: bool,
138    pub note_id: String,
139}
140
141pub async fn delete(state: &AppState, params: DeleteParams) -> Result<DeleteResult, RpcError> {
142    state
143        .note_store
144        .delete(&params.note_id, &params.workspace_id)
145        .await?;
146    Ok(DeleteResult {
147        deleted: true,
148        note_id: params.note_id,
149    })
150}