Skip to main content

max / goingson

2.3 KB · 82 lines History Blame Raw
1 //! Daily review note commands.
2
3 use chrono::NaiveDate;
4 use serde::{Deserialize, Serialize};
5 use std::sync::Arc;
6 use tauri::State;
7 use tracing::instrument;
8
9 use goingson_core::DailyNote;
10
11 use crate::state::{AppState, DESKTOP_USER_ID};
12 use super::ApiError;
13
14 // ============ Response Type ============
15
16 #[derive(Debug, Serialize)]
17 #[serde(rename_all = "camelCase")]
18 pub struct DailyNoteResponse {
19 pub id: String,
20 pub note_date: String,
21 pub went_well: String,
22 pub could_improve: String,
23 pub is_reviewed: bool,
24 pub reviewed_at: Option<String>,
25 }
26
27 impl From<DailyNote> for DailyNoteResponse {
28 fn from(note: DailyNote) -> Self {
29 Self {
30 id: note.id.to_string(),
31 note_date: note.note_date.format("%Y-%m-%d").to_string(),
32 went_well: note.went_well,
33 could_improve: note.could_improve,
34 is_reviewed: note.is_reviewed,
35 reviewed_at: note.reviewed_at.map(|dt| dt.to_rfc3339()),
36 }
37 }
38 }
39
40 // ============ Input Types ============
41
42 #[derive(Debug, Deserialize)]
43 #[serde(rename_all = "camelCase")]
44 pub struct UpsertDailyNoteInput {
45 pub note_date: String,
46 pub went_well: String,
47 pub could_improve: String,
48 pub is_reviewed: bool,
49 }
50
51 // ============ Commands ============
52
53 #[tauri::command]
54 #[instrument(skip_all)]
55 pub async fn get_daily_note(
56 state: State<'_, Arc<AppState>>,
57 date: String,
58 ) -> Result<Option<DailyNoteResponse>, ApiError> {
59 let date = NaiveDate::parse_from_str(&date, "%Y-%m-%d")
60 .map_err(|_| ApiError::validation("date", "Invalid date format, expected YYYY-MM-DD"))?;
61 let note = state.daily_notes.get_by_date(DESKTOP_USER_ID, date).await?;
62 Ok(note.map(DailyNoteResponse::from))
63 }
64
65 #[tauri::command]
66 #[instrument(skip_all)]
67 pub async fn upsert_daily_note(
68 state: State<'_, Arc<AppState>>,
69 input: UpsertDailyNoteInput,
70 ) -> Result<DailyNoteResponse, ApiError> {
71 let date = NaiveDate::parse_from_str(&input.note_date, "%Y-%m-%d")
72 .map_err(|_| ApiError::validation("date", "Invalid date format, expected YYYY-MM-DD"))?;
73 let note = state.daily_notes.upsert(
74 DESKTOP_USER_ID,
75 date,
76 &input.went_well,
77 &input.could_improve,
78 input.is_reviewed,
79 ).await?;
80 Ok(DailyNoteResponse::from(note))
81 }
82