diff options
Diffstat (limited to 'makima/src/db')
| -rw-r--r-- | makima/src/db/models.rs | 27 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 82 |
2 files changed, 109 insertions, 0 deletions
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<Utc>, + pub updated_at: DateTime<Utc>, +} + +/// 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<UserSetting>, +} + 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<Vec<UserSetting>, 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<Option<UserSetting>, 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<UserSetting, sqlx::Error> { + 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<bool, sqlx::Error> { + 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) +} + |
