compassmock/src/app/actions/baselines.ts
Nicholai aa6230c9d4 feat(schedule): add BuilderTrend parity enhancements
Add two-level tab structure (Schedule/Baseline/Workday Exceptions),
calendar view, enhanced list view with progress rings and initials
avatars, split-pane gantt view, workday exception management with
business day integration, and baseline snapshot comparison.
2026-01-23 20:14:09 -07:00

92 lines
2.5 KiB
TypeScript
Executable File

"use server"
import { getCloudflareContext } from "@opennextjs/cloudflare"
import { getDb } from "@/db"
import {
scheduleBaselines,
scheduleTasks,
taskDependencies,
} from "@/db/schema"
import { eq, asc } from "drizzle-orm"
import { revalidatePath } from "next/cache"
import type { ScheduleBaselineData } from "@/lib/schedule/types"
export async function getBaselines(
projectId: string
): Promise<ScheduleBaselineData[]> {
const { env } = await getCloudflareContext()
const db = getDb(env.DB)
return await db
.select()
.from(scheduleBaselines)
.where(eq(scheduleBaselines.projectId, projectId))
}
export async function createBaseline(
projectId: string,
name: string
): Promise<{ success: boolean; error?: string }> {
try {
const { env } = await getCloudflareContext()
const db = getDb(env.DB)
const tasks = await db
.select()
.from(scheduleTasks)
.where(eq(scheduleTasks.projectId, projectId))
.orderBy(asc(scheduleTasks.sortOrder))
const deps = await db.select().from(taskDependencies)
const taskIds = new Set(tasks.map((t) => t.id))
const projectDeps = deps.filter(
(d) => taskIds.has(d.predecessorId) && taskIds.has(d.successorId)
)
const snapshot = JSON.stringify({ tasks, dependencies: projectDeps })
await db.insert(scheduleBaselines).values({
id: crypto.randomUUID(),
projectId,
name,
snapshotData: snapshot,
createdAt: new Date().toISOString(),
})
revalidatePath(`/dashboard/projects/${projectId}/schedule`)
return { success: true }
} catch (error) {
console.error("Failed to create baseline:", error)
return { success: false, error: "Failed to create baseline" }
}
}
export async function deleteBaseline(
baselineId: string
): Promise<{ success: boolean; error?: string }> {
try {
const { env } = await getCloudflareContext()
const db = getDb(env.DB)
const [existing] = await db
.select()
.from(scheduleBaselines)
.where(eq(scheduleBaselines.id, baselineId))
.limit(1)
if (!existing) return { success: false, error: "Baseline not found" }
await db
.delete(scheduleBaselines)
.where(eq(scheduleBaselines.id, baselineId))
revalidatePath(
`/dashboard/projects/${existing.projectId}/schedule`
)
return { success: true }
} catch (error) {
console.error("Failed to delete baseline:", error)
return { success: false, error: "Failed to delete baseline" }
}
}