fix(backend): exclusion mutuelle des backends OpenCode (llamacpp vs cloud) (#97)
Les builders `with_opencode` / `with_opencode_provider` s'évacuent réciproquement (dernier appel gagnant) pour honorer l'invariant `opencode_backend_is_consistent`. Le use case SaveOpenCodeProviderProfile route désormais via le builder au lieu de muter le champ directement — c'est ce qui dupliquait `opencode` + `opencodeProvider` et forçait un repli sur llamacpp même quand l'utilisateur choisissait un provider cloud. Défense en profondeur côté store : - `read_doc` répare les profils corrompus sur disque (drop du stale `opencode`) - `save` refuse de persister un profil violant l'invariant via le nouveau variant `StoreError::Invalid` (mappé vers `AppError::Invalid`) Tests verts : builders last-wins (domain), save rejets + read repair (infra, profile_store 10/10). Refs #97
This commit is contained in:
@ -361,8 +361,12 @@ impl SaveOpenCodeProviderProfile {
|
||||
provider = provider.with_custom(custom);
|
||||
}
|
||||
|
||||
let mut profile = input.profile;
|
||||
profile.opencode_provider = Some(provider);
|
||||
// Route through the builder (ticket #97): `with_opencode_provider` clears
|
||||
// any stale `opencode` (llamacpp) carried by the input profile, so the
|
||||
// persisted profile honours the mutual-exclusion invariant instead of
|
||||
// keeping both backends — which previously forced a wrong llamacpp
|
||||
// fallback even when the user chose a cloud provider.
|
||||
let profile = input.profile.with_opencode_provider(provider);
|
||||
|
||||
self.profile_store.save(&profile).await?;
|
||||
Ok(SaveOpenCodeProviderProfileOutput { profile })
|
||||
|
||||
@ -134,6 +134,7 @@ impl From<StoreError> for AppError {
|
||||
fn from(e: StoreError) -> Self {
|
||||
match e {
|
||||
StoreError::NotFound => Self::NotFound("store item".to_owned()),
|
||||
StoreError::Invalid(message) => Self::Invalid(message),
|
||||
other => Self::Store(other.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user