33import { revalidatePath } from "next/cache" ;
44import { Task , TaskDraft } from "@/types/home/codev" ;
55import { createClientServerComponent } from "@/utils/supabase/server" ;
6+ import { createNotificationAction } from "@/lib/actions/notification.actions" ;
67
78interface CodevMember {
89 id : string ;
@@ -247,8 +248,10 @@ export const updateTask = async (
247248 const rawDeadline = formData . get ( "deadline" ) ?. toString ( ) ;
248249 const deadline = rawDeadline === "" || rawDeadline === "null" ? null : rawDeadline ;
249250
251+ const title = formData . get ( "title" ) ?. toString ( ) ;
252+
250253 const updateData = {
251- title : formData . get ( " title" ) ?. toString ( ) ,
254+ title : title ,
252255 description : formData . get ( "description" ) ?. toString ( ) ,
253256 priority : formData . get ( "priority" ) ?. toString ( ) ,
254257 difficulty : formData . get ( "difficulty" ) ?. toString ( ) ,
@@ -264,9 +267,10 @@ export const updateTask = async (
264267 updated_at : new Date ( ) . toISOString ( ) ,
265268 } ;
266269
270+ // 1. Fetch existing task to check current assignee
267271 const { data : existingTask , error : fetchError } = await supabase
268272 . from ( "tasks" )
269- . select ( "* " )
273+ . select ( "codev_id, title, kanban_column_id " )
270274 . eq ( "id" , taskId )
271275 . single ( ) ;
272276
@@ -275,6 +279,7 @@ export const updateTask = async (
275279 return { success : false , error : "Could not find task to update" } ;
276280 }
277281
282+ // 2. Perform the update
278283 const { error : updateError } = await supabase
279284 . from ( "tasks" )
280285 . update ( {
@@ -288,6 +293,32 @@ export const updateTask = async (
288293 return { success : false , error : updateError . message } ;
289294 }
290295
296+ // 3. NOTIFICATION LOGIC: Trigger if assignee changed and isn't null
297+ if ( codev_id && codev_id !== existingTask . codev_id ) {
298+ // Get current user to avoid self-notification
299+ const { data : { user } } = await supabase . auth . getUser ( ) ;
300+
301+ if ( user && user . id !== codev_id ) {
302+ // Fetch project info to build the action URL
303+ const { data : colData } = await supabase
304+ . from ( "kanban_columns" )
305+ . select ( "board_id, kanban_boards(project_id)" )
306+ . eq ( "id" , existingTask . kanban_column_id )
307+ . single ( ) ;
308+
309+ await createNotificationAction ( {
310+ recipientId : codev_id ,
311+ title : "Task Assigned" ,
312+ message : `You've been assigned to: ${ title || existingTask . title } ` ,
313+ type : "task" ,
314+ priority : "normal" ,
315+ projectId : ( colData ?. kanban_boards as any ) ?. project_id ,
316+ actionUrl : `/home/kanban/${ ( colData ?. kanban_boards as any ) ?. project_id } /${ colData ?. board_id } ?taskId=${ taskId } ` ,
317+ metadata : { taskId }
318+ } ) ;
319+ }
320+ }
321+
291322 return { success : true } ;
292323 } catch ( error ) {
293324 console . error ( "Update task error:" , error ) ;
@@ -989,6 +1020,25 @@ export const promoteDraft = async (
9891020 return { success : false , error : createError . message } ;
9901021 }
9911022
1023+ // Step 3.5: Trigger Notification if assignee exists in the draft
1024+ if ( draft . codev_id ) {
1025+ // Get current user to avoid self-notification
1026+ const { data : { user } } = await supabase . auth . getUser ( ) ;
1027+
1028+ if ( user && user . id !== draft . codev_id ) {
1029+ await createNotificationAction ( {
1030+ recipientId : draft . codev_id ,
1031+ title : "Task Assigned (from Draft)" ,
1032+ message : `The draft "${ draft . title } " has been published and assigned to you.` ,
1033+ type : "task" ,
1034+ priority : "normal" ,
1035+ projectId : draft . project_id ,
1036+ actionUrl : `/home/kanban/${ draft . project_id } /${ draft . intended_column_id } ?taskId=${ newTask . id } ` ,
1037+ metadata : { taskId : newTask . id }
1038+ } ) ;
1039+ }
1040+ }
1041+
9921042 // Step 4: Delete the draft
9931043 const { error : deleteError } = await supabase
9941044 . from ( "task_drafts" )
0 commit comments