v0.1.4-pre.012-fix.001

This commit is contained in:
2026-08-16 16:35:51 +02:00
parent 13a2e0038a
commit 2b343c25de
8 changed files with 128 additions and 11 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 80
# version: 81
[workspace]
resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib"]
[workspace.package]
version = "0.1.4-pre.12"
version = "0.1.4-pre.12.fix.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/README.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# `ksp-app-config-desk`
@@ -153,4 +153,6 @@ La vue **Environnement / `.env`** expose la projection sûre de `ConfigManagemen
Les mutations acceptent un nom existant ou nouveau sous `KSP_*` / `KSPB_*`, présentent explicitement `source_changed`, `effective_changed`, `shadowed_by_process_environment` et `reload_required`, puis rechargent le rapport depuis Config. Une ligne du tableau ne précharge que le nom de variable : aucune ancienne valeur réelle n'est injectée dans le formulaire. Pour un namespace Secret, la nouvelle saisie est masquée ; la consultation d'une valeur réelle reste réservée au flux privilégié de `pre.013`.
La suppression demande une confirmation via un modal Bootstrap intégré au shell. Les dialogues navigateur natifs `window.alert` / `window.confirm` / `window.prompt` ne sont pas utilisés pour ce flux.
Les valeurs `KSP_SECRET_*` / `KSPB_SECRET_*` restent redacted par `ksp-config-lib` dans le rapport. La priorité `process > .env > fallback` reste visible : une mutation `.env` shadowed peut changer le desired sans modifier l'effective. Les logs frontend/backend n'enregistrent jamais la valeur soumise, seulement le nom de variable, l'opération et les booléens du rapport de changement.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/USAGE.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# Utilisation de `ksp-app-config-desk`
@@ -194,4 +194,6 @@ reload_required
Cliquer une ligne du rapport remplit uniquement le nom de variable. L'ancienne valeur n'est jamais préchargée dans le formulaire. Une saisie `KSP_SECRET_*` / `KSPB_SECRET_*` est masquée ; le reveal de l'ancienne valeur réelle reste hors de cette tranche.
Le bouton **Supprimer** ouvre un modal Bootstrap indiquant la variable ciblée. **Annuler**, la fermeture du modal ou `Esc` abandonnent l'opération ; **Supprimer** confirme ensuite l'appel à `ConfigManagement::remove_dotenv_value()`. Aucun `window.confirm()` natif n'est utilisé.
Pour valider le shadowing, lancer ponctuellement l'application avec `KSP_LOGS_DIRECTORY` fourni par le process puis modifier la même variable dans `.env` depuis le panneau. Le résultat attendu est `source_changed=true`, `effective_changed=false`, `shadowed_by_process_environment=true`, `reload_required=false`. Le process hérité reste prioritaire et n'est jamais modifié par Config Desk.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/frontend/main.html -->
<!-- version: 7 -->
<!-- version: 8 -->
<!DOCTYPE html>
<html lang="fr">
@@ -306,6 +306,25 @@
</div>
</main>
<div id="environmentRemoveConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="environmentRemoveConfirmTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h2 id="environmentRemoveConfirmTitle" class="modal-title fs-5">Confirmer la suppression .env</h2>
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Annuler"></button>
</div>
<div class="modal-body">
<p class="mb-2">Supprimer l'entrée <code id="environmentRemoveConfirmVariable" class="font-monospace"></code> de <code>.env</code> ?</p>
<p class="text-body-secondary small mb-0">L'environnement process déjà hérité ne sera pas modifié.</p>
</div>
<div class="modal-footer">
<button class="btn btn-outline-secondary" type="button" data-bs-dismiss="modal">Annuler</button>
<button id="environmentRemoveConfirmAction" class="btn btn-danger" type="button">Supprimer</button>
</div>
</div>
</div>
</div>
<footer class="app-footer bg-dark text-light">
<div class="container h-100 d-flex align-items-center justify-content-center">
<small>&copy; 2026 SASEDEV</small>

View File

@@ -1,8 +1,9 @@
// file: crates/ksp-app-config-desk/frontend/ts/environment.ts
// version: 2
// version: 3
//! Safe environment report and `.env` management panel backed exclusively by ConfigManagement.
import { Modal } from "bootstrap";
import DataTable from "datatables.net-bs5";
import "datatables.net-bs5/css/dataTables.bootstrap5.css";
import type { ConfigEnvironmentChangeDto } from "./bindings/ksp_app_config_desk/environment/ConfigEnvironmentChangeDto";
@@ -221,6 +222,35 @@ function setMutationControlsDisabled(disabled: boolean): void {
document.querySelector<HTMLButtonElement>("#removeEnvironmentValue")?.toggleAttribute("disabled", disabled);
}
function confirmEnvironmentRemoval(variableName: string): Promise<boolean> {
const modalElement = document.querySelector<HTMLElement>("#environmentRemoveConfirmModal");
const variable = document.querySelector<HTMLElement>("#environmentRemoveConfirmVariable");
const confirmButton = document.querySelector<HTMLButtonElement>("#environmentRemoveConfirmAction");
if (!modalElement || !variable || !confirmButton) {
frontendDebug("main", "Environment removal confirmation modal is unavailable", { variableName });
return Promise.resolve(false);
}
variable.textContent = variableName;
const modal = Modal.getOrCreateInstance(modalElement);
frontendDebug("main", "Environment .env removal confirmation opened", { variableName });
return new Promise<boolean>(resolve => {
let confirmed = false;
const onConfirm = (): void => {
confirmed = true;
modal.hide();
};
const onHidden = (): void => {
confirmButton.removeEventListener("click", onConfirm);
variable.textContent = "";
frontendDebug("main", "Environment .env removal confirmation answered", { variableName, confirmed });
resolve(confirmed);
};
confirmButton.addEventListener("click", onConfirm, { once: true });
modalElement.addEventListener("hidden.bs.modal", onHidden, { once: true });
modal.show();
});
}
async function refreshEnvironmentReport(): Promise<void> {
frontendDebug("main", "Config environment report refresh requested");
setEnvironmentStatus("Chargement du rapport environnement sûr...", "primary");
@@ -289,14 +319,14 @@ async function removeEnvironmentValue(): Promise<void> {
setMutationStatus("Saisis ou sélectionne la variable .env à supprimer.", "warning");
return;
}
const confirmed = window.confirm(`Supprimer l'entrée .env ${variableName} ? L'environnement process hérité ne sera pas modifié.`);
frontendTrace("main", "Environment .env removal confirmation answered", { variableName, confirmed });
setMutationControlsDisabled(true);
const confirmed = await confirmEnvironmentRemoval(variableName);
if (!confirmed) {
setMutationControlsDisabled(false);
return;
}
const sensitivity = classifyEditorSensitivity(variableName);
frontendDebug("main", "Environment .env mutation requested", { operation: "remove", variableName, sensitivity });
setMutationControlsDisabled(true);
setMutationStatus("Suppression atomique par Config...", "secondary");
try {
const result = await invokeKsp<ConfigEnvironmentChangeDto>("main", "remove_environment_value", { variableName });

View File

@@ -0,0 +1,62 @@
<!-- file: deltas/0.1.4/pre.012-fix.001.md -->
<!-- version: 1 -->
# Delta `0.1.4-pre.012-fix.001` — confirmation Bootstrap des suppressions `.env`
## Statut
Correctif de `pre.012` livré pour validation locale.
La validation utilisateur de `pre.012` confirme déjà `fmt`, `check`, `clippy`, les 34 tests Config Desk, les 87 tests Config, les cinq audits ownership et les 12 tests d'API publique. Les mutations `.env` create/update/remove fonctionnent et les valeurs Secret restent redacted. Le défaut corrigé ici est uniquement l'emploi d'un dialogue navigateur natif `window.confirm()` lors d'une suppression.
## Correctif
- remplacement de `window.confirm()` par un modal Bootstrap intégré à `main.html` ;
- le modal affiche uniquement le nom de la variable ciblée et rappelle que l'environnement process hérité n'est pas modifié ;
- **Annuler**, fermeture du modal ou `Esc` annulent la suppression ;
- **Supprimer** ferme le modal puis déclenche le flux existant `remove_environment_value` ;
- les contrôles de mutation sont désactivés pendant la confirmation afin d'éviter plusieurs confirmations concurrentes ;
- ouverture et réponse du modal sont journalisées en `debug` sans valeur `.env` ;
- ajout de la règle normative `KSP-APP-032` : les interfaces desk KSP utilisent des modals Bootstrap pour les confirmations destructives/privilégiées au lieu de `window.alert` / `window.confirm` / `window.prompt` ;
- README, USAGE et plan `0.1.4` alignés.
## Sécurité
Le correctif ne change ni l'ownership Config ni le payload IPC : aucune valeur `.env` supplémentaire n'est projetée, journalisée ou préchargée. La suppression reste exclusivement réalisée par `ConfigManagement::remove_dotenv_value()`.
## Validation fonctionnelle restante de `pre.012`
Après validation de ce fix, le seul scénario fonctionnel encore non observé dans les logs fournis est le shadowing réel `process > .env`, car le dernier lancement rapporte `process_count=0`.
Lancer par exemple :
```bash
KSP_LOGS_DIRECTORY=logs-process-test \
cargo tauri dev -c crates/ksp-app-config-desk/tauri.conf.json
```
Puis modifier `KSP_LOGS_DIRECTORY` depuis l'UI. Résultat attendu :
```text
source_changed = true
effective_changed = false
shadowed_by_process_environment = true
reload_required = false
```
## Version technique
```text
workspace.package.version = "0.1.4-pre.12.fix.1"
```
## Validation locale demandée
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-app-config-desk
cargo test -p ksp-config-lib
cargo tauri dev -c crates/ksp-app-config-desk/tauri.conf.json
```

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md -->
<!-- version: 13 -->
<!-- version: 14 -->
# Plan `0.1.4` — `ksp-app-config-desk`
@@ -1221,6 +1221,7 @@ pre.011 Environnement — rapports [réalisé]
pre.012 Environnement — management/test .env [en cours]
- create/update via set_dotenv_value
- remove via remove_dotenv_value
- confirmation destructive via modal Bootstrap, sans dialogue natif window.confirm
- résultats source/effective/shadow/reload
- démonstration process > .env
- démonstration placeholder KSP_LOGS_DIRECTORY

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 27 -->
<!-- version: 28 -->
# Règles spécifiques à KSP
@@ -224,6 +224,7 @@
- **KSP-APP-029** — En développement workspace, une application desk Tauri normalise le current working directory du processus Rust vers la racine du workspace avant le bootstrap Config lorsque `cargo tauri ... -c crates/<app>/tauri.conf.json` lance le binaire depuis la crate. Cette adaptation ne lit ni ne parse directement `config/`, `.env` ou les variables `KSP_*`/`KSPB_*` : `ksp-config-lib` reste seul propriétaire de ces ressources. Le comportement de distribution/release reste défini séparément et ne doit pas dépendre dun checkout source.
- **KSP-APP-030** — Lorsquune application KSP persiste des logs applicatifs, chaque lancement doit disposer dun fichier propre et non partagé avec un lancement précédent. Le nom encode au minimum lidentité applicative et un horodatage de démarrage, par exemple `app-name.YYYYMMDD-HHMMSS.log` / `.json` / `.jsonl` selon le format du sink ; une rotation quotidienne ne doit pas fusionner plusieurs exécutions applicatives dans le même fichier.
- **KSP-APP-031** — Le niveau de logging spécifique à une application/crate peut être élevé temporairement à `debug` ou `trace` pendant une phase de développement ou correction. Avant la clôture/release de cette application/crate, son niveau de référence est ramené à `info` ou `warn` selon le besoin opératoire ; il nest remonté que lorsquun développement/correctif est explicitement rouvert.
- **KSP-APP-032** — Les interfaces desk KSP nutilisent pas les dialogues bloquants natifs du navigateur (`window.alert`, `window.confirm`, `window.prompt`) pour les interactions applicatives normales. Les confirmations destructives ou privilégiées utilisent un modal Bootstrap intégré à lUI, instrumenté par le bridge Logging ; toute exception doit être explicitement justifiée et documentée.
## Data plane / control plane