From 8fd2c0b5cf021c1566e533c997c2de4b91c8c4a5 Mon Sep 17 00:00:00 2001 From: mahlatseclayton Date: Wed, 29 Jul 2026 22:10:49 +0200 Subject: [PATCH] Database schema creation/data access layer/overdue calculation --- src/lib/db.ts | 2 +- src/lib/tasks.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/types.ts | 19 ++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/lib/tasks.ts create mode 100644 src/lib/types.ts diff --git a/src/lib/db.ts b/src/lib/db.ts index 48af1f0..0d458e9 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -11,7 +11,7 @@ db.exec( title TEXT NOT NULL, due_date TEXT NOT NULL, topic TEXT NOT NULL, - status TEXT CHECK(status IN ('To-Do','In-Progress','Completed')) NOT NULL DEFAULT 'to-do', + status TEXT CHECK(status IN ('To-Do','In-Progress','Complete')) NOT NULL DEFAULT 'to-do', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_Archived BOOLEAN NOT NULL DEFAULT 0 ) diff --git a/src/lib/tasks.ts b/src/lib/tasks.ts new file mode 100644 index 0000000..bee4daf --- /dev/null +++ b/src/lib/tasks.ts @@ -0,0 +1,68 @@ +import db from './db'; +import { Task, TaskStatus, computeIsOverdue } from './types'; +export function getTasks(sortBy: 'due_date' | 'topic' | 'status' = 'due_date'): Task[] { + + const validSortColumns = ['due_date', 'topic', 'status']; + const sortColumn = validSortColumns.includes(sortBy) ? sortBy : 'due_date'; + + const sql = `SELECT * FROM tasks WHERE is_archived = 0 ORDER BY ${sortColumn} ASC`; + const tasks = db.prepare(sql).all() as Task[]; + + return tasks.map(task => ({ + ...task, + is_overdue: computeIsOverdue(task.due_date, task.status) + })); +} + +export function createTask(task: { + title: string; + description?: string; + due_date: string; + topic: string; + status?: TaskStatus; +}) { + const stmt = db.prepare(` + INSERT INTO tasks (title, description, due_date, topic, status) + VALUES (?, ?, ?, ?, ?) + `); + + return stmt.run( + task.title, + task.description || '', + task.due_date, + task.topic, + task.status || 'Todo' + ); +} + + +export function updateTask( + id: number, + task: { + title: string; + description?: string; + due_date: string; + topic: string; + status: TaskStatus; + } +) { + const stmt = db.prepare(` + UPDATE tasks + SET title = ?, description = ?, due_date = ?, topic = ?, status = ? + WHERE id = ? + `); + + return stmt.run( + task.title, + task.description || '', + task.due_date, + task.topic, + task.status, + id + ); +} + + +export function archiveTask(id: number) { + return db.prepare(`UPDATE tasks SET is_archived = 1 WHERE id = ?`).run(id); +} diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..78dd7f6 --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,19 @@ +export type TaskStatus = 'Todo' | 'In-Progress' | 'Complete'; + +export interface Task { + id: number; + title: string; + description: string; + due_date: string; // ISO Format YYYY-MM-DD + topic: string; + status: TaskStatus; + is_archived: number; // 0 or 1 + created_at: string; + is_overdue?: boolean; // Derived field +} + +export function computeIsOverdue(dueDateStr: string, status: TaskStatus): boolean { + if (status === 'Complete') return false; + const today = new Date().toISOString().split('T')[0]; + return dueDateStr < today; +} \ No newline at end of file