Quando usarlo
La UI ha bisogno di una risposta immediata dal core Rust, per esempio la
dimensione del database locale o i dettagli di un file scelto. I passi usano
come esempio un comando storage_info. Il lavoro che può durare più di un
istante (leggere un albero di cartelle, rete, dispositivi) è un job: vedi il
playbook "Aggiungere un job handler".
Regole da rispettare
- Il percorso è sempre UI →
packages/native-client→ comando Tauri →crates/app-api→ crate del core. Il comando chiama un solo metodo diAppApi; nessuna logica inapps/desktop/src-tauri. - Ogni comando ha bisogno del proprio permesso in
apps/desktop/src-tauri/capabilities/main-window.json. Niente permessi globali o wildcard. - I tipi attraversano il confine come DTO di
crates/app-api/src/dto.rs; le versioni TypeScript sono generate, mai scritte a mano. - Gli errori sono valori
ApiErrorcon un codiceRW_*stabile, mai frasi. È la UI a tradurre il codice. - Un percorso che arriva dalla UI passa da
validate_pathprima di essere usato.
Passi
Aggiungi il DTO in
crates/app-api/src/dto.rscon gli stessi derive e attributi degli altri (Serialize,Deserialize, ilcfg_attrdits-exporterename_all = "camelCase"). Marca i campiu64conts(type = "number")come faJobDto:#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "ts-export", derive(TS), ts(export))] #[serde(rename_all = "camelCase")] pub struct StorageInfoDto { pub data_dir: String, #[cfg_attr(feature = "ts-export", ts(type = "number"))] pub database_bytes: u64, }Aggiungi il metodo ad
AppApiincrates/app-api/src/api.rs, che restituisceResult<StorageInfoDto, ApiError>. Costruisci gli errori conApiError::new("RW_...", category, recoverable)e controlla i moduli disattivati come fanno i metodi esistenti. Testalo incrates/app-api/tests/api.rscon l'helperapi(config()), compreso il caso di errore.Esegui
pnpm types:generate, esporta il nuovo tipo dapackages/shared-types/src/index.tse fai commit dei file inpackages/shared-types/src/generated.pnpm types:checkfallisce se non sono aggiornati.Aggiungi il comando nel file corrispondente di
apps/desktop/src-tauri/src/commands/(quifilesystem.rs), sul modello divalidate_path: riceveState<'_>e gli argomenti e restituiscestate.api.storage_info(). Registralo ingenerate_handler!insrc-tauri/src/main.rs, dichiara"storage_info"inbuild.rse concedi"allow-storage-info"incapabilities/main-window.json.Aggiungi il metodo all'interfaccia
NativeClientinpackages/native-client/src/client.ts, aTauriNativeClientintauri.ts(call<StorageInfoDto>("storage_info"); gli argomenti JavaScript sono in camelCase e Tauri li converte in snake_case) e aMockNativeClientinmock.tscon dati realistici e gli scenari di errore. Testa il mock inmock.test.ts.Leggilo nella UI con un hook in
apps/desktop/src/features/<feature>/hooks/, comeuseFeatures:useQuerycon una chiave stabile euseNativeClient(). Mostra gli errori coni18n.error.Aggiungi ogni nuovo codice
RW_*inpackages/i18n/locales/*/errors.jsone ogni testo della UI incommon.json, in de-DE, en e it-IT. Controlla il layout in tedesco.Elenca il comando in
docs/tauri-bridge.md.
Completato quando
- i comandi di verifica superano e
pnpm types:checknon segnala differenze; - il comando ha esattamente una voce
allow-<nome>nella capability ed è registrato inmain.rsebuild.rs; - il mock implementa il metodo, così
pnpm devfunziona senza il core Rust; - ogni nuovo codice e testo esiste nelle tre lingue.
