Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
22 changes: 22 additions & 0 deletions .github/instructions/copilot-instructions.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
description: This file describes the architecture of the repository, including the structure of directories and the purpose of key files.
applyTo: "**/*"
---

<!-- Tip: Use /create-instructions in chat to generate content with agent assistance -->

# Repository Architecture
This repository is organized into several key directories and files that serve specific purposes:
- **src/**: This directory contains the source code for the project. It is organized into subdirectories based on functionality, such as components, services, and utilities.
- **tests/**: This directory contains all the test cases for the project. It is structured similarly to the src/ directory to maintain consistency and ease of navigation.
- **docs/**: This directory holds the documentation for the project, including API references, user guides, and architectural diagrams.
- **.github/**: This directory contains GitHub-specific files, such as issue templates,


security policies, and instructions for GitHub Actions workflows.
- **README.md**: This file provides an overview of the project, including its purpose, how to set it up, and how to contribute.
- **LICENSE**: This file specifies the licensing terms for the project, outlining how others can use, modify, and distribute the code.


architechture f this repo is based on a modular design, where each module is responsible for a specific aspect of the application. This promotes separation of concerns and makes the codebase easier to maintain and extend. The use of clear directory structures and naming conventions helps developers quickly locate and understand different parts of the code, facilitating collaboration and onboarding of new contributors.
coding standards and best practices are followed throughout the codebase, ensuring consistency and readability. This includes adhering to established design patterns, writing clear and concise code, and providing comprehensive documentation for functions and modules. By maintaining a well-structured architecture and following coding standards, the project aims to be scalable, maintainable, and accessible to developers of all skill levels.
10 changes: 10 additions & 0 deletions .github/skills/labelskills/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: labelskills
description: create the Label feature
---

<!-- Tip: Use /create-skill in chat to generate content with agent assistance -->

# Label Skills
This skill is responsible for creating the Label feature in the Task Manager App. The Label feature allows users to categorize their tasks using different labels, making it easier to organize and filter tasks based on their labels. The skill will include functionalities such as creating new labels, assigning labels to tasks, and filtering tasks based on their assigned labels. This will enhance the user experience by providing a more efficient way to manage and organize tasks within the application.

65 changes: 65 additions & 0 deletions .github/skills/skills/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: refactor-plan
description: 'Plan a multi-file refactor with proper sequencing and rollback steps'
---

# Refactor Plan

Create a detailed plan for this refactoring task.

## Refactor Goal

{{refactor_description}}

## Instructions

1. Search the codebase to understand current state
2. Identify all affected files and their dependencies
3. Plan changes in a safe sequence (types first, then implementations, then tests)
4. Include verification steps between changes
5. Consider rollback if something fails

## Output Format

```markdown
## Refactor Plan: [title]

### Current State
[Brief description of how things work now]

### Target State
[Brief description of how things will work after]

### Affected Files
| File | Change Type | Dependencies |
|------|-------------|--------------|
| path | modify/create/delete | blocks X, blocked by Y |

### Execution Plan

#### Phase 1: Types and Interfaces
- [ ] Step 1.1: [action] in `file.ts`
- [ ] Verify: [how to check it worked]

#### Phase 2: Implementation
- [ ] Step 2.1: [action] in `file.ts`
- [ ] Verify: [how to check]

#### Phase 3: Tests
- [ ] Step 3.1: Update tests in `file.test.ts`
- [ ] Verify: Run `npm test`

#### Phase 4: Cleanup
- [ ] Remove deprecated code
- [ ] Update documentation

### Rollback Plan
If something fails:
1. [Step to undo]
2. [Step to undo]

### Risks
- [Potential issue and mitigation]
```

Shall I proceed with Phase 1?
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
tasks.db
*.log
nohup.out
23 changes: 23 additions & 0 deletions __mocks__/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const database = {
initialize: jest.fn(),
createTask: jest.fn(),
getAllTasks: jest.fn(),
getTaskById: jest.fn(),
updateTask: jest.fn(),
deleteTask: jest.fn(),
setTaskRating: jest.fn(),
getTaskRating: jest.fn(),
resetTaskRating: jest.fn(),
createLabel: jest.fn(),
getAllLabels: jest.fn(),
getLabelById: jest.fn(),
updateLabel: jest.fn(),
deleteLabel: jest.fn(),
assignLabelToTask: jest.fn(),
removeLabelFromTask: jest.fn(),
getTaskLabels: jest.fn(),
getTasksByLabel: jest.fn(),
closeDatabase: jest.fn(),
};

module.exports = database;
126 changes: 122 additions & 4 deletions database.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,38 @@ const initialize = () => {
description TEXT,
priority TEXT DEFAULT 'medium',
completed INTEGER DEFAULT 0,
rating INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Add rating column for existing databases that predate this feature
db.run(`ALTER TABLE tasks ADD COLUMN rating INTEGER DEFAULT 0`, (err) => {
if (err && !err.message.includes('duplicate column name')) {
console.error('Error adding rating column:', err);
}
});

// Create labels table
db.run(`
CREATE TABLE IF NOT EXISTS labels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
color TEXT DEFAULT '#808080',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);

// Create task_labels junction table for many-to-many relationship
db.run(`
CREATE TABLE IF NOT EXISTS task_labels (
task_id INTEGER NOT NULL,
label_id INTEGER NOT NULL,
PRIMARY KEY (task_id, label_id),
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE
)
`);
});
};

Expand All @@ -36,20 +64,98 @@ const getTaskById = (id, callback) => {
db.get(sql, [id], callback);
};

const updateTask = (id, title, description, priority, completed, callback) => {
const updateTask = (id, title, description, priority, completed, rating, callback) => {
const sql = `
UPDATE tasks
SET title = ?, description = ?, priority = ?, completed = ?, updated_at = CURRENT_TIMESTAMP
UPDATE tasks
SET title = COALESCE(?, title),
description = COALESCE(?, description),
priority = COALESCE(?, priority),
completed = COALESCE(?, completed),
rating = COALESCE(?, rating),
updated_at = CURRENT_TIMESTAMP
WHERE id = ?
`;
db.run(sql, [title, description, priority, completed, id], callback);
db.run(sql, [title ?? null, description ?? null, priority ?? null, completed ?? null, rating ?? null, id], callback);
};

const deleteTask = (id, callback) => {
const sql = `DELETE FROM tasks WHERE id = ?`;
db.run(sql, [id], callback);
};

const setTaskRating = (id, rating, callback) => {
const sql = `UPDATE tasks SET rating = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
db.run(sql, [rating, id], callback);
};

const getTaskRating = (id, callback) => {
const sql = `SELECT rating FROM tasks WHERE id = ?`;
db.get(sql, [id], callback);
};

const resetTaskRating = (id, callback) => {
const sql = `UPDATE tasks SET rating = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
db.run(sql, [id], callback);
};

// Label-related functions
const createLabel = (name, color, callback) => {
const sql = `INSERT INTO labels (name, color) VALUES (?, ?)`;
db.run(sql, [name, color], function(err) {
callback(err, this.lastID);
});
};

const getAllLabels = (callback) => {
const sql = `SELECT * FROM labels ORDER BY name ASC`;
db.all(sql, [], callback);
};

const getLabelById = (id, callback) => {
const sql = `SELECT * FROM labels WHERE id = ?`;
db.get(sql, [id], callback);
};

const updateLabel = (id, name, color, callback) => {
const sql = `UPDATE labels SET name = COALESCE(?, name), color = COALESCE(?, color) WHERE id = ?`;
db.run(sql, [name ?? null, color ?? null, id], callback);
};

const deleteLabel = (id, callback) => {
const sql = `DELETE FROM labels WHERE id = ?`;
db.run(sql, [id], callback);
};

const assignLabelToTask = (taskId, labelId, callback) => {
const sql = `INSERT OR IGNORE INTO task_labels (task_id, label_id) VALUES (?, ?)`;
db.run(sql, [taskId, labelId], callback);
};

const removeLabelFromTask = (taskId, labelId, callback) => {
const sql = `DELETE FROM task_labels WHERE task_id = ? AND label_id = ?`;
db.run(sql, [taskId, labelId], callback);
};

const getTaskLabels = (taskId, callback) => {
const sql = `
SELECT l.* FROM labels l
INNER JOIN task_labels tl ON l.id = tl.label_id
WHERE tl.task_id = ?
ORDER BY l.name ASC
`;
db.all(sql, [taskId], callback);
};

const getTasksByLabel = (labelId, callback) => {
const sql = `
SELECT t.* FROM tasks t
INNER JOIN task_labels tl ON t.id = tl.task_id
WHERE tl.label_id = ?
ORDER BY t.created_at DESC
`;
db.all(sql, [labelId], callback);
};

const closeDatabase = () => {
db.close();
};
Expand All @@ -61,5 +167,17 @@ module.exports = {
getTaskById,
updateTask,
deleteTask,
setTaskRating,
getTaskRating,
resetTaskRating,
createLabel,
getAllLabels,
getLabelById,
updateLabel,
deleteLabel,
assignLabelToTask,
removeLabelFromTask,
getTaskLabels,
getTasksByLabel,
closeDatabase
};
Loading