diff --git a/.pa/task_arch10c.md b/.pa/task_arch10c.md new file mode 100644 index 00000000..6cb24704 --- /dev/null +++ b/.pa/task_arch10c.md @@ -0,0 +1,15 @@ +# ARCH-10c — Ziel-Routen nach hq_routes + +Status: entwurf + +Paketgröße: M, höchstens 300 Diff-Zeilen +Dateien: `src-tauri/src/api.rs`, `src-tauri/src/api/hq_routes.rs`, dieser Auftrag + +Verschiebt unverändert die drei Arme `GET /api/hq/v1/goals`, +`POST /api/hq/v1/goals` und `POST /api/hq/v1/goals/:goalId/tasks` aus +`api.rs` in `hq_routes::handle()`. Besitztest in `hq_routes::route` nennt +genau diese Methoden und Pfadsegmente, kein Präfix- oder Methoden-Platzhalter. + +Keine neue Funktion, kein Bugfix, keine Änderung an Backend, Store, Schema, +Auth oder Konfiguration. Bestehende Ziel-API-Tests in `api.rs` decken +Verhalten und Reihenfolge ab (No-Test, rein mechanisch). diff --git a/src-tauri/src/api.rs b/src-tauri/src/api.rs index 77817f7d..024e8a45 100644 --- a/src-tauri/src/api.rs +++ b/src-tauri/src/api.rs @@ -1386,84 +1386,6 @@ fn route(inner: &Inner, request: &Request, proof: VerdictProof) -> Response { } match (method, path.as_slice()) { - ("GET", ["api", "hq", "v1", "goals"]) => { - let project_id = match project_id { - Some(value) if !value.is_empty() => value, - _ => return Response::error(400, "projectId is required"), - }; - match backend.list_continuous_goals(project_id) { - Ok(goals) => Response::ok(json!({ "goals": goals })), - Err(err) => continuous_error(err), - } - } - ("POST", ["api", "hq", "v1", "goals"]) => { - let body = match parse_body(&request.body) { - Ok(body) => body, - Err(err) => return Response::error(400, err), - }; - if let Err(err) = only_keys( - &body, - &[ - "projectId", - "objective", - "acceptanceCriteria", - "sourceGoalId", - "admit", - ], - ) { - return Response::error(400, err); - } - let project_id = match required_str(&body, "projectId") { - Ok(value) => value, - Err(err) => return Response::error(400, err), - }; - let objective = match required_str(&body, "objective") { - Ok(value) => value, - Err(err) => return Response::error(400, err), - }; - let admit = match optional_bool(&body, "admit") { - Ok(value) => value.unwrap_or(false), - Err(err) => return Response::error(400, err), - }; - match backend.create_continuous_goal( - &project_id, - &objective, - optional_str(&body, "acceptanceCriteria"), - optional_str(&body, "sourceGoalId"), - admit, - ) { - Ok(goal) => Response::ok(json!({ "goal": goal })), - Err(err) => continuous_error(err), - } - } - ("POST", ["api", "hq", "v1", "goals", goal_id, "tasks"]) => { - let body = match parse_body(&request.body) { - Ok(body) => body, - Err(err) => return Response::error(400, err), - }; - let objective = match required_str(&body, "objective") { - Ok(value) => value, - Err(err) => return Response::error(400, err), - }; - let owned_paths = match string_array(&body, "ownedPaths") { - Ok(value) => value, - Err(err) => return Response::error(400, err), - }; - let dependencies = match string_array(&body, "dependencies") { - Ok(value) => value, - Err(err) => return Response::error(400, err), - }; - match backend.create_continuous_task( - goal_id, - &objective, - optional_str(&body, "profileId"), - owned_paths, - dependencies, - ) { - Ok(task) => Response::ok(json!({ "task": task })), - Err(err) => continuous_error(err), - } - } ("GET", ["api", "hq", "v1", "tasks", task_id, "assignment"]) => { match backend.continuous_task_assignment(task_id) { Ok(assignment) => Response::ok( diff --git a/src-tauri/src/api/hq_routes.rs b/src-tauri/src/api/hq_routes.rs index 3fec7dc3..fba3a901 100644 --- a/src-tauri/src/api/hq_routes.rs +++ b/src-tauri/src/api/hq_routes.rs @@ -21,6 +21,8 @@ pub(super) fn route( | ("GET", ["api", "hq", "v1", "runtime" | "plan" | "runs"]) | ("GET", ["api", "hq", "v1", "context" | "changes"]) | ("POST", ["api", "hq", "v1", "plan", "import"]) + | ("GET" | "POST", ["api", "hq", "v1", "goals"]) + | ("POST", ["api", "hq", "v1", "goals", _, "tasks"]) ); owned.then(|| handle(inner, request, method, path, project_id)) } @@ -173,6 +175,84 @@ fn handle( } continuous_response(backend.development_records(project_id)) } + ("GET", ["api", "hq", "v1", "goals"]) => { + let project_id = match project_id { + Some(value) if !value.is_empty() => value, + _ => return Response::error(400, "projectId is required"), + }; + match backend.list_continuous_goals(project_id) { + Ok(goals) => Response::ok(json!({ "goals": goals })), + Err(err) => continuous_error(err), + } + } + ("POST", ["api", "hq", "v1", "goals"]) => { + let body = match parse_body(&request.body) { + Ok(body) => body, + Err(err) => return Response::error(400, err), + }; + if let Err(err) = only_keys( + &body, + &[ + "projectId", + "objective", + "acceptanceCriteria", + "sourceGoalId", + "admit", + ], + ) { + return Response::error(400, err); + } + let project_id = match required_str(&body, "projectId") { + Ok(value) => value, + Err(err) => return Response::error(400, err), + }; + let objective = match required_str(&body, "objective") { + Ok(value) => value, + Err(err) => return Response::error(400, err), + }; + let admit = match optional_bool(&body, "admit") { + Ok(value) => value.unwrap_or(false), + Err(err) => return Response::error(400, err), + }; + match backend.create_continuous_goal( + &project_id, + &objective, + optional_str(&body, "acceptanceCriteria"), + optional_str(&body, "sourceGoalId"), + admit, + ) { + Ok(goal) => Response::ok(json!({ "goal": goal })), + Err(err) => continuous_error(err), + } + } + ("POST", ["api", "hq", "v1", "goals", goal_id, "tasks"]) => { + let body = match parse_body(&request.body) { + Ok(body) => body, + Err(err) => return Response::error(400, err), + }; + let objective = match required_str(&body, "objective") { + Ok(value) => value, + Err(err) => return Response::error(400, err), + }; + let owned_paths = match string_array(&body, "ownedPaths") { + Ok(value) => value, + Err(err) => return Response::error(400, err), + }; + let dependencies = match string_array(&body, "dependencies") { + Ok(value) => value, + Err(err) => return Response::error(400, err), + }; + match backend.create_continuous_task( + goal_id, + &objective, + optional_str(&body, "profileId"), + owned_paths, + dependencies, + ) { + Ok(task) => Response::ok(json!({ "task": task })), + Err(err) => continuous_error(err), + } + } _ => unreachable!("route() only hands over owned arms"), } }