From c8b169da8cb7eae0957e0ab5e7370b071093a224 Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 28 Apr 2026 00:18:40 +0100 Subject: feat: Document UI for directive orchestration with Lexical editor (#93) * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Save previous goal on update and include history in re-planning prompt * feat: soryu-co/soryu - makima: Install Lexical and create base document editor component * feat: soryu-co/soryu - makima: Create directive file system sidebar and document layout * feat: soryu-co/soryu - makima: Create custom Lexical step diagram block * feat: soryu-co/soryu - makima: Add context menu and goal auto-update integration * WIP: heartbeat checkpoint --- makima/src/db/models.rs | 27 +++++++++++++++ makima/src/db/repository.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) (limited to 'makima/src/db') diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 97657dc..c03b4ac 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -3050,4 +3050,31 @@ pub struct DirectiveOrderGroupListResponse { pub total: i64, } +/// User setting record from the database (key-value per owner). +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct UserSetting { + pub id: Uuid, + pub owner_id: Uuid, + pub key: String, + pub value: serde_json::Value, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +/// Request body for upserting a user setting. +#[derive(Debug, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct UpsertUserSettingRequest { + pub key: String, + pub value: serde_json::Value, +} + +/// Response containing a list of user settings. +#[derive(Debug, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct UserSettingsResponse { + pub settings: Vec, +} + diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index 57e8a78..401da94 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -21,6 +21,7 @@ use super::models::{ PhaseDefinition, SupervisorHeartbeatRecord, SupervisorState, Task, TaskCheckpoint, TaskEvent, TaskSummary, UpdateContractRequest, UpdateFileRequest, UpdateTaskRequest, UpdateTemplateRequest, + UserSetting, }; /// Repository error types. @@ -6698,3 +6699,84 @@ pub async fn get_available_orders_for_dog_pickup( .await } +// ─── User Settings ─────────────────────────────────────────────────────────── + +/// Get all settings for a given owner. +pub async fn get_user_settings( + pool: &PgPool, + owner_id: Uuid, +) -> Result, sqlx::Error> { + sqlx::query_as::<_, UserSetting>( + r#" + SELECT id, owner_id, key, value, created_at, updated_at + FROM user_settings + WHERE owner_id = $1 + ORDER BY key ASC + "#, + ) + .bind(owner_id) + .fetch_all(pool) + .await +} + +/// Get a single setting by owner and key. +pub async fn get_user_setting( + pool: &PgPool, + owner_id: Uuid, + key: &str, +) -> Result, sqlx::Error> { + sqlx::query_as::<_, UserSetting>( + r#" + SELECT id, owner_id, key, value, created_at, updated_at + FROM user_settings + WHERE owner_id = $1 AND key = $2 + "#, + ) + .bind(owner_id) + .bind(key) + .fetch_optional(pool) + .await +} + +/// Upsert a user setting (insert or update on conflict). +pub async fn upsert_user_setting( + pool: &PgPool, + owner_id: Uuid, + key: &str, + value: &serde_json::Value, +) -> Result { + sqlx::query_as::<_, UserSetting>( + r#" + INSERT INTO user_settings (owner_id, key, value) + VALUES ($1, $2, $3) + ON CONFLICT (owner_id, key) DO UPDATE + SET value = EXCLUDED.value, updated_at = now() + RETURNING id, owner_id, key, value, created_at, updated_at + "#, + ) + .bind(owner_id) + .bind(key) + .bind(value) + .fetch_one(pool) + .await +} + +/// Delete a user setting. Returns true if a row was deleted. +pub async fn delete_user_setting( + pool: &PgPool, + owner_id: Uuid, + key: &str, +) -> Result { + let result = sqlx::query( + r#" + DELETE FROM user_settings + WHERE owner_id = $1 AND key = $2 + "#, + ) + .bind(owner_id) + .bind(key) + .execute(pool) + .await?; + Ok(result.rows_affected() > 0) +} + -- cgit v1.2.3