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:
@@ -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"),
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user