feat: implémentation et QA ticket99 - agent model configuration v2

- backend A-C: VO Codex/Claude, renderers/projecteurs modèle, SecretRef/env, catalogues/use cases/Tauri commands
- frontend D: profils Codex/Claude provider->model->secret, validations, conservation SecretRef
- fix: app-tauri embedded_server isolant IDEA_WEB_ROOT

QA: backend 57/57 tests, frontend 74/74 tests OK
This commit is contained in:
2026-07-26 11:56:25 +02:00
parent 13fb538880
commit dae07d35bb
27 changed files with 2358 additions and 143 deletions

View File

@ -623,29 +623,6 @@ mod tests {
use super::*;
use uuid::Uuid;
struct EnvVarGuard {
key: &'static str,
previous: Option<std::ffi::OsString>,
}
impl EnvVarGuard {
fn set(key: &'static str, value: &Path) -> Self {
let previous = std::env::var_os(key);
std::env::set_var(key, value);
Self { key, previous }
}
}
impl Drop for EnvVarGuard {
fn drop(&mut self) {
if let Some(previous) = &self.previous {
std::env::set_var(self.key, previous);
} else {
std::env::remove_var(self.key);
}
}
}
fn tmp_app_data() -> PathBuf {
std::env::temp_dir().join(format!("idea-embedded-server-test-{}", Uuid::new_v4()))
}
@ -662,6 +639,19 @@ mod tests {
web_root
}
fn tmp_resource_dir_with_web_root() -> PathBuf {
let resource_dir =
std::env::temp_dir().join(format!("idea-embedded-server-resource-{}", Uuid::new_v4()));
let web_root = resource_dir.join("web");
std::fs::create_dir_all(&web_root).unwrap();
std::fs::write(
web_root.join("index.html"),
"<!doctype html><title>IdeA</title>",
)
.unwrap();
resource_dir
}
fn loopback_bind_available() -> bool {
std::net::TcpListener::bind((Ipv4Addr::LOCALHOST, 0)).is_ok()
}
@ -806,9 +796,9 @@ mod tests {
return;
}
let app_data = tmp_app_data();
let web_root = tmp_web_root();
let _env = EnvVarGuard::set("IDEA_WEB_ROOT", &web_root);
let controller = EmbeddedServerController::new(app_data.clone());
let resource_dir = tmp_resource_dir_with_web_root();
let controller =
EmbeddedServerController::with_resource_dir(app_data.clone(), Some(resource_dir));
controller
.save_settings(ServerExposureSettingsDto {
mode: ServerExposureMode::LocalOnly,
@ -920,9 +910,9 @@ mod tests {
return;
}
let app_data = tmp_app_data();
let web_root = tmp_web_root();
let _env = EnvVarGuard::set("IDEA_WEB_ROOT", &web_root);
let controller = EmbeddedServerController::new(app_data.clone());
let resource_dir = tmp_resource_dir_with_web_root();
let controller =
EmbeddedServerController::with_resource_dir(app_data.clone(), Some(resource_dir));
controller
.save_settings(ServerExposureSettingsDto {
mode: ServerExposureMode::LocalOnly,
@ -979,9 +969,9 @@ mod tests {
return;
}
let app_data = tmp_app_data();
let web_root = tmp_web_root();
let _env = EnvVarGuard::set("IDEA_WEB_ROOT", &web_root);
let controller = EmbeddedServerController::new(app_data.clone());
let resource_dir = tmp_resource_dir_with_web_root();
let controller =
EmbeddedServerController::with_resource_dir(app_data.clone(), Some(resource_dir));
controller
.save_settings(ServerExposureSettingsDto {
mode: ServerExposureMode::LocalOnly,
@ -1006,11 +996,11 @@ mod tests {
return;
}
let app_data = tmp_app_data();
let web_root = tmp_web_root();
let _env = EnvVarGuard::set("IDEA_WEB_ROOT", &web_root);
let resource_dir = tmp_resource_dir_with_web_root();
let reserved = std::net::TcpListener::bind((Ipv4Addr::LOCALHOST, 0)).unwrap();
let port = reserved.local_addr().unwrap().port();
let controller = EmbeddedServerController::new(app_data.clone());
let controller =
EmbeddedServerController::with_resource_dir(app_data.clone(), Some(resource_dir));
controller
.save_settings(ServerExposureSettingsDto {
mode: ServerExposureMode::LocalOnly,