diff --git a/server/index.ts b/server/index.ts index e0318b1..97ce54c 100644 --- a/server/index.ts +++ b/server/index.ts @@ -31,9 +31,12 @@ function err(message: string, status: number) { const TASK_FIELDS = ["title", "notes", "status", "project_id", "context", "waiting_for", "due_date", "defer_date", "priority", "estimate_min", "sort_order"]; const PROJECT_FIELDS = ["name", "status", "notes", "sort_order"]; +// Only these may be cleared to NULL; notes/title are NOT NULL and keep "". +const NULLABLE = new Set(["project_id", "context", "waiting_for", "due_date", "defer_date", "estimate_min"]); + function pick(body: Record, fields: string[]) { const out: Record = {}; - for (const f of fields) if (f in body) out[f] = body[f] === "" ? null : body[f]; + for (const f of fields) if (f in body) out[f] = body[f] === "" && NULLABLE.has(f) ? null : body[f]; return out; } @@ -166,6 +169,10 @@ Bun.serve({ fetch: (req) => handle(req).catch((e) => { console.error(e); + // Constraint violations are bad input, not server faults — 400 so + // offline clients drop the op instead of retrying it forever. + const errno = (e as { errno?: string }).errno ?? ""; + if (errno.startsWith("23")) return err(`constraint violation: ${(e as Error).message}`, 400); return err("internal error", 500); }), });