Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions app/api/projects/[id]/milestones/[milestoneId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export async function PATCH(
const user = await getCurrentUser()
if (!user?.id) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

const { milestoneId } = await params
const { id, milestoneId } = await params
try {
const { completed } = await request.json()
const milestone = await toggleMilestone(milestoneId, Boolean(completed))
const milestone = await toggleMilestone(milestoneId, id, user.id, Boolean(completed))
if (!milestone) return NextResponse.json({ error: 'Not found' }, { status: 404 })
return NextResponse.json({ milestone })
} catch (err) {
Expand All @@ -28,9 +28,10 @@ export async function DELETE(
const user = await getCurrentUser()
if (!user?.id) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

const { milestoneId } = await params
const { id, milestoneId } = await params
try {
await deleteMilestone(milestoneId)
const deleted = await deleteMilestone(milestoneId, id, user.id)
if (!deleted) return NextResponse.json({ error: 'Not found' }, { status: 404 })
return NextResponse.json({ ok: true })
} catch (err) {
console.error('[milestones/id] DELETE error:', err)
Expand Down
44 changes: 35 additions & 9 deletions lib/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1044,27 +1044,53 @@ export async function createMilestone(data: {
return result[0] as ProjectMilestone
}

export async function toggleMilestone(id: string, completed: boolean): Promise<ProjectMilestone | null> {
export async function toggleMilestone(
id: string,
projectId: string,
userId: string,
completed: boolean,
): Promise<ProjectMilestone | null> {
const sql = getDb()
const result = completed
? await sql`
UPDATE project_milestones
UPDATE project_milestones AS m
SET completed = true, completed_at = NOW()
WHERE id = ${id}
RETURNING *
FROM projects AS p
WHERE m.id = ${id}
AND m.project_id = ${projectId}
AND p.id = m.project_id
AND p.user_id = ${userId}
RETURNING m.*
`
: await sql`
UPDATE project_milestones
UPDATE project_milestones AS m
SET completed = false, completed_at = NULL
WHERE id = ${id}
RETURNING *
FROM projects AS p
WHERE m.id = ${id}
AND m.project_id = ${projectId}
AND p.id = m.project_id
AND p.user_id = ${userId}
RETURNING m.*
`
return (result[0] as ProjectMilestone) || null
}

export async function deleteMilestone(id: string): Promise<void> {
export async function deleteMilestone(
id: string,
projectId: string,
userId: string,
): Promise<boolean> {
const sql = getDb()
await sql`DELETE FROM project_milestones WHERE id = ${id}`
const result = await sql`
DELETE FROM project_milestones AS m
USING projects AS p
WHERE m.id = ${id}
AND m.project_id = ${projectId}
AND p.id = m.project_id
AND p.user_id = ${userId}
RETURNING m.id
`
return result.length > 0
}

export async function seedDefaultMilestones(projectId: string): Promise<void> {
Expand Down
Loading