@@ -4,13 +4,25 @@ import { revalidatePath } from "next/cache";
44import { Task } from "@/types/home/codev" ;
55import { createClientServerComponent } from "@/utils/supabase/server" ;
66
7+ // =============================================================================
8+ // TYPE DEFINITIONS
9+ // =============================================================================
10+
711interface CodevMember {
812 id : string ;
913 first_name : string ;
1014 last_name : string ;
1115 image_url ?: string | null ;
1216}
1317
18+ // =============================================================================
19+ // TASK OPERATIONS
20+ // =============================================================================
21+
22+ /**
23+ * Updates a task's column assignment (for drag-and-drop)
24+ * Line 18-37
25+ */
1426export const updateTaskColumnId = async (
1527 taskId : string ,
1628 newColumnId : string ,
@@ -35,6 +47,11 @@ export const updateTaskColumnId = async (
3547 }
3648} ;
3749
50+ /**
51+ * Fetches available team members for task assignment
52+ * Prioritizes team leader, then sorts members alphabetically
53+ * Line 39-107
54+ */
3855export const fetchAvailableMembers = async (
3956 projectId : string ,
4057) : Promise < CodevMember [ ] > => {
@@ -95,12 +112,19 @@ export const fetchAvailableMembers = async (
95112 return members . sort ( ( a , b ) => a . first_name . localeCompare ( b . first_name ) ) ;
96113} ;
97114
115+ /**
116+ * Creates a new task with all fields including deadline
117+ * ENHANCED: Added deadline field support
118+ * created_at is auto-generated by database default
119+ * Line 109-178
120+ */
98121export const createNewTask = async (
99122 formData : FormData ,
100123) : Promise < { success : boolean ; error ?: string } > => {
101124 const supabase = await createClientServerComponent ( ) ;
102125
103126 try {
127+ // Extract all form fields
104128 const title = formData . get ( "title" ) ?. toString ( ) ;
105129 const description = formData . get ( "description" ) ?. toString ( ) ;
106130 const priority = formData . get ( "priority" ) ?. toString ( ) ;
@@ -117,11 +141,23 @@ export const createNewTask = async (
117141 . filter ( Boolean ) ;
118142 const skill_category_id = formData . get ( "skill_category_id" ) ?. toString ( ) ;
119143 const created_by = formData . get ( "created_by" ) ?. toString ( ) ;
120-
144+
145+ // ENHANCED: Extract deadline field (nullable)
146+ const rawDeadline = formData . get ( "deadline" ) ?. toString ( ) ;
147+ const deadline = rawDeadline && rawDeadline !== "" && rawDeadline !== "null"
148+ ? new Date ( rawDeadline ) . toISOString ( )
149+ : null ;
150+
151+ // Validate required fields
121152 if ( ! title || ! kanban_column_id || ! skill_category_id ) {
122- return { success : false , error : "Required fields are missing (title, column, and skill category)" } ;
153+ return {
154+ success : false ,
155+ error : "Required fields are missing (title, column, and skill category)"
156+ } ;
123157 }
124158
159+ // Insert task with deadline support
160+ // Note: created_at is auto-generated by database default (now())
125161 const { error } = await supabase . from ( "tasks" ) . insert ( [
126162 {
127163 title,
@@ -136,6 +172,7 @@ export const createNewTask = async (
136172 sidekick_ids,
137173 skill_category_id,
138174 created_by,
175+ deadline, // ENHANCED: Include deadline field
139176 } ,
140177 ] ) ;
141178
@@ -173,20 +210,34 @@ export const createNewTask = async (
173210 }
174211} ;
175212
213+ /**
214+ * Updates an existing task with all fields including deadline
215+ * ENHANCED: Added deadline field support
216+ * Line 180-252
217+ */
176218export const updateTask = async (
177219 formData : FormData ,
178220 taskId : string ,
179221) : Promise < { success : boolean ; error ?: string } > => {
180222 const supabase = await createClientServerComponent ( ) ;
181223
182224 try {
183- // Handle BOTH UUID fields properly
225+ // Handle UUID fields properly (codev_id, skill_category_id)
184226 const rawCodevId = formData . get ( "codev_id" ) ?. toString ( ) ;
185227 const codev_id = rawCodevId === "" || rawCodevId === "null" ? null : rawCodevId ;
186228
187229 const rawSkillCategoryId = formData . get ( "skill_category_id" ) ?. toString ( ) ;
188- const skill_category_id = rawSkillCategoryId === "" || rawSkillCategoryId === "null" ? null : rawSkillCategoryId ;
230+ const skill_category_id = rawSkillCategoryId === "" || rawSkillCategoryId === "null"
231+ ? null
232+ : rawSkillCategoryId ;
233+
234+ // ENHANCED: Handle deadline field properly
235+ const rawDeadline = formData . get ( "deadline" ) ?. toString ( ) ;
236+ const deadline = rawDeadline && rawDeadline !== "" && rawDeadline !== "null"
237+ ? new Date ( rawDeadline ) . toISOString ( )
238+ : null ;
189239
240+ // Prepare update data
190241 const updateData = {
191242 title : formData . get ( "title" ) ?. toString ( ) ,
192243 description : formData . get ( "description" ) ?. toString ( ) ,
@@ -200,9 +251,11 @@ export const updateTask = async (
200251 : [ ] ,
201252 skill_category_id : skill_category_id ,
202253 codev_id : codev_id ,
254+ deadline : deadline , // ENHANCED: Include deadline in updates
203255 updated_at : new Date ( ) . toISOString ( ) ,
204256 } ;
205257
258+ // Validate task exists before updating
206259 const { data : existingTask , error : fetchError } = await supabase
207260 . from ( "tasks" )
208261 . select ( "*" )
@@ -214,6 +267,7 @@ export const updateTask = async (
214267 return { success : false , error : "Could not find task to update" } ;
215268 }
216269
270+ // Perform update
217271 const { error : updateError } = await supabase
218272 . from ( "tasks" )
219273 . update ( {
@@ -237,6 +291,10 @@ export const updateTask = async (
237291 }
238292} ;
239293
294+ /**
295+ * Deletes a task and revalidates the kanban board path
296+ * Line 254-295
297+ */
240298export const deleteTask = async (
241299 taskId : string ,
242300) : Promise < { success : boolean ; error ?: string } > => {
@@ -288,6 +346,14 @@ export const deleteTask = async (
288346 }
289347} ;
290348
349+ // =============================================================================
350+ // COLUMN OPERATIONS
351+ // =============================================================================
352+
353+ /**
354+ * Creates a new kanban column with auto-incremented position
355+ * Line 297-333
356+ */
291357export const createNewColumn = async (
292358 columnName : string ,
293359 boardId : string ,
@@ -332,6 +398,10 @@ export const createNewColumn = async (
332398 }
333399} ;
334400
401+ /**
402+ * Updates column position (for drag-and-drop column reordering)
403+ * Line 335-361
404+ */
335405export const updateColumnPosition = async (
336406 columnId : string ,
337407 newPosition : number ,
@@ -361,6 +431,10 @@ export const updateColumnPosition = async (
361431 }
362432} ;
363433
434+ /**
435+ * Deletes a kanban column
436+ * Line 363-382
437+ */
364438export const deleteColumn = async (
365439 columnId : string ,
366440) : Promise < { success : boolean ; error ?: string } > => {
@@ -384,6 +458,10 @@ export const deleteColumn = async (
384458 }
385459} ;
386460
461+ /**
462+ * Updates column name
463+ * Line 384-408
464+ */
387465export const updateColumnName = async (
388466 columnId : string ,
389467 newName : string ,
@@ -412,14 +490,24 @@ export const updateColumnName = async (
412490 }
413491} ;
414492
493+ // =============================================================================
494+ // POINTS & LEVELING SYSTEM
495+ // =============================================================================
496+
497+ /**
498+ * Internal function to update developer levels based on points
499+ * Calculates level for each skill category based on accumulated points
500+ * Line 410-458
501+ */
415502const updateDeveloperLevels = async ( codevId ?: string ) => {
416503 if ( ! codevId ) return ;
417504
418505 const supabase = await createClientServerComponent ( ) ;
419506
420507 const { data : pointsData , error : pointsError } = await supabase
421508 . from ( "codev_points" )
422- . select ( "skill_category_id, points" ) ;
509+ . select ( "skill_category_id, points" )
510+ . eq ( "codev_id" , codevId ) ;
423511
424512 if ( pointsError ) {
425513 console . error ( "Error fetching points:" , pointsError ) ;
@@ -458,7 +546,15 @@ const updateDeveloperLevels = async (codevId?: string) => {
458546 }
459547} ;
460548
461- // RESOLVED: Comprehensive completeTask implementation with RPC fallback
549+ /**
550+ * Completes a task with comprehensive point distribution
551+ * - Archives task instead of deleting for data preservation
552+ * - Awards 100% points to primary assignee
553+ * - Awards 50% points to sidekicks
554+ * - Updates developer levels for all participants
555+ * - Falls back to manual implementation if RPC function unavailable
556+ * Line 460-631
557+ */
462558export const completeTask = async (
463559 task : Task ,
464560) : Promise < { success : boolean ; error ?: string } > => {
@@ -637,6 +733,15 @@ export const completeTask = async (
637733 }
638734} ;
639735
736+ // =============================================================================
737+ // BATCH OPERATIONS
738+ // =============================================================================
739+
740+ /**
741+ * Batch updates multiple tasks' column assignments
742+ * Used for optimizing drag-and-drop performance
743+ * Line 633-657
744+ */
640745export async function batchUpdateTasks (
641746 updates : Array < { taskId : string ; newColumnId : string } > ,
642747) {
@@ -666,6 +771,14 @@ export async function batchUpdateTasks(
666771 }
667772}
668773
774+ // =============================================================================
775+ // TASK SPECIFIC OPERATIONS
776+ // =============================================================================
777+
778+ /**
779+ * Updates a task's PR link
780+ * Line 659-700
781+ */
669782export async function updateTaskPRLink ( taskId : string , prLink : string ) {
670783 const supabase = await createClientServerComponent ( ) ;
671784 try {
@@ -716,6 +829,10 @@ export async function updateTaskPRLink(taskId: string, prLink: string) {
716829 }
717830}
718831
832+ /**
833+ * Unarchives a previously archived task
834+ * Line 702-743
835+ */
719836export async function unarchiveTask ( taskId : string ) {
720837 const supabase = await createClientServerComponent ( ) ;
721838 try {
0 commit comments