How to Perform Bulk Task Operations and Imports in Kaneo

Kaneo's bulk-task API lets you apply status changes, assignments, labels, and deletions to multiple tasks at once via a single PATCH request to /api/task/bulk.

Kaneo is an open-source project management platform that treats bulk actions as first-class citizens. Whether you're cleaning up completed tasks, reassigning an entire sprint, or importing work from an external system, the bulk operations architecture in Kaneo makes mass updates efficient and permission-aware. This guide walks through the API design, frontend integration, and practical patterns for bulk task operations and imports.

Understanding Kaneo's Bulk Task API

The core bulk functionality lives in the Bulk-Update-Tasks controller at apps/api/src/task/controllers/bulk-update-tasks.ts. This controller handles the PATCH /api/task/bulk endpoint and validates every request against workspace membership before executing database operations.

Request Payload Structure

Every bulk request requires three fields:

Field Type Description
taskIds string[] Array of task UUIDs to modify
operation string The operation to perform (see supported operations below)
value string | null | undefined Operation-specific value (omitted for delete)

The controller enforces a critical constraint: all tasks must belong to the same workspace, and the requesting user must have access to that workspace. This prevents cross-tenant data leaks.

Supported Bulk Operations

Kaneo supports seven distinct bulk operations as implemented in the controller:

Operation Required value Effect on Tasks
updateStatus Column slug ("planned", "in-progress", "done", etc.) Moves tasks to a new board column
updatePriority Priority string ("low", "medium", "high") Updates priority field
updateAssignee User ID string or omitted Reassigns to user or unassigns
delete None Permanently deletes selected tasks
addLabel Label ID Attaches label to each task
removeLabel Label ID Detaches label and syncs with GitHub/Gitea
updateDueDate ISO 8601 date string or null Sets or clears due dates

After successful execution, the controller calls publishEvent for each affected task, ensuring real-time UI synchronization across connected clients.

Frontend Architecture for Bulk Operations

The Kaneo web interface implements bulk actions through a coordinated system of React components, custom hooks, and fetchers.

Component: Bulk Toolbar

The Bulk Toolbar (apps/web/src/components/bulk-selection/bulk-toolbar.tsx) appears automatically when users select multiple tasks. It renders action buttons based on available operations and consumes the useBulkOperations hook.

Hook: useBulkOperations

Located at apps/web/src/hooks/mutations/task/use-bulk-operations.ts, this hook creates a collection of useMutation objects—one for each bulk operation type. Key responsibilities include:

  • Wrapping API calls with loading/error states
  • Cache invalidation for tasks, projects, and labels queries on success
  • Returning strongly-typed mutateAsync functions for programmatic use

Fetcher: bulkOperation

The low-level network call resides in apps/web/src/fetchers/task/bulk-operation.ts. It sends a PATCH request and throws JavaScript exceptions for HTTP errors, allowing consistent error handling upstream.

Implementing Bulk Task Operations

React Hook Examples

Bulk archive (status update):

import { useBulkOperations } from "@/hooks/mutations/task/use-bulk-operations";

const { bulkArchive } = useBulkOperations();

async function archiveCompleted(taskIds: string[]) {
  await bulkArchive(taskIds);
  // Query cache automatically refreshes
}

Bulk assign to user:

const { bulkAssign } = useBulkOperations();

await bulkAssign({ 
  taskIds: selectedIds, 
  userId: "usr_123abc" 
});

Bulk add label:

const { bulkAddLabel } = useBulkOperations();

await bulkAddLabel({ 
  taskIds: selectedIds, 
  labelId: "lbl_456def" 
});

Direct Fetcher Usage (Non-React)

For server-side scripts, CLI tools, or vanilla JavaScript:

import bulkOperation from "@/fetchers/task/bulk-operation";

await bulkOperation({
  taskIds: ["task_a1", "task_b2", "task_c3"],
  operation: "updatePriority",
  value: "high"
});

Importing Tasks with Bulk Operations

Kaneo does not expose a dedicated import endpoint. Instead, the recommended pattern combines task creation with bulk application of shared properties.

Import Workflow

  1. Parse source data (CSV, JSON, Trello export, etc.) on the client
  2. Create tasks individually using createTask fetcher (apps/web/src/fetchers/task/create-task.ts)
  3. Collect returned task IDs
  4. Issue bulk operation to apply common labels, assignments, or due dates

This two-phase approach leverages Kaneo's existing validation while minimizing API calls for property application.

Import-Then-Bulk Example

import { createTask } from "@/fetchers/task/create-task";
import bulkOperation from "@/fetchers/task/bulk-operation";

async function importFromTrello(cards: TrelloCard[]) {
  const newTaskIds: string[] = [];
  
  // Phase 1: Create individual tasks
  for (const card of cards) {
    const { id } = await createTask({
      title: card.name,
      description: card.desc,
      projectId: destinationProjectId
    });
    newTaskIds.push(id);
  }
  
  // Phase 2: Bulk-label all imports
  await bulkOperation({
    taskIds: newTaskIds,
    operation: "addLabel",
    value: "migrated-from-trello"
  });
  
  // Optional: Bulk assign to import owner
  await bulkOperation({
    taskIds: newTaskIds,
    operation: "updateAssignee",
    value: currentUserId
  });
}

Key Implementation Files

Purpose Path
API route registration apps/api/src/task/index.ts
Core bulk controller apps/api/src/task/controllers/bulk-update-tasks.ts
Bulk toolbar UI apps/web/src/components/bulk-selection/bulk-toolbar.tsx
Operations hook apps/web/src/hooks/mutations/task/use-bulk-operations.ts
Network fetcher apps/web/src/fetchers/task/bulk-operation.ts
List view integration apps/web/src/components/list-view/task-row.tsx
Selection state apps/web/src/store/bulk-selection.ts

Summary

  • Kaneo's bulk-task API at /api/task/bulk supports seven operations: status, priority, assignee, delete, add/remove label, and due date updates
  • Workspace validation ensures users can only affect tasks within accessible workspaces
  • Frontend integration uses useBulkOperations hook with automatic cache invalidation
  • Import patterns combine individual task creation with bulk property application for efficiency
  • Real-time sync via publishEvent keeps all connected clients updated

Frequently Asked Questions

What is the payload limit for bulk operations?

The Kaneo source code does not enforce a hard limit on taskIds array length in bulk-update-tasks.ts, but practical limits depend on your database configuration and request timeout settings. For imports exceeding hundreds of tasks, consider batching into multiple requests.

Can I undo a bulk delete operation?

No. The delete operation permanently removes tasks immediately, with no soft-delete or trash mechanism in the current implementation. Always verify your selection before executing bulk deletions.

How do bulk operations handle partial failures?

The controller validates all task IDs against workspace membership before executing any database changes. If validation fails for any task, the entire request rejects with an error—operations are atomic at the request level.

Is there built-in CSV import support?

Not directly. Kaneo expects you to parse CSV files client-side and use the standard task creation API followed by bulk operations. This design keeps the core API lean while enabling flexible import sources (CSV, JSON, XML, third-party APIs).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →