From 57a6f4bb390422e446e91eecb00c934463151b4d Mon Sep 17 00:00:00 2001 From: vidane Date: Sat, 2 May 2026 18:03:31 -0400 Subject: [PATCH] Add src/server/db/schema.ts --- src/server/db/schema.ts | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/server/db/schema.ts diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts new file mode 100644 index 0000000..be1805f --- /dev/null +++ b/src/server/db/schema.ts @@ -0,0 +1,62 @@ +import { pgTable, text, integer, timestamp, boolean, uuid, pgEnum } from 'drizzle-orm/pg-core'; +import { relations } from 'drizzle-orm'; + +// Enums +export const priorityEnum = pgEnum('priority', ['low', 'medium', 'high', 'urgent']); +export const statusEnum = pgEnum('status', ['todo', 'in_progress', 'done']); +export const recurrenceEnum = pgEnum('recurrence', ['daily', 'weekly', 'biweekly', 'monthly', 'yearly', 'none']); + +// Projects table +export const projects = pgTable('projects', { + id: uuid('id').defaultRandom().primaryKey(), + name: text('name').notNull(), + description: text('description').default(''), + color: text('color').default('#3b82f6'), // default blue + sortOrder: integer('sort_order').default(0), + createdAt: timestamp('created_at').defaultNow().notNull(), + updatedAt: timestamp('updated_at').defaultNow().notNull(), +}); + +// Tasks table +export const tasks = pgTable('tasks', { + id: uuid('id').defaultRandom().primaryKey(), + projectId: uuid('project_id').references(() => projects.id), + title: text('title').notNull(), + description: text('description').default(''), + completed: boolean('completed').default(false).notNull(), + priority: priorityEnum('priority').default('medium').notNull(), + dueDate: timestamp('due_date'), + status: statusEnum('status').default('todo').notNull(), + parentTaskId: uuid('parent_task_id').references(() => tasks.id), + recurrenceRule: recurrenceEnum('recurrence_rule').default('none').notNull(), + recurrenceInterval: integer('recurrence_interval').default(1).notNull(), + nextOccurrence: timestamp('next_occurrence'), + sortOrder: integer('sort_order').default(0), + createdAt: timestamp('created_at').defaultNow().notNull(), + updatedAt: timestamp('updated_at').defaultNow().notNull(), +}); + +// Relations +export const projectsRelations = relations(projects, ({ many }) => ({ + tasks: many(tasks), +})); + +export const tasksRelations = relations(tasks, ({ one, many }) => ({ + project: one(projects, { + fields: [tasks.projectId], + references: [projects.id], + }), + parentTask: one(tasks, { + fields: [tasks.parentTaskId], + references: [tasks.id], + }), + subtasks: many(tasks, { + relationName: 'subtasks', + }), +})); + +// Types +export type Project = typeof projects.$inferSelect; +export type NewProject = typeof projects.$inferInsert; +export type Task = typeof tasks.$inferSelect; +export type NewTask = typeof tasks.$inferInsert;