← Índice

8.1 No desde cero

Esta traducción fue asistida por IA y revisada superficialmente. Si encuentras errores o algo no suena natural, escríbeme — lo agradezco.

Dos entradas a un mismo almacén - eso es útil. Dos entradas a dos almacenes con el mismo nombre - esas son dos herramientas separadas que no saben que la otra existe. La diferencia no se nota enseguida: todo parece normal justo hasta que una entrada busca algo que se metió a través de la otra.

Lo que necesitas

La línea de comandos escribe tareas en tasks.json. El servidor podría leer del mismo archivo - entonces ambas entradas llevarían a un único almacén. Ahora mismo el servidor siempre arranca con un almacén vacío. Unas pocas líneas en crates/api/src/main.rs cambian eso: cargar la config, cargar las tareas del disco, pasárselas a TaskStore.

La construcción

El crates/api/src/main.rs completo:

// crates/api/src/main.rs - CAMBIADO
mod routes;

use axum::{Router, routing::get};
use routes::SharedStore;
use std::path::Path;
use std::sync::{Arc, Mutex};
use tq_core::config::Config;
use tq_core::persistence;
use tq_core::store::TaskStore;

async fn health() -> String {
    "tq ok".to_string()
}

#[tokio::main]
async fn main() {
    let config = Config::load(Path::new("config.toml"), None).unwrap_or_default();
    let data_path = config.data_dir.join("tasks.json");
    let tasks = persistence::load(&data_path).unwrap_or_default(); // vec vacío si el archivo no existe
    let store: SharedStore = Arc::new(Mutex::new(TaskStore::new(tasks)));
    let app = Router::new()
        .route("/", get(health))
        .merge(routes::router(store));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

El resultado

Añade tareas por la línea de comandos y luego arranca el servidor. Si hay un tasks.json de capítulos anteriores, bórralo primero:

$ rm -f tasks.json
$ cargo run -p tq-cli -- add "buy milk"
$ cargo run -p tq-cli -- add "send report"
$ make serve

En otro terminal:

$ curl -s localhost:3000/tasks
[{"id":1,"title":"buy milk","status":"Todo","created_at":"2026-06-20T10:00:00Z"},
 {"id":2,"title":"send report","status":"Todo","created_at":"2026-06-20T10:05:00Z"}]

Ambas entradas miran el mismo libro de cuentas. Las tareas añadidas por la CLI son visibles a través de la API.

Las tareas añadidas a través de la API todavía no se guardan - todos los cambios hechos a través del servidor viven solo en la memoria del proceso. El siguiente paso lo corregirá.

El código completo de tq para este capítulo está en 8-ready/01-not-from-scratch/.