# To-Dos

The **to-dos** are a domain of **users** who note down what they mean to do, and work it off: they remember to-dos, adjust them, put them off or move them closer, complete or discard them, restore them, and mark them as important. In a request, the domain is named **`todo`**.

## Subjects

- **A to-do** is a subject of its own, **`/to-dos/<uuid>`**. The subject does not say whose to-do it is: its **owner** is named in its first event, `remembered`, as `rememberedBy`.
- **Users** have no events of their own. They appear only as references in the data, as **`/users/<uuid>`**.

For more on subjects, see **[Subjects](/docs/eventsourcingdb/subjects)**.

## Events

| Event type | What it records | Data |
|---|---|---|
| `io.synthevents.todo.remembered` | A user noted a to-do down, and became its owner. | `rememberedBy`, `intention`, `details`, `dueDate` |
| `io.synthevents.todo.adjusted` | The intention or the details changed. | `intention`, `details` |
| `io.synthevents.todo.postponed` | The due date moved further away. | `dueDate` |
| `io.synthevents.todo.advanced` | The due date moved closer. | `dueDate` |
| `io.synthevents.todo.completed` | The to-do is done. | `completedDate` |
| `io.synthevents.todo.discarded` | The to-do was thrown away. | `discardedDate` |
| `io.synthevents.todo.restored` | A completed or discarded to-do is pending again. | `dueDate` |
| `io.synthevents.todo.prioritized` | The to-do was marked as important. | none |
| `io.synthevents.todo.deprioritized` | The mark was taken away again. | none |

## Data

- **`rememberedBy`** names the owner as **`/users/<uuid>`**.
- **`intention`** is what the user means to do, such as `Write the newsletter`. It is never empty.
- **`details`** is a note on the to-do. It is always present, and an empty string when there is no note.
- **`dueDate`**, **`completedDate`**, and **`discardedDate`** are days, such as `2025-04-03`, in the time zone the rules reckon in.
- `prioritized` and `deprioritized` carry no data, since the mark is all there is to them: their `data` is `{}`.

Every field is present in every event of its type, and no other field is. The **[backup for EventSourcingDB](/docs/synthevents/formats#backup-for-eventsourcingdb)** carries the schemas that say so.

A `remembered` event, formatted for reading, looks like this:

```json
{
  "specversion": "1.0",
  "id": "48",
  "source": "tag:synthevents.io,2026:synthevents;version=golden;domain=todo;scenario=everyday;from=2025-01-01T00:00:00Z;to=2026-01-01T00:00:00Z;eventCount=500;seed=golden",
  "subject": "/to-dos/095dc1e6-aa0f-41d0-b3b8-ed4d0f55fdb8",
  "type": "io.synthevents.todo.remembered",
  "time": "2025-03-23T21:33:23.287981791Z",
  "datacontenttype": "application/json",
  "data": {
    "details": "Draft is on the desktop",
    "dueDate": "2025-04-03",
    "intention": "Write the newsletter",
    "rememberedBy": "/users/26151d86-003c-4179-86c7-4839b9a8c847"
  }
}
```

*Note that this event comes from a test of SynthEvents, which generates its data sets with the version `golden` and the seed `golden`. In a data set of the public service, `version` names the version of SynthEvents that generated it.*

## Rules

The events follow **nine rules**, one for every thing a user can do with a to-do. A command that breaks one of them is refused and leaves no event.

### Ownership

Every command names the **user who sends it**, and the rules refuse every command but noting a to-do down unless that user is the **owner**. They ask this **before anything else**, so a to-do of somebody else tells nothing about itself.

### What a User Can Do

- **Remembering** notes a new to-do down. Its intention must not be empty, and its due date must not be in the past.
- **Adjusting** changes the intention and the details of a pending to-do. The intention must not be empty, and at least one of the two must change.
- **Postponing** moves the due date of a pending to-do further away. The new due date must not be in the past, and must lie after the current one. If the to-do is prioritized and the new due date lies beyond tomorrow, it loses its priority: `deprioritized` follows `postponed`.
- **Advancing** moves the due date of a pending to-do closer. The new due date must not be in the past, and must lie before the current one.
- **Completing** marks a pending to-do as done today. If it was due later, it is advanced to today first: `advanced` comes before `completed`, so that the due date and the date of completion agree.
- **Discarding** throws a pending to-do away today.
- **Restoring** makes a completed or discarded to-do pending again. It keeps its due date, unless that date has passed in the meantime, in which case it is due today.
- **Prioritizing** marks a pending to-do as important. It must not be prioritized already, and it must be due no later than tomorrow.
- **Deprioritizing** takes the mark away from a pending to-do that has it.

The events of one command share the same time, such as `advanced` and `completed`, or `postponed` and `deprioritized`.

### Today

No command carries the day it is sent on. The rules work out **what day it is** from their clock and the **time zone** the scenario chooses, as a server does in its own time zone.

### Revisions

Every command except remembering decides on the **revision** of the to-do its sender saw last, which is the ID of its latest event. If the to-do has changed in the meantime, the command is refused as a conflict.

## Scenarios

- **[To-Dos in Everyday Use](/docs/synthevents/todo-everyday)** (`everyday`) has users join one after the other and work their to-dos off.
