Saltar al contenido

El árbol de decisión

Cinco preguntas que llevan cualquier cosa que quieras guardar a su sitio, y el cierre del nivel: lo que ya puedes decidir antes de conocer las plataformas.

Las cinco preguntas

El paso 5 es el patrón que resuelve todo lo que no cabe en el paso 4: una base de datos entera, un directorio de documentos, un archivo grande. No se meten en el llavero —que no está pensado para eso y tiene límites de tamaño— sino que se cifran, y lo que se guarda en el llavero son los pocos bytes de la clave.

Los destinos

Lo que ya puedes decidir sin conocer las plataformas

Esto es lo importante del cierre: cuatro decisiones de diseño no dependen de macOS, Windows ni Linux, y se pueden tomar hoy.

  • Qué guardas y qué no. El paso 1 y el paso 2 son de tu aplicación, no del sistema.
  • La forma de tus identificadores. Nivel 34.3: servicio estable, cuenta que identifica al sujeto, comprensible para el usuario.
  • Que el código que toca secretos viva en el core y no en el frontend. Nivel 31.5: lo que no llega a la webview no se puede leer desde ahí. El frontend pide operaciones —«inicia sesión», «llama a la API»—, nunca el testigo.
  • Y que el camino de «no está» sea un camino normal. Porque el usuario puede borrar la entrada, cambiar de máquina o arrancar sin almacén, y las tres cosas van a pasar.

Lo que sí depende de la plataforma es más estrecho de lo que parece: cuándo aparece un diálogo, qué rompe el acceso, y qué hacer si el almacén no existe. Ésos son los tres niveles siguientes.

Rust
// la forma que sale de las cuatro decisiones: el secreto no cruza el puente#[tauri::command]async fn iniciar_sesion(app: AppHandle, email: String, clave: String) -> Result<Perfil, Error> {    let testigo = servicio::autenticar(&email, &clave).await?;    secretos::guardar(&app, &email, &testigo)?;   // se queda en el core    Ok(testigo.perfil)                            // sale el perfil, no el testigo}#[tauri::command]async fn sesion_actual(app: AppHandle) -> Result<Option<Perfil>, Error> {    // "no está" es un camino normal, no un error    match secretos::leer(&app)? {        Some(t) => Ok(Some(servicio::perfil(&t).await?)),        None => Ok(None),    }}