diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-09-07 11:32:41 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-09-07 11:32:41 +0200 |
| commit | 18a0f9c874aaa09c0f71252dad853c23f9511ed6 (patch) | |
| tree | 93103b83f6d0057c40f0bab9c9473bf04292e9c4 /src/lib/server/db/schema.ts | |
| parent | 113415ce357a9cea1759d0452ebae6352f8fe36b (diff) | |
Add projects with routines, urgency tracking and health scores
Projects group recurring routines (chores included) with an append-only
snapshot table (id, version) so edits never rewrite history; completions
reference the exact snapshot. Pure metrics compute due dates, urgency
buckets (ok/due/late/veryLate) and 0-100 health scores per routine,
project, and globally. Home page lists projects; project dashboard sorts
routines most-urgent first with one-tap completion and interval parser
inputs (1d/2w/3m/1y).
Diffstat (limited to 'src/lib/server/db/schema.ts')
| -rw-r--r-- | src/lib/server/db/schema.ts | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 31c2f65..23e10f5 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -1,4 +1,11 @@ -import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core'; +import { + sqliteTable, + text, + integer, + real, + primaryKey, + foreignKey, +} from 'drizzle-orm/sqlite-core'; export const categories = sqliteTable('categories', { id: integer('id').primaryKey({ autoIncrement: true }), @@ -26,3 +33,44 @@ export const references = sqliteTable('references', { unit: text('unit'), qualityScore: integer('quality_score'), }); + +export const projects = sqliteTable('projects', { + id: integer('id').primaryKey({ autoIncrement: true }), + name: text('name').notNull().unique(), + archived: integer('archived', { mode: 'boolean' }).notNull().default(false), +}); + +// Append-only snapshot table: an edit inserts a new row with version+1, the +// current routine is the row with the max version for its id. +export const routines = sqliteTable( + 'routines', + { + id: integer('id').notNull(), + version: integer('version').notNull(), + projectId: integer('project_id') + .notNull() + .references(() => projects.id, { onDelete: 'cascade' }), + name: text('name').notNull(), + frequencyDays: integer('frequency_days').notNull(), + archived: integer('archived', { mode: 'boolean' }).notNull().default(false), + createdAt: text('created_at').notNull(), + }, + (t) => [primaryKey({ columns: [t.id, t.version] })], +); + +export const routineCompletions = sqliteTable( + 'routine_completions', + { + id: integer('id').primaryKey({ autoIncrement: true }), + routineId: integer('routine_id').notNull(), + routineVersion: integer('routine_version').notNull(), + doneAt: text('done_at').notNull(), + note: text('note'), + }, + (t) => [ + foreignKey({ + columns: [t.routineId, t.routineVersion], + foreignColumns: [routines.id, routines.version], + }).onDelete('cascade'), + ], +); |
