← Table of contents

8.1 Not from Scratch

Two entries into one store - that is useful. Two entries into two stores with the same name

What You Need

The command line writes tasks to tasks.json. The server could read from the same file - then both entries would lead to one store. Right now the server always starts with an empty store. A few lines in crates/api/src/main.rs change that: load the config, load the tasks from disk, hand them to TaskStore.

The Build

The full crates/api/src/main.rs:

// crates/api/src/main.rs - CHANGED
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(); // empty vec if file missing
    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();
}

The Result

Add tasks through the command line, then start the server. If a tasks.json remains from earlier chapters, clear it first:

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

In another 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"}]

Both entries look into the same ledger. Tasks added through the CLI are visible through the API.

Tasks added through the API are not yet saved - all changes made through the server live only in process memory. The next step will fix that.

The complete tq code for this chapter is in 8-ready/01-not-from-scratch/.