The server side of task-pool-cli:
a FastAPI router implementing a lightweight, append-only task pool used to coordinate
work across a fleet of devices. Tasks and responses are persisted as JSONL (one
message per line, one file per UTC day) — no message broker, no extra infrastructure.
This repository is an extracted slice of a larger FastAPI backend, kept self-contained enough to read and reason about on its own.
The pool is low-volume (fleet coordination, not high-throughput jobs) and benefits from
being human-readable and greppable. Appends are atomic on Linux for single-line
writes (O_APPEND, line ≤ PIPE_BUF), so concurrent writers don't corrupt the file, and
a day's history is just cat 2026-06-03.jsonl.
Each line is one JSON object:
{
"id": "msg_<uuid4hex>", "ts": "2026-06-03T12:34:56Z",
"from": "user:<email> | device:<id> | backend",
"to": "device:<id> | device:* | device:[1,2] | user:<email>",
"type": "task | response | info | heartbeat | error",
"title": "...", "body": "...", "parent_id": "msg_... | null", "meta": { }
}A task is "pending" for a device if it targets that device (device:<id>, device:*, or
a list) and has no response with status done/failed referencing it via parent_id.
| Method & path | Auth | Purpose |
|---|---|---|
GET /pool/pending |
device | Unanswered tasks addressed to the calling device |
POST /pool/response |
device | Post a result (done/failed/progress) |
POST /pool/heartbeat |
device | Liveness ping |
POST /pool/task |
master | Create a task for one or many devices |
GET /pool/log |
admin | Dump a day's messages (?date=YYYY-MM-DD) |
GET /pool/devices |
admin | Registered devices + last pool activity |
Device endpoints authenticate with the JWT in backend/auth/jwt_auth.py
(get_device_id_from_token); the /task, /log, and /devices endpoints require a
role-checked user.
backend/
auth/jwt_auth.py # JWT device auth (HS256, env-provided SECRET_KEY) — self-contained
pool/routes.py # the task-pool router
pool/routes.py expects three things from the application it's mounted into:
-
backend.core.database.get_db— a FastAPI dependency yielding a SQLAlchemySession. -
backend.users.auth_user.get_current_user— resolves the authenticatedUser. -
backend.core.models— SQLAlchemy models with at least:class UserRole(enum.Enum): admin = "admin"; master = "master"; user = "user" class User: id; email; role: UserRole class DeviceUser: id; user_session; validado: bool; kind: str
Wire it up with app.include_router(pool_router) (and the auth router from your app).
MIT — see LICENSE.