fix: use integer instead of serial for taskNumber, add backfill on startup

serial caused db:push failure on existing tables. Now uses nullable
integer with app-level sequencing and startup backfill.
This commit is contained in:
2026-01-29 00:51:26 +00:00
parent 321ba2cadc
commit 76b9c61b09
3 changed files with 37 additions and 2 deletions

View File

@@ -3,7 +3,6 @@ import {
uuid,
text,
integer,
serial,
timestamp,
jsonb,
pgEnum,
@@ -41,7 +40,7 @@ export interface ProgressNote {
export const tasks = pgTable("tasks", {
id: uuid("id").defaultRandom().primaryKey(),
taskNumber: serial("task_number").notNull(),
taskNumber: integer("task_number"),
title: text("title").notNull(),
description: text("description"),
source: taskSourceEnum("source").notNull().default("donovan"),

View File

@@ -2,9 +2,38 @@ import { Elysia } from "elysia";
import { cors } from "@elysiajs/cors";
import { taskRoutes } from "./routes/tasks";
import { auth } from "./lib/auth";
import { db } from "./db";
import { tasks } from "./db/schema";
import { isNull, asc, sql } from "drizzle-orm";
const PORT = process.env.PORT || 3100;
// Backfill task numbers for existing tasks that don't have one
async function backfillTaskNumbers() {
const unnumbered = await db
.select()
.from(tasks)
.where(isNull(tasks.taskNumber))
.orderBy(asc(tasks.createdAt));
if (unnumbered.length === 0) return;
const maxNum = await db
.select({ max: sql<number>`COALESCE(MAX(${tasks.taskNumber}), 0)` })
.from(tasks);
let next = (maxNum[0]?.max ?? 0) + 1;
for (const task of unnumbered) {
await db
.update(tasks)
.set({ taskNumber: next++ })
.where(sql`${tasks.id} = ${task.id}`);
}
console.log(`Backfilled ${unnumbered.length} task numbers (${next - unnumbered.length} to ${next - 1})`);
}
backfillTaskNumbers().catch(console.error);
const app = new Elysia()
.use(
cors({

View File

@@ -119,6 +119,12 @@ export const taskRoutes = new Elysia({ prefix: "/api/tasks" })
const maxPos = await db
.select({ max: sql<number>`COALESCE(MAX(${tasks.position}), 0)` })
.from(tasks);
// Get next task number
const maxNum = await db
.select({ max: sql<number>`COALESCE(MAX(${tasks.taskNumber}), 0)` })
.from(tasks);
const nextNumber = (maxNum[0]?.max ?? 0) + 1;
const newTask = await db
.insert(tasks)
.values({
@@ -128,6 +134,7 @@ export const taskRoutes = new Elysia({ prefix: "/api/tasks" })
status: body.status || "queued",
priority: body.priority || "medium",
position: (maxPos[0]?.max ?? 0) + 1,
taskNumber: nextNumber,
progressNotes: [],
})
.returning();