decision_cockpit 0.1.0

Layer — product decision memory with MCP tools and an embedded review dashboard
Documentation
use chrono::{DateTime, Utc};
use sqlx::PgPool;
use uuid::Uuid;

use crate::domain::actions::Action;

pub struct NewAction<'a> {
    pub title: &'a str,
    pub description: Option<&'a str>,
    pub status: &'a str,
    pub owner: Option<&'a str>,
    pub due_at: Option<DateTime<Utc>>,
}

pub async fn create(pool: &PgPool, new: NewAction<'_>) -> Result<Action, sqlx::Error> {
    let id = Uuid::new_v4();
    sqlx::query_as::<_, Action>(
        r#"
        INSERT INTO actions (id, title, description, status, owner, due_at)
        VALUES ($1, $2, $3, $4, $5, $6)
        RETURNING id, title, description, status, owner, due_at, created_at, updated_at
        "#,
    )
    .bind(id)
    .bind(new.title)
    .bind(new.description)
    .bind(new.status)
    .bind(new.owner)
    .bind(new.due_at)
    .fetch_one(pool)
    .await
}

pub async fn get(pool: &PgPool, id: Uuid) -> Result<Option<Action>, sqlx::Error> {
    sqlx::query_as::<_, Action>(
        r#"
        SELECT id, title, description, status, owner, due_at, created_at, updated_at
        FROM actions
        WHERE id = $1
        "#,
    )
    .bind(id)
    .fetch_optional(pool)
    .await
}

pub async fn list(pool: &PgPool, limit: i64) -> Result<Vec<Action>, sqlx::Error> {
    sqlx::query_as::<_, Action>(
        r#"
        SELECT id, title, description, status, owner, due_at, created_at, updated_at
        FROM actions
        ORDER BY created_at DESC
        LIMIT $1
        "#,
    )
    .bind(limit)
    .fetch_all(pool)
    .await
}