summaryrefslogtreecommitdiff
path: root/makima/src/db/repository.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db/repository.rs')
-rw-r--r--makima/src/db/repository.rs214
1 files changed, 210 insertions, 4 deletions
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index e072eb8..d50ef61 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -11,12 +11,13 @@ use super::models::{
ContractTypeTemplateRecord, ConversationMessage, ConversationSnapshot,
CreateContractRequest, CreateDirectiveRequest, CreateFileRequest, CreateTaskRequest,
CreateTemplateRequest, Daemon, DaemonTaskAssignment, DaemonWithCapacity,
- DeliverableDefinition, Directive, DirectiveChain, DirectiveSummary,
+ DeliverableDefinition, Directive, DirectiveChain, DirectiveEvaluation, DirectiveEvent,
+ DirectiveSummary,
File, FileSummary, FileVersion, HistoryEvent, HistoryQueryFilters,
MeshChatConversation, MeshChatMessageRecord, PhaseChangeResult, PhaseConfig,
- PhaseDefinition, SupervisorHeartbeatRecord, SupervisorState, Task, TaskCheckpoint,
- TaskEvent, TaskSummary, UpdateContractRequest, UpdateDirectiveRequest,
- UpdateFileRequest, UpdateTaskRequest, UpdateTemplateRequest,
+ PhaseDefinition, StepContractSummary, SupervisorHeartbeatRecord, SupervisorState,
+ Task, TaskCheckpoint, TaskEvent, TaskSummary, UpdateContractRequest,
+ UpdateDirectiveRequest, UpdateFileRequest, UpdateTaskRequest, UpdateTemplateRequest,
};
/// Repository error types.
@@ -5184,6 +5185,29 @@ pub async fn list_steps_for_chain(
.await
}
+/// Batch-fetch lightweight contract summaries for a set of contract IDs.
+pub async fn get_contract_summaries_batch(
+ pool: &PgPool,
+ contract_ids: &[Uuid],
+) -> Result<Vec<StepContractSummary>, sqlx::Error> {
+ sqlx::query_as::<_, StepContractSummary>(
+ r#"
+ SELECT c.id, c.name, c.contract_type, c.phase, c.status,
+ COUNT(t.id) as task_count,
+ COUNT(t.id) FILTER (WHERE t.status IN ('done','merged')) as tasks_done,
+ COUNT(t.id) FILTER (WHERE t.status IN ('running','initializing','starting')) as tasks_running,
+ COUNT(t.id) FILTER (WHERE t.status = 'failed') as tasks_failed
+ FROM contracts c
+ LEFT JOIN tasks t ON t.contract_id = c.id
+ WHERE c.id = ANY($1)
+ GROUP BY c.id, c.name, c.contract_type, c.phase, c.status
+ "#,
+ )
+ .bind(contract_ids)
+ .fetch_all(pool)
+ .await
+}
+
// ── Directive orchestration functions ───────────────────────────────────────
/// Update directive status with automatic timestamp management.
@@ -5479,3 +5503,185 @@ pub async fn update_chain_status(
.fetch_optional(pool)
.await
}
+
+// ── Directive monitoring / evaluation functions ─────────────────────────────
+
+/// Create a directive evaluation record. evaluation_number is auto-incremented per step.
+pub async fn create_directive_evaluation(
+ pool: &PgPool,
+ directive_id: Uuid,
+ chain_id: Uuid,
+ step_id: Uuid,
+ contract_id: Uuid,
+ evaluation_type: &str,
+ evaluator: Option<&str>,
+ passed: bool,
+ overall_score: Option<f64>,
+ confidence_level: Option<&str>,
+ criteria_results: &serde_json::Value,
+ summary_feedback: &str,
+ rework_instructions: Option<&str>,
+) -> Result<DirectiveEvaluation, sqlx::Error> {
+ sqlx::query_as::<_, DirectiveEvaluation>(
+ r#"
+ INSERT INTO directive_evaluations (
+ directive_id, chain_id, step_id, contract_id,
+ evaluation_type, evaluation_number, evaluator,
+ passed, overall_score, confidence_level,
+ criteria_results, summary_feedback, rework_instructions,
+ completed_at
+ )
+ VALUES (
+ $1, $2, $3, $4,
+ $5, COALESCE((SELECT MAX(evaluation_number) FROM directive_evaluations WHERE step_id = $3), 0) + 1, $6,
+ $7, $8, $9,
+ $10, $11, $12,
+ NOW()
+ )
+ RETURNING *
+ "#,
+ )
+ .bind(directive_id)
+ .bind(chain_id)
+ .bind(step_id)
+ .bind(contract_id)
+ .bind(evaluation_type)
+ .bind(evaluator)
+ .bind(passed)
+ .bind(overall_score)
+ .bind(confidence_level)
+ .bind(criteria_results)
+ .bind(summary_feedback)
+ .bind(rework_instructions)
+ .fetch_one(pool)
+ .await
+}
+
+/// List evaluations for a step, ordered by evaluation_number.
+pub async fn list_evaluations_for_step(
+ pool: &PgPool,
+ step_id: Uuid,
+) -> Result<Vec<DirectiveEvaluation>, sqlx::Error> {
+ sqlx::query_as::<_, DirectiveEvaluation>(
+ r#"
+ SELECT * FROM directive_evaluations
+ WHERE step_id = $1
+ ORDER BY evaluation_number ASC
+ "#,
+ )
+ .bind(step_id)
+ .fetch_all(pool)
+ .await
+}
+
+/// Create a directive event.
+pub async fn create_directive_event(
+ pool: &PgPool,
+ directive_id: Uuid,
+ chain_id: Option<Uuid>,
+ step_id: Option<Uuid>,
+ event_type: &str,
+ severity: &str,
+ event_data: Option<&serde_json::Value>,
+ actor_type: &str,
+ actor_id: Option<Uuid>,
+) -> Result<DirectiveEvent, sqlx::Error> {
+ sqlx::query_as::<_, DirectiveEvent>(
+ r#"
+ INSERT INTO directive_events (directive_id, chain_id, step_id, event_type, severity, event_data, actor_type, actor_id)
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
+ RETURNING *
+ "#,
+ )
+ .bind(directive_id)
+ .bind(chain_id)
+ .bind(step_id)
+ .bind(event_type)
+ .bind(severity)
+ .bind(event_data)
+ .bind(actor_type)
+ .bind(actor_id)
+ .fetch_one(pool)
+ .await
+}
+
+/// Update step evaluation fields after an evaluation completes.
+pub async fn update_step_evaluation_fields(
+ pool: &PgPool,
+ step_id: Uuid,
+ confidence_score: Option<f64>,
+ confidence_level: Option<&str>,
+ last_evaluation_id: Uuid,
+) -> Result<Option<ChainStep>, sqlx::Error> {
+ sqlx::query_as::<_, ChainStep>(
+ r#"
+ UPDATE chain_steps
+ SET confidence_score = $2,
+ confidence_level = $3,
+ evaluation_count = evaluation_count + 1,
+ last_evaluation_id = $4
+ WHERE id = $1
+ RETURNING *
+ "#,
+ )
+ .bind(step_id)
+ .bind(confidence_score)
+ .bind(confidence_level)
+ .bind(last_evaluation_id)
+ .fetch_optional(pool)
+ .await
+}
+
+/// Update step monitoring contract/task references.
+pub async fn update_step_monitoring_contract(
+ pool: &PgPool,
+ step_id: Uuid,
+ monitoring_contract_id: Uuid,
+ monitoring_task_id: Uuid,
+) -> Result<Option<ChainStep>, sqlx::Error> {
+ sqlx::query_as::<_, ChainStep>(
+ r#"
+ UPDATE chain_steps
+ SET monitoring_contract_id = $2,
+ monitoring_task_id = $3
+ WHERE id = $1
+ RETURNING *
+ "#,
+ )
+ .bind(step_id)
+ .bind(monitoring_contract_id)
+ .bind(monitoring_task_id)
+ .fetch_optional(pool)
+ .await
+}
+
+/// Increment step rework_count.
+pub async fn increment_step_rework_count(
+ pool: &PgPool,
+ step_id: Uuid,
+) -> Result<Option<ChainStep>, sqlx::Error> {
+ sqlx::query_as::<_, ChainStep>(
+ r#"
+ UPDATE chain_steps
+ SET rework_count = rework_count + 1
+ WHERE id = $1
+ RETURNING *
+ "#,
+ )
+ .bind(step_id)
+ .fetch_optional(pool)
+ .await
+}
+
+/// Get a chain step by its monitoring contract ID.
+pub async fn get_step_by_monitoring_contract_id(
+ pool: &PgPool,
+ contract_id: Uuid,
+) -> Result<Option<ChainStep>, sqlx::Error> {
+ sqlx::query_as::<_, ChainStep>(
+ r#"SELECT * FROM chain_steps WHERE monitoring_contract_id = $1"#,
+ )
+ .bind(contract_id)
+ .fetch_optional(pool)
+ .await
+}