---
title: "Example: Task Management App · RUAL Documentation"
description: "Boards, columns, assignees and due dates."
canonical: https://docs.rual.nl/examples/task-management
language: en
---

# Example: Task Management App

Boards, assignments, due dates, and activity. A complete team task app assembled from the CRUD tutorial upward.

This is the CRUD tutorial grown up: multiple lists, people, and notifications. It reuses the exact flows from [Build Your First CRUD App](https://docs.rual.nl/getting-started/first-crud-app) and shows what to add for a real team tool.

### The Task Document

```
{
  "_meta": {
    "cms": 1782166695910,
    "created": 1782166695,
    "entity": 1,
    "expiry": -1,
    "guid": "f7802a394c5f48da8694374577160bc974cf563deb37a02d3bf085ca420b4325",
    "removed": 0,
    "ums": 1782253095327,
    "update_hash": "a4f8172be5093d6c47ba209fe83c15d074e2b6a9",
    "updated": 1782253095
  },
  "assignee_guid": "b9ee6a631b24e78d1aa48aef0dc067fff7bfbacd24a56ef4ed1f08e537d48b6bd02",
  "assignee_name": "sami b",
  "board": "engineering",
  "column": "in-progress",
  "created_by": "sami b",
  "due": 1782432000,
  "labels": [
    "ux",
    "onboarding"
  ],
  "priority": "high",
  "title": "review q3 onboarding flow"
}
```

- `column` drives the board view (todo / in-progress / review / done); `board` separates teams.

- Assignee is denormalized. The board renders names without joins (see [Storages](https://docs.rual.nl/blueprints/storage)).

- Everything searchable (`title`, `labels`) is lowercase at write time.

### The Views

- **Board**: one `function_search` per column (term on `board` + `column`, sorted by `priority` then `due`) or one search grouped in the flow with `array` blocks. The dashboard pattern from [Dashboards](https://docs.rual.nl/tutorials/dashboard-charts).

- **My tasks**: `user_current` → term on `assignee_guid` + `column != done`, sorted by `due` ascending.

- **Detail**: the task + its activity log (term on `task_guid`) on one page.

- **Overdue strip**: `column != done` + `due < now` (range query) at the top of every board.

### The Flows

- **Create/move**. The CRUD flows from the tutorial, plus writing an activity entry per change (`moved to review by sami b`) via a second create in the same flow.

- **Assign**: update `assignee_guid` + `assignee_name` together (never one without the other), then notify the new assignee with the [email pattern](https://docs.rual.nl/tutorials/email-system).

- **Daily digest**: [`schedule_repeating_event`](https://docs.rual.nl/block-types/events/schedule_repeating_event): tasks due tomorrow per assignee, one mail each with `reminder_sent` markers to stay idempotent.

- **Close**: status to `done` with a timestamp; boards filter it out, stats keep counting it.

### Scaling Notes

- Board queries get a `cache_key`: boards are read-heavy and tolerate seconds of staleness (see [caching patterns](https://docs.rual.nl/blueprints/common-patterns#caching-strategies)).

- Invalidate the board cache on every task write with a storage-event → Redis delete flow ([cache invalidation](https://docs.rual.nl/blueprints/common-patterns#caching-strategies)).

- Past a few thousand open tasks per board, split counters per column onto a stats document instead of counting live.

### Next Steps
