Skip to Content
ExamplesTask Manager

Task Manager Tutorial

Build a complete task management application using Synap SDK. This tutorial covers all core features: creating entities, managing relationships, and tracking history.

What You’ll Build

A task manager with:

  • ✅ Create, update, delete tasks
  • 👥 Assign tasks to people
  • 🔗 Task dependencies
  • 📊 Task statistics
  • 📜 Complete audit trail
  • 🔍 Search functionality

Prerequisites

pnpm add @synap/sdk

Initialize SDK:

import { SynapSDK } from '@synap/sdk' const synap = new SynapSDK({ url: process.env.SYNAP_URL!, apiKey: process.env.SYNAP_API_KEY! })

Step 1: Create Tasks

Basic Task Creation

async function createTask(title: string, priority: 'low' | 'medium' | 'high') { const { entityId } = await synap.entities.create({ type: 'task', title, preview: `Priority: ${priority}`, metadata: { priority, status: 'todo', createdAt: new Date().toISOString() } }) console.log('✅ Task created:', entityId) return entityId } // Usage const taskId = await createTask('Review PR #123', 'high')

Task with Due Date

async function createTaskWithDueDate( title: string, dueDate: string, priority: 'low' | 'medium' | 'high' = 'medium' ) { const { entityId } = await synap.entities.create({ type: 'task', title, metadata: { priority, status: 'todo', dueDate, estimatedHours: 2 } }) return entityId } // Create task due tomorrow const tomorrow = new Date() tomorrow.setDate(tomorrow.getDate() + 1) await createTaskWithDueDate( 'Prepare quarterly report', tomorrow.toISOString().split('T')[0], 'high' )

Step 2: Assign Tasks to People

Create Person

async function createPerson(name: string, email: string) { const { entityId } = await synap.entities.create({ type: 'person', title: name, metadata: { email, role: 'developer' } }) return entityId } const marie = await createPerson('Marie Johnson', 'marie@example.com') const john = await createPerson('John Smith', 'john@example.com')

Assign Task

async function assignTask(taskId: string, personId: string) { await synap.relations.create(taskId, personId, 'assigned_to') console.log('✅ Task assigned') } // Assign task to Marie await assignTask(taskId, marie)

Get Task Assignees

async function getTaskAssignees(taskId: string) { const people = await synap.relations.getRelated(taskId, { type: 'assigned_to', direction: 'source' }) return people } // Check who is assigned const assignees = await getTaskAssignees(taskId) console.log('Assigned to:', assignees.map(p => p.title).join(', '))

Step 3: Task Dependencies

Create Dependent Tasks

async function createDependentTask( title: string, dependsOnTaskId: string ) { // Create new task const { entityId } = await synap.entities.create({ type: 'task', title, metadata: { priority: 'medium', status: 'blocked' // Can't start until dependency completes } }) // Create dependency relationship await synap.relations.create(entityId, dependsOnTaskId, 'depends_on') return entityId } // Create task that depends on another const designTask = await createTask('Design new feature', 'high') const implementTask = await createDependentTask( 'Implement new feature', designTask )

Check Dependencies

async function getTaskDependencies(taskId: string) { const dependencies = await synap.relations.getRelated(taskId, { type: 'depends_on', direction: 'source' }) return dependencies } // Check what task depends on const deps = await getTaskDependencies(implementTask) console.log('Depends on:', deps.map(t => t.title))

Find Blocked Tasks

async function getBlockedTasks() { const allTasks = await synap.entities.list({ type: 'task' }) return allTasks.filter(task => task.metadata.status === 'blocked' ) } const blocked = await getBlockedTasks() console.log(`${blocked.length} tasks are blocked`)

Step 4: Update Tasks

Mark Task as In Progress

async function startTask(taskId: string) { await synap.entities.update(taskId, { metadata: { status: 'in_progress', startedAt: new Date().toISOString() } }) console.log('✅ Task started') } await startTask(taskId)

Complete Task

async function completeTask(taskId: string) { await synap.entities.update(taskId, { metadata: { status: 'done', completedAt: new Date().toISOString() } }) console.log('✅ Task completed') } await completeTask(designTask) // Unblock dependent tasks const dependents = await synap.relations.getRelated(designTask, { type: 'depends_on', direction: 'target' // Tasks that depend ON this one }) for (const task of dependents) { await synap.entities.update(task.id, { metadata: { status: 'todo' } }) }

Update Priority

async function updateTaskPriority( taskId: string, priority: 'low' | 'medium' | 'high' ) { await synap.entities.update(taskId, { metadata: { priority } }) } await updateTaskPriority(taskId, 'urgent')

Step 5: Query Tasks

Get All Tasks

async function getAllTasks() { const tasks = await synap.entities.list({ type: 'task', limit: 100 }) return tasks } const allTasks = await getAllTasks() console.log(`Total tasks: ${allTasks.length}`)

Filter by Status

function filterByStatus(tasks: Entity[], status: string) { return tasks.filter(task => task.metadata.status === status) } const allTasks = await getAllTasks() const todoTasks = filterByStatus(allTasks, 'todo') const inProgress = filterByStatus(allTasks, 'in_progress') const done = filterByStatus(allTasks, 'done') console.log(`Todo: ${todoTasks.length}`) console.log(`In Progress: ${inProgress.length}`) console.log(`Done: ${done.length}`)

Get Overdue Tasks

function getOverdueTasks(tasks: Entity[]) { const now = new Date() return tasks.filter(task => { if (!task.metadata.dueDate || task.metadata.status === 'done') { return false } const dueDate = new Date(task.metadata.dueDate) return dueDate < now }) } const overdue = getOverdueTasks(allTasks) console.log(`⚠️ ${overdue.length} overdue tasks`)

Search Tasks

async function searchTasks(query: string) { const results = await synap.entities.search({ query, types: ['task'], limit: 20 }) return results } // Search for tasks const results = await searchTasks('review code') console.log(`Found ${results.length} tasks`)

Step 6: Task Statistics

Get User’s Task Stats

async function getTaskStats() { const tasks = await getAllTasks() const stats = { total: tasks.length, todo: filterByStatus(tasks, 'todo').length, inProgress: filterByStatus(tasks, 'in_progress').length, done: filterByStatus(tasks, 'done').length, overdue: getOverdueTasks(tasks).length, byPriority: { high: tasks.filter(t => t.metadata.priority === 'high').length, medium: tasks.filter(t => t.metadata.priority === 'medium').length, low: tasks.filter(t => t.metadata.priority === 'low').length } } return stats } const stats = await getTaskStats() console.log('Task Statistics:', stats)

Get Person’s Tasks

async function getPersonTasks(personId: string) { const tasks = await synap.relations.getRelated(personId, { type: 'assigned_to', direction: 'target' // Person is target of assignment }) return tasks } const marieTasks = await getPersonTasks(marie) console.log(`Marie has ${marieTasks.length} tasks`)

Step 7: Audit Trail

View Task History

async function getTaskHistory(taskId: string) { const history = await synap.events.getHistory(taskId) console.log(`\nTask History (${history.length} events):`) history.forEach(event => { console.log(`${event.createdAt}: ${event.eventType}`) console.log(' Data:', event.data) }) return history } await getTaskHistory(taskId)

Track Changes

async function getTaskChanges(taskId: string) { const history = await synap.events.getHistory(taskId) const updates = history.filter(e => e.eventType === 'entities.update.validated' ) console.log('\nTask Changes:') updates.forEach(update => { console.log(`\n${update.createdAt}:`) Object.entries(update.data.metadata || {}).forEach(([key, value]) => { console.log(` ${key}: ${value}`) }) }) return updates } await getTaskChanges(taskId)

Step 8: Delete Tasks

Soft Delete

async function deleteTask(taskId: string) { // Delete task await synap.entities.delete(taskId) // Relationships are automatically handled console.log('✅ Task deleted') } await deleteTask(taskId)

Complete Example: Task Dashboard

async function buildTaskDashboard() { // Get all tasks const tasks = await getAllTasks() // Get statistics const stats = await getTaskStats() // Get overdue tasks const overdue = getOverdueTasks(tasks) // Get high priority tasks const highPriority = tasks.filter(t => t.metadata.priority === 'high' && t.metadata.status !== 'done' ) return { stats, overdue: overdue.map(t => ({ id: t.id, title: t.title, dueDate: t.metadata.dueDate, daysOverdue: Math.floor( (Date.now() - new Date(t.metadata.dueDate).getTime()) / (1000 * 60 * 60 * 24) ) })), highPriority: highPriority.map(t => ({ id: t.id, title: t.title, status: t.metadata.status, assignees: [] // Fetch separately })), recentActivity: tasks .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime() ) .slice(0, 5) } } // Use it const dashboard = await buildTaskDashboard() console.log('Dashboard:', dashboard)

Next Steps

Enhance Your Task Manager:

  1. Add Comments - Create note entities linked to tasks
  2. Task Templates - Create reusable task structures
  3. Notifications - Use event webhooks for real-time updates
  4. Time Tracking - Add start/end times, calculate duration
  5. Sub-tasks - Use parent_of relationships
  6. Tags - Create tag entities and link with tagged_with
  7. Projects - Group tasks under project entities

Full Code

Complete task manager implementation

import { SynapSDK } from '@synap/sdk' const synap = new SynapSDK({ url: process.env.SYNAP_URL!, apiKey: process.env.SYNAP_API_KEY! }) // Create task async function createTask(title: string, priority: 'low' | 'medium' | 'high') { const { entityId } = await synap.entities.create({ type: 'task', title, metadata: { priority, status: 'todo' } }) return entityId } // Assign task async function assignTask(taskId: string, personId: string) { await synap.relations.create(taskId, personId, 'assigned_to') } // Update status async function updateStatus(taskId: string, status: string) { await synap.entities.update(taskId, { metadata: { status } }) } // Get all tasks async function getAllTasks() { return await synap.entities.list({ type: 'task' }) } // Get statistics async function getStats() { const tasks = await getAllTasks() return { total: tasks.length, todo: tasks.filter(t => t.metadata.status === 'todo').length, done: tasks.filter(t => t.metadata.status === 'done').length } } // Main async function main() { // Create person const { entityId: personId } = await synap.entities.create({ type: 'person', title: 'Marie Johnson', metadata: { email: 'marie@example.com' } }) // Create and assign task const taskId = await createTask('Review code', 'high') await assignTask(taskId, personId) // Complete task await updateStatus(taskId, 'done') // Show stats const stats = await getStats() console.log('Stats:', stats) } main()

Congratulations! 🎉 You’ve built a complete task management system with Synap SDK!

Last updated on