Skip to content

Steps in a Task

A Step is a child of a Task with only a title and a done state. Steps cannot be starred, assigned, shared, dated, or nested — and a Step cannot have Steps (Product Brief §5.2 “Step rules”).

The components that make up the Step feature, server through client:

flowchart LR
  Routes["registerStepsRoutes<br/>(src/api/routes/steps.ts)"] --> Repo["createStepsRepository<br/>(src/db/repositories/steps.ts)"]
  Repo --> Schema[("steps table<br/>(src/db/schema.ts)")]
  Repo --> Rank["generateKeyBetween<br/>(Fractional Rank)"]
  Client["Offline mutation API<br/>+ outbox"] --> Routes
  Recon["reconcileSteps /<br/>reconcileAllSteps"] --> Client
  Recon --> Rank
  • The steps table (src/db/schema.ts): taskId, title, done, rank, timestamps.
  • createStepsRepository(db) (src/db/repositories/steps.ts) — typed access (list/create/update/delete/reorder by rank).
  • Routes in src/api/routes/steps.ts (registerStepsRoutes) — contract-first under /v1. New Steps are added at the bottom of the Step list (rank at end); deleting a Task deletes its Steps.
  • Steps reconcile via reconcileSteps(...) and reconcileAllSteps(...) (see Sync-Core Reconcilers); ordering uses the Fractional Rank Algorithm (per-Task scope).
  • Optimistic create/rename/toggle/reorder flow through the offline mutation API + outbox (see Offline Outbox & Optimistic Writes).

The runtime path of adding a Step, from optimistic UI write to server persistence and reconcile:

sequenceDiagram
  participant UI as Step UI
  participant Outbox as Offline mutation API + outbox
  participant API as registerStepsRoutes (/v1)
  participant Repo as createStepsRepository
  participant DB as steps table
  UI->>Outbox: create Step (optimistic)
  Outbox->>API: POST /v1 step
  API->>Repo: create (rank at end)
  Repo->>DB: insert with fractional rank
  API-->>Outbox: persisted Step
  Outbox->>UI: reconcileSteps(...) applies server state

Related: Fractional Rank Algorithm (per-Task ordering), Sync-Core Reconcilers, Task Attributes API (the parent Task).