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(())
|
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)]
|
#[derive(Serialize)]
|
||||||
pub struct ErrorResponse {
|
pub struct ErrorResponse {
|
||||||
pub error: String,
|
pub error: String,
|
||||||
|
|
@ -649,6 +712,9 @@ pub async fn create_node(
|
||||||
// -- Valider metadata for orchestration-noder (oppgave 24.1) --
|
// -- Valider metadata for orchestration-noder (oppgave 24.1) --
|
||||||
validate_orchestration_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
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) --
|
// -- Kontekstbasert identitet (oppgave 8.2) --
|
||||||
// Hvis context_id er satt, sjekk om brukeren har et alias som er
|
// Hvis context_id er satt, sjekk om brukeren har et alias som er
|
||||||
// deltaker i kommunikasjonsnoden. I så fall brukes aliaset som created_by.
|
// 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) --
|
// -- Valider metadata for orchestration-noder (oppgave 24.1) --
|
||||||
validate_orchestration_metadata(&node_kind, &metadata).map_err(|e| bad_request(&e))?;
|
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) --
|
// -- Beskytt model_profile for egendefinerte AI-presets (oppgave 18.6) --
|
||||||
// Kun admin/owner på en samling kan endre model_profile. Vanlige brukere
|
// 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.)
|
// som eier et custom preset kan redigere alt annet (prompt, icon, farge osv.)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue