Oppgave-noder: proposal/assignment/task node_kind med validering
Tre nye node-typer for oppgavestyring: - proposal: status (draft/discussed/approved/rejected/parked) - assignment: status (open/planning/active/paused/done/blocked) + priority - task: status (open/active/done/failed/skipped) + priority Validering i create_node og update_node. Ingen ny tabell — bruker eksisterende nodes-tabell med metadata. Ref: docs/infra/oppgaver.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
68d8fff2dd
commit
494a6b5f18
1 changed files with 69 additions and 0 deletions
|
|
@ -317,6 +317,69 @@ fn validate_orchestration_metadata(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Validerer metadata for oppgave-noder (proposal, assignment, task).
|
||||
///
|
||||
/// Ref: docs/infra/oppgaver.md
|
||||
fn validate_task_metadata(
|
||||
node_kind: &str,
|
||||
metadata: &serde_json::Value,
|
||||
) -> Result<(), String> {
|
||||
match node_kind {
|
||||
"proposal" => {
|
||||
// Valgfri status, default "draft"
|
||||
if let Some(status) = metadata.get("status").and_then(|v| v.as_str()) {
|
||||
let valid = ["draft", "discussed", "approved", "rejected", "parked"];
|
||||
if !valid.contains(&status) {
|
||||
return Err(format!(
|
||||
"proposal metadata.status må være en av: {}",
|
||||
valid.join(", ")
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
"assignment" => {
|
||||
// Valgfri status, default "open"
|
||||
if let Some(status) = metadata.get("status").and_then(|v| v.as_str()) {
|
||||
let valid = ["open", "planning", "active", "paused", "done", "blocked"];
|
||||
if !valid.contains(&status) {
|
||||
return Err(format!(
|
||||
"assignment metadata.status må være en av: {}",
|
||||
valid.join(", ")
|
||||
));
|
||||
}
|
||||
}
|
||||
// Valgfri priority (heltall)
|
||||
if let Some(val) = metadata.get("priority") {
|
||||
if !val.is_number() {
|
||||
return Err("assignment metadata.priority må være et tall".into());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
"task" => {
|
||||
// Valgfri status, default "open"
|
||||
if let Some(status) = metadata.get("status").and_then(|v| v.as_str()) {
|
||||
let valid = ["open", "active", "done", "failed", "skipped"];
|
||||
if !valid.contains(&status) {
|
||||
return Err(format!(
|
||||
"task metadata.status må være en av: {}",
|
||||
valid.join(", ")
|
||||
));
|
||||
}
|
||||
}
|
||||
// Valgfri priority (heltall)
|
||||
if let Some(val) = metadata.get("priority") {
|
||||
if !val.is_number() {
|
||||
return Err("task metadata.priority må være et tall".into());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ErrorResponse {
|
||||
pub error: String,
|
||||
|
|
@ -649,6 +712,9 @@ pub async fn create_node(
|
|||
// -- Valider metadata for orchestration-noder (oppgave 24.1) --
|
||||
validate_orchestration_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
||||
|
||||
// -- Valider metadata for oppgave-noder (proposal/assignment/task) --
|
||||
validate_task_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
||||
|
||||
// -- Kontekstbasert identitet (oppgave 8.2) --
|
||||
// Hvis context_id er satt, sjekk om brukeren har et alias som er
|
||||
// deltaker i kommunikasjonsnoden. I så fall brukes aliaset som created_by.
|
||||
|
|
@ -1186,6 +1252,9 @@ pub async fn update_node(
|
|||
// -- Valider metadata for orchestration-noder (oppgave 24.1) --
|
||||
validate_orchestration_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
||||
|
||||
// -- Valider metadata for oppgave-noder --
|
||||
validate_task_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
||||
|
||||
// -- Beskytt model_profile for egendefinerte AI-presets (oppgave 18.6) --
|
||||
// Kun admin/owner på en samling kan endre model_profile. Vanlige brukere
|
||||
// som eier et custom preset kan redigere alt annet (prompt, icon, farge osv.)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue