Skip to content

A full-featured task tracker application built with the Motia framework, demonstrating event-driven architecture with CRUD operations, task management, and asynchronous notifications.

Notifications You must be signed in to change notification settings

glauberfc/task-tracker

Repository files navigation

Task Tracker - Motia Example

A full-featured task tracker application built with the Motia framework, demonstrating event-driven architecture with CRUD operations, task management, and asynchronous notifications.

Features

  • Complete CRUD Operations: Create, read, update, and delete tasks
  • 👤 Task Assignment: Assign tasks to users
  • 📊 Status Workflow: Manage task status (todo → in-progress → done/cancelled)
  • 🔔 Asynchronous Notifications: Background event processing for notifications
  • 🎯 Priority Levels: Low, medium, high, and urgent priorities
  • 📅 Due Dates: Optional due date tracking
  • 🔍 Filtering: Query tasks by status, assignee, or priority

Architecture

Task Properties

  • id: Unique task identifier
  • title: Task title
  • description: Task description
  • status: Current status (todo, in-progress, done, cancelled)
  • assignee: Assigned user (optional)
  • priority: Priority level (low, medium, high, urgent)
  • dueDate: Due date in ISO format (optional)
  • createdAt: Creation timestamp
  • updatedAt: Last update timestamp

Project Structure

src/
└── services/
    └── task/
        ├── types.ts           # Task types and Zod schemas
        ├── task-service.ts    # In-memory task service
        └── index.ts           # Service exports

steps/
└── task/
    ├── create-task.step.ts              # POST /tasks
    ├── get-task.step.ts                 # GET /tasks/:id
    ├── list-tasks.step.ts               # GET /tasks
    ├── update-task.step.ts              # PUT /tasks/:id
    ├── delete-task.step.ts              # DELETE /tasks/:id
    ├── assign-task.step.ts              # PUT /tasks/:id/assign
    ├── update-status.step.ts            # PUT /tasks/:id/status
    ├── notify-task-created.step.ts      # Event: task.created
    ├── notify-task-assigned.step.ts     # Event: task.assigned
    ├── notify-status-changed.step.ts    # Event: task.status-changed
    └── notify-task-updated.step.ts      # Event: task.updated

API Endpoints

Create Task

POST /tasks
Content-Type: application/json

{
  "title": "Implement authentication",
  "description": "Add JWT-based authentication to the API",
  "priority": "high",
  "assignee": "[email protected]",
  "dueDate": "2025-10-15T00:00:00Z"
}

Get Task

GET /tasks/:id

List Tasks

GET /tasks
# Optional query parameters:
# - status: todo | in-progress | done | cancelled
# - assignee: user email
# - priority: low | medium | high | urgent

# Examples:
GET /tasks?status=in-progress
GET /tasks?[email protected]
GET /tasks?priority=high&status=todo

Update Task

PUT /tasks/:id
Content-Type: application/json

{
  "title": "Updated title",
  "description": "Updated description",
  "priority": "urgent",
  "dueDate": "2025-10-20T00:00:00Z"
}

Delete Task

DELETE /tasks/:id

Assign Task

PUT /tasks/:id/assign
Content-Type: application/json

{
  "assignee": "[email protected]"
}

Update Status

PUT /tasks/:id/status
Content-Type: application/json

{
  "status": "in-progress"
}

Event Flow

The application uses Motia's event-driven architecture for notifications:

  1. API Step receives request and processes it
  2. API Step emits event (e.g., task.created)
  3. Event Step subscribes to the event and handles notification
  4. Notification is logged (can be extended to email, Slack, etc.)

Events

  • task.created: Triggered when a new task is created
  • task.assigned: Triggered when a task is assigned to a user
  • task.status-changed: Triggered when task status changes
  • task.updated: Triggered when task is updated

Getting Started

Prerequisites

  • Node.js 18+ installed
  • npm or yarn

Installation

# Install dependencies
npm install

# Generate Motia types
npm run generate-types

Development

# Start the development server
npm run dev

The server will start on the default port (typically 3000). You can then access:

  • API endpoints at http://localhost:3000/tasks
  • Motia Workbench for visualization at http://localhost:3000/__workbench

Build

# Build for production
npm run build

Using Motia Workbench

Motia Workbench provides real-time visualization of your task management flow:

  1. Navigate to http://localhost:3000/__workbench
  2. Select the task-management flow
  3. View all connected steps and their relationships
  4. Monitor events and traces in real-time
  5. Test API endpoints directly from the UI

Testing Examples

Create a Task

curl -X POST http://localhost:3000/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Write documentation",
    "description": "Create comprehensive README for the project",
    "priority": "high"
  }'

List All Tasks

curl http://localhost:3000/tasks

Filter Tasks by Status

curl http://localhost:3000/tasks?status=todo

Assign a Task

curl -X PUT http://localhost:3000/tasks/TASK_ID/assign \
  -H "Content-Type: application/json" \
  -d '{
    "assignee": "[email protected]"
  }'

Update Task Status

curl -X PUT http://localhost:3000/tasks/TASK_ID/status \
  -H "Content-Type: application/json" \
  -d '{
    "status": "in-progress"
  }'

Extending the Application

Add Real Notifications

Replace the simulated notifications in Event Steps with real integrations:

// Example: Send email notification
import { sendEmail } from './email-service'

export const handler: Handlers['NotifyTaskCreated'] = async (input, { logger }) => {
  await sendEmail({
    to: input.assignee,
    subject: `New Task: ${input.title}`,
    body: `You have been assigned a new task with ${input.priority} priority.`
  })
}

Add Database Persistence

Replace the in-memory storage in task-service.ts with a real database:

import { db } from './database'

class TaskService {
  async create(input: CreateTaskInput): Promise<Task> {
    return await db.tasks.insert({...})
  }
  // ... other methods
}

Add Authentication

Create middleware for authentication:

// middleware/auth.middleware.ts
export const authMiddleware: ApiMiddleware = async (req, ctx, next) => {
  const token = req.headers.authorization
  // Validate token and add user to context
  return await next()
}

// In your steps
export const config: ApiRouteConfig = {
  // ...
  middleware: [authMiddleware]
}

Learn More

License

This is an example project for demonstration purposes.

About

A full-featured task tracker application built with the Motia framework, demonstrating event-driven architecture with CRUD operations, task management, and asynchronous notifications.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published