286 lines
9.0 KiB
Markdown
286 lines
9.0 KiB
Markdown
<!-- file: deltas/0.2.12/pre.004.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.12-pre.004` — runtime prix, registry rows et DTOs
|
|
|
|
## 1. Base requise
|
|
|
|
Cette tranche s'applique exclusivement après :
|
|
|
|
```text
|
|
v0.2.11
|
|
+ 0.2.12-pre.001
|
|
+ 0.2.12-pre.001-fix.001
|
|
+ 0.2.12-pre.002
|
|
+ 0.2.12-pre.002-fix.001
|
|
+ 0.2.12-pre.003
|
|
+ 0.2.12-pre.003-fix.001
|
|
```
|
|
|
|
Le retour opérateur du `27 août 2026` clôt `pre.003-fix.001` pour la progression de release : `cargo fmt`, audits Rust/Markdown, `cargo check --workspace`, Clippy workspace, `cargo test -p ksp-app-solprices-desk` et `cargo tauri dev` passent. Le runtime Tauri journalise le bootstrap Logging, le profil composite `public_keyless`, le profil Off-chain `public_keyless` et `provider_count=8`. `cargo test --workspace` n'est pas présent dans ce retour précis et n'est donc pas revendiqué comme exécuté.
|
|
|
|
La version workspace passe à :
|
|
|
|
```text
|
|
0.2.12-pre.4
|
|
```
|
|
|
|
Les versions `package.json` et `tauri.conf.json` de SOL Prices Desk sont synchronisées sur la même prerelease.
|
|
|
|
## 2. Responsabilité de la tranche
|
|
|
|
`pre.004` matérialise uniquement la couche applicative provider-neutral entre le `MarketPriceService` déjà construit par Config et la future UX de refresh :
|
|
|
|
```text
|
|
MarketPriceRuntime backend
|
|
état de présentation courant en mémoire uniquement
|
|
projection du registry en lignes stables
|
|
MarketPriceRuntimeStatusDto
|
|
MarketPriceProviderRowDto
|
|
commande list_market_prices
|
|
états frontend loading / empty / table
|
|
projection initiale sans observation ni prix
|
|
```
|
|
|
|
La tranche n'appelle ni `MarketPriceService::refresh`, ni `refresh_many`, ni `refresh_all`. Aucun bouton de refresh ou scheduler n'est introduit avant les tranches prévues.
|
|
|
|
## 3. Ownership du runtime prix
|
|
|
|
`AppState` possède désormais un `MarketPriceRuntime`. Celui-ci retient :
|
|
|
|
```text
|
|
OffchainTransportStartup
|
|
-> ResolvedOffchainTransportConfig
|
|
-> MarketPriceService
|
|
|
|
presentation: Mutex<...>
|
|
-> une entrée par provider_id opaque
|
|
-> loading bool
|
|
-> dernière observation optionnelle
|
|
```
|
|
|
|
La présentation n'est persistée ni dans Config, ni dans Store, ni sur le filesystem frontend, ni dans `localStorage`/`sessionStorage`.
|
|
|
|
L'inventaire initial est dérivé du `MarketPriceService::registry()` détaché. Chaque ligne commence avec :
|
|
|
|
```text
|
|
loading = false
|
|
observation = None
|
|
price = None
|
|
refreshed = false
|
|
```
|
|
|
|
L'availability initiale reste celle possédée par Off-chain Transport (`Ready`, `Disabled`, etc.).
|
|
|
|
## 4. DTOs provider-neutral
|
|
|
|
`MarketPriceRuntimeStatusDto` remplace le nom bootstrap générique précédent et expose uniquement :
|
|
|
|
```text
|
|
application/config/composite/logging/offchain metadata sûrs
|
|
provider_count
|
|
ready_provider_count
|
|
unavailable_provider_count
|
|
startup_diagnostic sûr
|
|
```
|
|
|
|
`MarketPriceProviderRowDto` expose uniquement la projection générique décidée par le plan :
|
|
|
|
```text
|
|
provider_id opaque
|
|
display_name
|
|
pair = SOL/USD
|
|
semantics générique
|
|
auth_mode générique
|
|
availability générique
|
|
loading
|
|
refreshed
|
|
price optionnel
|
|
provider_timestamp optionnel
|
|
received_at optionnel
|
|
retry_at optionnel
|
|
```
|
|
|
|
Le prix exact traverse l'IPC sous forme de `Option<String>` issue de `MarketPriceDecimal::to_canonical_string()`. Les timestamps traversent eux aussi sous forme de chaînes de millisecondes Unix afin de ne pas introduire de perte d'entier JavaScript. Aucun `f64` n'est une vérité IPC.
|
|
|
|
Les enums Off-chain `#[non_exhaustive]` sont projetés en codes génériques bornés avec fallback `unknown`; aucune enum provider-specific n'est exposée au frontend.
|
|
|
|
## 5. Commande d'inventaire
|
|
|
|
La nouvelle commande Tauri centralisée est :
|
|
|
|
```text
|
|
list_market_prices
|
|
```
|
|
|
|
Elle n'accepte aucun argument et retourne :
|
|
|
|
```text
|
|
Vec<MarketPriceProviderRowDto>
|
|
```
|
|
|
|
Elle ne déclenche aucun réseau. L'ordre des lignes suit l'ordre stable du registry Off-chain.
|
|
|
|
La surface command reste donc à cette tranche :
|
|
|
|
```text
|
|
emit_frontend_log
|
|
get_runtime_status
|
|
list_market_prices
|
|
splash_frontend_ready
|
|
```
|
|
|
|
Les commandes `refresh_market_price`, `refresh_market_prices` et `refresh_all_market_prices` restent absentes par contrat.
|
|
|
|
## 6. Frontend initial
|
|
|
|
La vue `Prices` remplace le placeholder de `pre.003` par trois états explicites :
|
|
|
|
```text
|
|
loading
|
|
empty
|
|
table provider-neutral
|
|
```
|
|
|
|
La table initiale affiche les capacités et l'availability du registry. Comme aucun refresh n'a encore eu lieu, les prix et timestamps d'observation s'affichent comme absents.
|
|
|
|
La tranche n'ajoute aucun bouton Refresh. La finalisation responsive/interactions/DataTable reste propriétaire de `pre.007`.
|
|
|
|
Diagnostics ajoute les comptes total/ready/unavailable sans exposer endpoint, credential, header ou payload provider.
|
|
|
|
## 7. Logging frontend/backend
|
|
|
|
`KSP-APP-027` reste appliqué :
|
|
|
|
```text
|
|
navigation/clic utilisateur debug
|
|
requête IPC debug via invokeKsp
|
|
fin IPC trace
|
|
chargement registry start/end trace
|
|
rendu des lignes trace avec row_count uniquement
|
|
erreur de projection/chargement warn/error sûr
|
|
```
|
|
|
|
Aucun log ne sérialise le prix, la row DTO complète, une API key, un header ou une réponse provider.
|
|
|
|
## 8. Dépendances et boundaries
|
|
|
|
SOL Prices Desk ajoute une dépendance directe à `ksp-offchain-transport-lib` parce que la couche application consomme désormais ses types publics génériques de registry/observation.
|
|
|
|
Cette dépendance ne donne lieu à aucune connaissance provider-specific :
|
|
|
|
```text
|
|
aucun SDK provider
|
|
aucun reqwest direct app
|
|
aucun fetch frontend
|
|
aucune URL/header/API key dans IPC
|
|
aucune branche CoinGecko/Kraken/etc.
|
|
aucun limiter/retry/sleep provider dans app
|
|
```
|
|
|
|
Config reste propriétaire de la construction du service et des secrets.
|
|
|
|
## 9. Tests et canaris
|
|
|
|
Les tests ajoutés/étendus couvrent :
|
|
|
|
```text
|
|
codes génériques auth/availability/semantics
|
|
projection initiale sans observation
|
|
projection exacte d'un decimal 123.4500 -> "123.45"
|
|
provider_timestamp / received_at / retry_at distincts
|
|
MarketPriceRuntime présent à partir de pre.004
|
|
commande list_market_prices centralisée dans tauri.rs
|
|
absence des trois commandes de refresh
|
|
états frontend loading/empty/table
|
|
aucune conversion parseFloat/Number du prix
|
|
aucun reqwest direct dans la crate app
|
|
logging registry sans sérialisation métier
|
|
```
|
|
|
|
Les bindings TS-RS restent générés par les tests et ne sont pas versionnés.
|
|
|
|
## 10. Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-app-solprices-desk/src/market_price_runtime.rs
|
|
crates/ksp-app-solprices-desk/unit_tests/market_price_runtime.rs
|
|
deltas/0.2.12/pre.004.md
|
|
```
|
|
|
|
## 11. Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-app-solprices-desk/Cargo.toml
|
|
crates/ksp-app-solprices-desk/package.json
|
|
crates/ksp-app-solprices-desk/tauri.conf.json
|
|
crates/ksp-app-solprices-desk/frontend/main.html
|
|
crates/ksp-app-solprices-desk/frontend/ts/main.ts
|
|
crates/ksp-app-solprices-desk/src/app_state.rs
|
|
crates/ksp-app-solprices-desk/src/dto_common.rs
|
|
crates/ksp-app-solprices-desk/src/lib.rs
|
|
crates/ksp-app-solprices-desk/src/tauri.rs
|
|
crates/ksp-app-solprices-desk/tests/desktop_contract.rs
|
|
crates/ksp-app-solprices-desk/tests/desktop_security.rs
|
|
docs/plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md
|
|
docs/validation/015-V0_2_12_SOL_PRICES_DESK.md
|
|
```
|
|
|
|
## 12. Fichiers volontairement inchangés
|
|
|
|
```text
|
|
crates/ksp-offchain-transport-lib/**
|
|
crates/ksp-config-lib/**
|
|
crates/ksp-app-wallet-desk/**
|
|
crates/ksp-app-config-desk/**
|
|
README.md
|
|
ROADMAP.md
|
|
CHANGELOG.md
|
|
prompts/017-V0_2_12_START_PROMPT.md
|
|
```
|
|
|
|
Aucun provider, wire REST, rate limit ou Config document n'est modifié.
|
|
|
|
## 13. Validations exécutées dans le sandbox
|
|
|
|
Après matérialisation du code avant écriture du delta :
|
|
|
|
```text
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
General Rust rule audit: clean
|
|
Rust export completeness audit: 0 candidate(s)
|
|
KSP workspace Rust rule audit: clean
|
|
```
|
|
|
|
Après écriture du présent delta :
|
|
|
|
```text
|
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.12
|
|
Markdown table audit: clean (143 table(s), 113 file(s))
|
|
|
|
validation JSON package.json / tauri.conf.json
|
|
JSON validation: clean
|
|
```
|
|
|
|
Le sandbox ne possède pas `cargo`; aucune commande Cargo n'est déclarée PASS localement.
|
|
|
|
## 14. Gate opérateur attendu
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.12
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-app-solprices-desk
|
|
cargo test --workspace
|
|
(cd crates/ksp-app-solprices-desk && cargo tauri dev)
|
|
```
|
|
|
|
Le parcours Tauri attendu doit afficher huit lignes provider-neutral pour le profil `public_keyless`, avec availability initiale mais sans prix ni timestamp d'observation, et sans effectuer de refresh réseau. Diagnostics doit afficher `provider_count=8` avec les comptes ready/unavailable cohérents.
|
|
|
|
## 15. Questions ouvertes
|
|
|
|
Aucune. Si le gate devient propre, `pre.005` peut brancher exclusivement le refresh individuel sur ce runtime sans modifier le format Config ni les adapters providers.
|