@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
120 lines • 4.05 kB
JavaScript
import { ConfigManager } from '../../config/config-manager.js';
export class KanbanDataStore {
store = { boards: {} };
configManager;
MODULE_NAME = 'kanban';
DATA_FILE = 'kanban.json';
constructor(configManager) {
this.configManager = configManager || new ConfigManager();
}
async init() {
const storageManager = this.configManager.getStorageManager();
await storageManager.ensureStorageDirectories();
const data = await storageManager.loadData(this.MODULE_NAME, this.DATA_FILE);
if (data) {
this.store = data;
}
else {
// If file doesn't exist, create it with empty store
await this.save();
}
}
async save() {
const storageManager = this.configManager.getStorageManager();
await storageManager.saveData(this.MODULE_NAME, this.DATA_FILE, this.store);
}
createBoard(name, columns = ['Backlog', 'To Do', 'In Progress', 'Review', 'Done']) {
const board = {
id: this.generateId(),
name,
columns,
tasks: [],
createdAt: new Date(),
updatedAt: new Date(),
};
this.store.boards[board.id] = board;
return board;
}
getBoard(nameOrId) {
// Try to find by ID first
if (this.store.boards[nameOrId]) {
return this.store.boards[nameOrId];
}
// Try to find by name
return Object.values(this.store.boards).find(board => board.name === nameOrId);
}
getAllBoards() {
return Object.values(this.store.boards);
}
addTask(boardNameOrId, task) {
const board = this.getBoard(boardNameOrId);
if (!board) {
return null;
}
const newTask = {
...task,
id: this.generateId(),
createdAt: new Date(),
updatedAt: new Date(),
// Initialize new enhanced properties with defaults if not provided
acceptanceCriteria: task.acceptanceCriteria || [],
dependencies: task.dependencies || [],
timeTracking: task.timeTracking || undefined,
attachments: task.attachments || [],
comments: task.comments || [],
customFields: task.customFields || [],
subtasks: task.subtasks || [],
watchers: task.watchers || [],
// Ensure tags is used instead of labels for consistency
tags: task.tags || task.labels || [],
};
board.tasks.push(newTask);
board.updatedAt = new Date();
return newTask;
}
moveTask(boardNameOrId, taskId, newColumn) {
const board = this.getBoard(boardNameOrId);
if (!board) {
return false;
}
const task = board.tasks.find(t => t.id === taskId);
if (!task || !board.columns.includes(newColumn)) {
return false;
}
task.column = newColumn;
task.updatedAt = new Date();
board.updatedAt = new Date();
return true;
}
updateTask(boardNameOrId, taskId, updates) {
const board = this.getBoard(boardNameOrId);
if (!board) {
return false;
}
const task = board.tasks.find(t => t.id === taskId);
if (!task) {
return false;
}
Object.assign(task, updates);
task.updatedAt = new Date();
board.updatedAt = new Date();
return true;
}
deleteTask(boardNameOrId, taskId) {
const board = this.getBoard(boardNameOrId);
if (!board) {
return false;
}
const taskIndex = board.tasks.findIndex(t => t.id === taskId);
if (taskIndex === -1) {
return false;
}
board.tasks.splice(taskIndex, 1);
board.updatedAt = new Date();
return true;
}
generateId() {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
}
//# sourceMappingURL=store.js.map