o
    "i<?                     @   s   d Z ddlZddlmZmZmZmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZ eeZG dd	 d	ee	ZG d
d dee	ZG dd dZdedefddZdS )ze
Annotation Task Manager Service
Manages annotation task creation, assignment, and workflow tracking
    N)OptionalListDictAny)datetime)Enum)Session)and_funccasec                   @       e Zd ZdZdZdZdZdZdS )
TaskStatuszAnnotation task statuspendingin_progress	completedreviewedN)__name__
__module____qualname____doc__PENDINGIN_PROGRESS	COMPLETEDREVIEWED r   r   V/lsinfo/ai/hellotax_ai/training_center/backend/app/services/annotation_task_manager.pyr          r   c                   @   r   )TaskPriorityzTask priority levelslowmediumhighurgentN)r   r   r   r   LOWMEDIUMHIGHURGENTr   r   r   r   r      r   r   c                   @   s$  e Zd ZdZdefddZejddddfdededed	ed
ede	e
 de	e dede	e deeef fddZdedededeeef fddZdedededeeef fddZdedeeef dedeeef fddZ	d6ded ed!ed"ed#edeeef fd$d%Z	d7dede	e deeeef  fd&d'Z		d8d	e	e d
e	e deeeef  fd(d)Zd*ee d ed!ed#ed"edeeeef  fd+d,Zd*ee d-ee dedeeef fd.d/Z					d9d0e	e
 d1e	e
 d"e	e d	e	e d
e	e deeef fd2d3Zdeeef fd4d5ZdS ):AnnotationTaskManagerz"Annotation task management servicedbc                 C   s
   || _ d S Nr'   )selfr'   r   r   r   __init__"   s   
zAnnotationTaskManager.__init__Ntitledescriptioncontent	task_typeprioritydeadlineassigned_to
created_bymetadatareturnc
                 C   sr   ddl m}
 |
||||tj|||||	pi d
}| j| | j  | j| t	d|j
 d|  | |S )a  
        Create annotation task

        Args:
            title: Task title
            description: Task description
            content: Content to annotate
            task_type: Type of annotation (labeling, review, qa, etc.)
            priority: Task priority
            deadline: Task deadline
            assigned_to: Expert user ID
            created_by: Creator user ID
            metadata: Additional metadata

        Returns:
            Created task data
        r   AnnotationTask)
r,   r-   r.   r/   statusr0   r1   r2   r3   	meta_datazCreated annotation task z: )
app.modelsr7   r   r   r'   addcommitrefreshloggerinfoid_task_to_dict)r*   r,   r-   r.   r/   r0   r1   r2   r3   r4   r7   taskr   r   r   create_task%   s$   

z!AnnotationTaskManager.create_tasktask_id	expert_idassigned_byc                 C   s   ddl m} | j||j|k|jdk }|s"td| d||_	||_
|jtjkr2tj|_| j  | j| td| d|  | |S )z
        Assign task to expert

        Args:
            task_id: Task ID
            expert_id: Expert user ID
            assigned_by: Assigner user ID

        Returns:
            Updated task data
        r   r6   FTask 
 not foundzAssigned task z to expert )r:   r7   r'   queryfilterr@   
is_deletedfirst
ValueErrorr2   rF   r8   r   r   r   r<   r=   r>   r?   rA   )r*   rD   rE   rF   r7   rB   r   r   r   assign_taskX   s"   

z!AnnotationTaskManager.assign_taskr8   
updated_byc                 C   s   ddl m} | j||j|k|jdk }|s"td| d||_	t
 |_|tjkr5t
 |_n
|tjkr?t
 |_| j  | j| td| d|  | |S )zUpdate task statusr   r6   FrG   rH   zUpdated task z status to )r:   r7   r'   rI   rJ   r@   rK   rL   rM   r8   r   utcnow
updated_atr   r   completed_atr   reviewed_atr<   r=   r>   r?   rA   )r*   rD   r8   rO   r7   rB   r   r   r   update_status   s&   





z#AnnotationTaskManager.update_statusannotation_datasubmitted_byc                 C   s   ddl m} | j||j|k|jdk }|s"td| d||_	t
j|_t |_| j  | j| td|  | |S )zSubmit annotation resultr   r6   FrG   rH   zSubmitted annotation for task )r:   r7   r'   rI   rJ   r@   rK   rL   rM   rU   r   r   r8   r   rP   rR   r<   r=   r>   r?   rA   )r*   rD   rU   rV   r7   rB   r   r   r   submit_annotation   s    


z'AnnotationTaskManager.submit_annotationTquality_scorefeedbackreviewed_byapprovedc                 C   s   ddl m} | j||j|k|jdk }|s"td| d|j	t
jkr4td| d|j	 d||_||_||_||_t |_|rJt
jnt
j|_	| j  | j| td| d	| d
|  | |S )zAdd quality review and feedbackr   r6   FrG   rH   z1 must be in completed status to review (current: )zAdded review for task z: score=, approved=)r:   r7   r'   rI   rJ   r@   rK   rL   rM   r8   r   r   rX   r[   reviewer_feedbackrZ   r   rP   rS   r   r   r<   r=   r>   r?   rA   )r*   rD   rX   rY   rZ   r[   r7   rB   r   r   r   
add_review   s*   	


z AnnotationTaskManager.add_reviewc                    sn   ddl m}  j||j|k|jdk}|r ||j|k}||j	
 |j  } fdd|D S )zGet tasks assigned to expertr   r6   Fc                       g | ]}  |qS r   rA   .0rB   r*   r   r   
<listcomp>       z=AnnotationTaskManager.get_tasks_by_expert.<locals>.<listcomp>)r:   r7   r'   rI   rJ   r2   rK   r8   order_byr0   descr1   ascall)r*   rE   r8   r7   rI   tasksr   rd   r   get_tasks_by_expert   s   z)AnnotationTaskManager.get_tasks_by_expertc                    s   ddl m}  j||jtjk|j	d}|r"||j
|k}|r,||j|k}||j |j  } fdd|D S )zGet unassigned tasksr   r6   Nc                    r`   r   ra   rb   rd   r   r   re   
  rf   z=AnnotationTaskManager.get_available_tasks.<locals>.<listcomp>)r:   r7   r'   rI   rJ   r8   r   r   r2   is_r/   r0   rg   rh   
created_atri   rj   )r*   r/   r0   r7   rI   rk   r   rd   r   get_available_tasks   s    

z)AnnotationTaskManager.get_available_taskstask_idsc                    s$  ddl m} j||j||jdk }t	|t	|kr8dd |D   fdd|D }t
d| d	d |D }	|	rHt
d
|	 t }
|D ]}||_||_||_||_|
|_|rdtjntj|_qNj  |D ]}j| qptdt	| d| d|  fdd|D S )z%Batch add reviews for completed tasksr   r6   Fc                 S      h | ]}|j qS r   r@   rb   r   r   r   	<setcomp>      z5AnnotationTaskManager.batch_review.<locals>.<setcomp>c                       g | ]}| vr|qS r   r   rc   rD   	found_idsr   r   re         z6AnnotationTaskManager.batch_review.<locals>.<listcomp>Tasks not found: c                 S   s   g | ]}|j tjkr|jqS r   )r8   r   r   r@   rb   r   r   r   re   !  s    zTasks not completed: zBatch reviewed z tasks: score=r]   c                    r`   r   ra   rb   rd   r   r   re   5  rf   )r:   r7   r'   rI   rJ   r@   in_rK   rj   lenrM   r   rP   rX   r[   r^   rZ   rS   r   r   r   r8   r<   r=   r>   r?   )r*   rp   rX   rY   r[   rZ   r7   rk   missinginvalid_tasksrS   rB   r   )rx   r*   r   batch_review  s:   	

z"AnnotationTaskManager.batch_reviewreviewer_idsc                    s  ddl m} |sdg iS |std| j||j||jdk	 }t
|t
|krDdd |D   fdd	|D }td
| | j|jt|jd|j||jtjk|j	 }dd |D fdd|D }g }	|D ]*}
t||jd}||
_||
_|
jtjkrtj|
_||  d7  < |	|
j|d qy| j  |D ]}
| j|
 qtdt
| d d|	iS )z7Assign tasks to reviewers by least in-progress workloadr   r6   assignedzReviewer list is emptyFc                 S   rq   r   rr   rb   r   r   r   rs   K  rt   z;AnnotationTaskManager.assign_by_workload.<locals>.<setcomp>c                    ru   r   r   rv   rw   r   r   re   L  ry   z<AnnotationTaskManager.assign_by_workload.<locals>.<listcomp>rz   countc                 S   s   i | ]}|j |jqS r   )r2   r   rc   rowr   r   r   
<dictcomp>W  rf   z<AnnotationTaskManager.assign_by_workload.<locals>.<dictcomp>c                    s   i | ]	}|  |d qS )r   )get)rc   reviewer_id)workload_mapr   r   r   X  s    )key   )rD   r2   z	Assigned z tasks by workload)r:   r7   rM   r'   rI   rJ   r@   r{   rK   rj   r|   r2   r
   r   labelr8   r   r   group_byminr   rF   r   appendr<   r=   r>   r?   )r*   rp   r   rF   r7   rk   r}   workload_rows	workloadsassignmentsrB   r   r   )rx   r   r   assign_by_workload7  sR   



z(AnnotationTaskManager.assign_by_workload
start_timeend_timec              
   C   sv  ddl m} |jtjk|jdkg}|r||j|k |r%||j|k |r/||j|k |r9||j	|k |rC||j
|k | jt|jdtt|jddfddd	t|jd
j|  }| jttd|j|j dttt|jd|j|jkdfdddj|  }	| j|jdt|jdt|jdj| |j}
|
t|j  ! }| j|j	t|jdj| |j	! }| j|j
t|jdj| |j
! }t"|j#pdt"|j$p
dt%|j&pddt"|	j'pdt%|	j(p!dddd |D dd |D dd |D ddS )zGet review analytics metricsr   r6   Favg_quality_scoreTg      ?g        )else_approval_ratetotal_reviewsepochavg_review_secondsNr   overdue_countrZ   review_countr   )r   r   r   )r   r   c                 S   s*   g | ]}|j t|jt|jpd dqS )r   )rZ   r   r   )rZ   intr   floatr   r   r   r   r   re     s    z>AnnotationTaskManager.get_review_analytics.<locals>.<listcomp>c                 S      g | ]}|j t|jd qS ))r/   r   )r/   r   r   r   r   r   r   re         c                 S   r   ))r0   r   )r0   r   r   r   r   r   r   re     r   )r/   r0   )quality_metricsefficiency_metricsreviewer_rankingdistribution))r:   r7   r8   r   r   rK   r   rS   rZ   r/   r0   r'   rI   r
   avgrX   r   r   r[   rm   r   r@   rJ   oneextractrR   sumr	   r1   isnotr   rg   rh   rj   r   r   r   r   r   r   r   )r*   r   r   rZ   r/   r0   r7   base_filtersquality_rowefficiency_rowreviewer_queryreviewer_rowstask_type_rowspriority_rowsr   r   r   get_review_analyticsk  s   	
"
	z*AnnotationTaskManager.get_review_analyticsc                 C   s   i d|j d|jd|jd|jd|jd|jd|jd|jr&|j nd	d
|j	d|j
d|jd|jr=|j nd	d|jrH|j nd	d|jrS|j nd	d|jr^|j nd	d|jd|j|j|j|j|jdS )zConvert task model to dictr@   r,   r-   r.   r/   r8   r0   r1   Nr2   rF   r3   rn   rQ   rR   rS   rZ   rX   )r[   r^   rU   r9   )r@   r,   r-   r.   r/   r8   r0   r1   	isoformatr2   rF   r3   rn   rQ   rR   rS   rZ   rX   r[   r^   rU   r9   )r*   rB   r   r   r   rA     sP   	
z#AnnotationTaskManager._task_to_dict)Tr(   )NN)NNNNN)r   r   r   r   r   r+   r   r#   strr   r   r   r   r   rC   rN   r   rT   rW   r   boolr_   r   rl   ro   r   r   r   rA   r   r   r   r   r&      s    		


3

'




!

&


+

6

Zr&   r'   r5   c                 C   s   t | S )z$Get annotation task manager instance)r&   r)   r   r   r   get_annotation_task_manager  s   r   )r   loggingtypingr   r   r   r   r   enumr   sqlalchemy.ormr   
sqlalchemyr	   r
   r   	getLoggerr   r>   r   r   r   r&   r   r   r   r   r   <module>   s    
   D