Consolidate server utilities into shared module

- Add lib/server/utils/normalize.ts with normalizeTicker, normalizeTagsOrNull, nowIso, todayIso
- Add lib/server/utils/validation.ts with asRecord, asBoolean, asStringArray, asEnum
- Add lib/server/utils/index.ts re-exporting all utilities
- Remove duplicate lib/server/utils.ts (old file)
- Update all repos and files to use shared utilities
- Remove redundant ?? '' from normalizeTicker calls
- Update watchlist.ts to use normalizeTagsOrNull for null-return tags
This commit is contained in:
2026-03-15 15:56:16 -04:00
parent edf1cfb421
commit 5f0abbb007
14 changed files with 193 additions and 127 deletions

View File

@@ -3,6 +3,7 @@ import type { Task, TaskStage, TaskStageContext, TaskStageEvent, TaskStatus, Tas
import { db } from '@/lib/server/db';
import { taskRun, taskStageEvent } from '@/lib/server/db/schema';
import { buildTaskNotification } from '@/lib/server/task-notifications';
import { nowIso } from '@/lib/server/utils';
type TaskRow = typeof taskRun.$inferSelect;
type TaskStageEventRow = typeof taskStageEvent.$inferSelect;
@@ -110,7 +111,7 @@ async function insertTaskStageEvent(executor: InsertExecutor, input: EventInsert
}
export async function createTaskRunRecord(input: CreateTaskInput) {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const [row] = await tx
@@ -219,7 +220,7 @@ async function attemptAtomicInsert(
}
export async function createTaskRunRecordAtomic(input: CreateTaskInput): Promise<AtomicCreateResult> {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const result = await attemptAtomicInsert(tx, input, now);
@@ -235,7 +236,7 @@ export async function setTaskWorkflowRunId(taskId: string, workflowRunId: string
.update(taskRun)
.set({
workflow_run_id: workflowRunId,
updated_at: new Date().toISOString()
updated_at: nowIso()
})
.where(eq(taskRun.id, taskId));
}
@@ -313,7 +314,7 @@ export async function findInFlightTaskByResourceKey(
}
export async function markTaskRunning(taskId: string) {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const [row] = await tx
@@ -354,7 +355,7 @@ export async function updateTaskStage(
detail: string | null = null,
context: TaskStageContext | null = null
) {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const [current] = await tx
@@ -403,7 +404,7 @@ export async function completeTask(
result: Record<string, unknown>,
completion: TaskCompletionState = {}
) {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const [row] = await tx
@@ -445,7 +446,7 @@ export async function markTaskFailure(
stage: TaskStage = 'failed',
failure: TaskCompletionState = {}
) {
const now = new Date().toISOString();
const now = nowIso();
return await db.transaction(async (tx) => {
const [row] = await tx
@@ -513,7 +514,7 @@ export async function setTaskStatusFromWorkflow(
return toTask(current);
}
const now = new Date().toISOString();
const now = nowIso();
const [row] = await tx
.update(taskRun)
.set({
@@ -551,7 +552,7 @@ export async function updateTaskNotificationState(
userId: string,
input: UpdateTaskNotificationStateInput
) {
const now = new Date().toISOString();
const now = nowIso();
const patch: Partial<typeof taskRun.$inferInsert> = {
updated_at: now
};