
    	]j4                     ^   d Z ddlZddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
 ddlmZmZ ddlmZ dd	lmZmZmZ dd
lmZmZmZ  ej0                  e      Z G d de
j6                        Z ed       G d de             Z ed       G d de             Z ed       G d de             Zy)a  
FSM State Models for Label Studio.

This module contains the state model definitions (BaseState and concrete state models).
These are separated from models.py to avoid registration issues in LSE where
extended state models need to be registered instead of the base OSS models.

When importing FsmHistoryStateModel, these state models won't be automatically
imported and registered, allowing LSE to register its own extended versions.
    N)datetime)AnyDictOptional)settings)models)QuerySet	UUIDField)register_state_model)AnnotationStateChoicesProjectStateChoicesTaskStateChoices)
UUID7Fieldgenerate_uuid7timestamp_from_uuid7c                      e Zd ZdZ ededd      Z ej                  dddd      Z	 ej                  ddd	
      Z ej                  dddd      Z ej                  dddd      Z ej                  ej                   ej"                  dd      Z ej&                  ed      Z ej,                  dd      Z ej0                  ddd      Z G d d      Zd Zed        Zedefd       Zde fdZ!e"de#d    fd       Z$e"de#e    fd       Z%e"de&d    fd        Z'e"d!ed"ede&d    fd#       Z(e"d$efd%       Z)e"de*e e+f   fd&       Z,e"dejZ                  fd'       Z.e"de fd(       Z/y))*	BaseStatea  
    Abstract base class for all state models using UUID7 for optimal time-series performance.

    This is the core of the FSM system, providing:
    - UUID7 primary key with natural time ordering
    - Standard state transition metadata
    - Audit trail information
    - Context data storage
    - Performance-optimized helper methods

    Benefits of this architecture:
    - INSERT-only operations for maximum concurrency
    - Natural time ordering eliminates need for created_at indexes
    - Global uniqueness enables distributed system support
    - Time-based partitioning for large amounts of state records with consistent performance
    - Complete audit trail by design
    TFz:UUID7 provides natural time ordering and global uniqueness)primary_keydefaulteditable	help_textzKOrganization ID that owns this state record (for multi-tenant applications))nullblankdb_indexr   2   zCurrent state of the entity)
max_lengthr   r   z%Previous state before this transition)r   r   r   r   d   z>Name of the transition method that triggered this state changez(User who triggered this state transition)	on_deleter   r   zTAdditional context data for this transition (e.g., validation results, external IDs))r   r   z/Human-readable reason for this state transition)r   r   zLHuman-readable timestamp for debugging (UUID7 id contains precise timestamp))auto_now_addr   r   c                       e Zd ZdZdgZdZy)BaseState.MetaT-ididN)__name__
__module____qualname__abstractorderingget_latest_by     G/root/env/lib/python3.12/site-packages/label_studio/fsm/state_models.pyMetar!   c   s    7r+   r-   c                     t        | | j                          dd      }| j                         j                          d| d| j                   d| j                   S )N_idunknown z: u    → )getattr_get_entity_nametitleprevious_statestate)self	entity_ids     r,   __str__zBaseState.__str__i   sa    DT%:%:%<$=S"A9M	'')//12!I;bATAT@UUZ[_[e[eZfggr+   c                 :    | j                         }t        | |      S )zGet the related entity object)r3   r2   )r7   entity_names     r,   entityzBaseState.entitym   s     ++-t[))r+   returnc                 ,    t        | j                        S )zExtract timestamp from UUID7 ID)r   r#   )r7   s    r,   timestamp_from_uuidzBaseState.timestamp_from_uuids   s     $DGG,,r+   c                 x    | j                   j                  }|j                  d      r|dd j                         S y)u>   Extract entity name from model name (e.g., TaskState → task)StateNr<   )	__class__r$   endswithlower)r7   
model_names     r,   r3   zBaseState._get_entity_namex   s7    ^^,,
w'cr?((**r+   c                     | j                          } | j                  j                  di ||ij                  d      j	                         S )z
        Get current state using UUID7 natural ordering.

        Uses UUID7's natural time ordering to efficiently find the latest state
        without requiring created_at indexes or complex queries.
        r"   r*   )_get_entity_field_nameobjectsfilterorder_byfirstclsr<   entity_fields      r,   get_current_statezBaseState.get_current_state   sH     4467!s{{!!;\6$:;DDUKQQSSr+   c                     | j                          } | j                  j                  di ||ij                  d      j	                         }|r|j
                  S dS )z
        Get current state value as string using UUID7 natural ordering.

        Uses UUID7's natural time ordering to efficiently find the latest state
        without requiring created_at indexes or complex queries.
        r"   Nr*   )rH   rI   rJ   rK   rL   r6   )rN   r<   rO   current_states       r,   get_current_state_valuez!BaseState.get_current_state_value   sZ     4467***DlF-CDMMeTZZ\&3}""==r+   c                 ~    | j                          } | j                  j                  di ||ij                  d      S )z(Get complete state history for an entityr"   r*   )rH   rI   rJ   rK   rM   s      r,   get_state_historyzBaseState.get_state_history   s?     4467!s{{!!;\6$:;DDUKKr+   
start_timeend_timec                     | j                          } | j                  j                  di ||i}t        j                  |||      j                  d      S )z
        Efficient time-range queries using UUID7.

        Uses UUID7's embedded timestamp for direct time-based filtering
        without requiring timestamp indexes.
        r#   r*   )rH   rI   rJ   r   filter_by_time_rangerK   )rN   r<   rV   rW   rO   querysets         r,   get_states_in_rangezBaseState.get_states_in_range   sT     4467%3;;%%?v(>?..xXNWWX\]]r+   sincec                     | j                          } | j                  j                  di ||i}t        j                  ||      j                  d      S )z)Get all states since a specific timestampr#   r*   )rH   rI   rJ   r   filter_since_timerK   )rN   r<   r\   rO   rZ   s        r,   get_states_sincezBaseState.get_states_since   sQ     4467%3;;%%?v(>?++He<EEdKKr+   c                     i S )a4  
        Get denormalized fields to include in the state record.

        Override this method in subclasses to provide denormalized data
        that should be stored with each state transition for performance
        optimization and auditing purposes.

        Args:
            entity: The entity instance being transitioned

        Returns:
            Dictionary of field names to values that should be stored
            in the state record

        Example:
            @classmethod
            def get_denormalized_fields(cls, entity):
                return {
                    'project_id': entity.project_id,
                    'organization_id': entity.project.organization_id,
                    'task_type': entity.task_type,
                    'priority': entity.priority
                }
        r*   rN   r<   s     r,   get_denormalized_fieldsz!BaseState.get_denormalized_fields   s	    4 	r+   c                 l    | j                         }| j                  j                  |      j                  S )z(Get the entity model for the state model)rH   _meta	get_fieldrelated_model)rN   
field_names     r,   get_entity_modelzBaseState.get_entity_model   s-     //1
yy"":.<<<r+   c                 d    | j                   }|j                  d      r|dd j                         S y)z-Get the foreign key field name for the entityrA   NrB   r<   )r$   rD   rE   )rN   rF   s     r,   rH   z BaseState._get_entity_field_name   s3     \\
w'cr?((**r+   N)0r$   r%   r&   __doc__r
   r   r#   r   PositiveIntegerFieldorganization_id	CharFieldr6   r5   transition_name
ForeignKeyr   AUTH_USER_MODELSET_NULLtriggered_by	JSONFielddictcontext_data	TextFieldreasonDateTimeField
created_atr-   r9   propertyr<   r   r?   strr3   classmethodr   rP   rS   r	   rU   r[   r_   r   r   rb   Modelrh   rH   r*   r+   r,   r   r      sl   & 
N	
B 2f11_	O FTEbcE%V%%D8_N
 'f&&R	O %6$$  //<	L $6## vL VD4efF &%%`J h * *
 -X - -#  T(;*? T T 	> 	> 	> L(;*? L L
 	^X 	^ 	^V^_jVk 	^ 	^ LX L L S#X  6 = = =
 s  r+   r   taskc                       e Zd ZdZ ej
                  ddej                        Z ej                  de	j                  d      Z ej                  dd	      Z G d
 d      Zed        Zy)	TaskStateu   
    Core task state tracking for Label Studio.
    Provides basic task state management with:
    - Simple 3-state workflow (CREATED → IN_PROGRESS → COMPLETED)
    - High-performance queries with UUID7 ordering
    z
tasks.Task
fsm_states)related_namer   r   Tr   choicesr   z3From task.project_id - denormalized for performancer   r   c                       e Zd ZdZ ej
                  ddgd       ej
                  g dd       ej
                  g dd	       ej
                  dd
gd      gZdgZy)TaskState.Metafsmtask_idr"   task_current_state_idxfieldsname
project_idr6   r"   task_project_state_idxrl   r6   r"   task_org_reporting_idxr#   task_history_idxNr$   r%   r&   	app_labelr   Indexindexesr(   r*   r+   r,   r-   r      si    	 FLLE 29QRFLL >E]^FLL CJbcFLLD 18JK	
 7r+   r-   c                     d|j                   iS )z.Get denormalized fields for TaskState creationr   )r   ra   s     r,   rb   z!TaskState.get_denormalized_fields  s     &++
 	
r+   N)r$   r%   r&   rj   r   ro   CASCADEr~   rm   r   r   r6   rk   r   r-   r|   rb   r*   r+   r,   r   r      s|     6\PVP^P^_D F4D4L4LW[\E,,,!VJ  
 
r+   r   
annotationc                   *   e Zd ZdZ ej
                  dej                  d      Z ej                  de	j                  d      Z ej                  dd	      Z ej                  dd
	      Z ej                  ddd      Z G d d      Zed        Zy)AnnotationStateu   
    Core annotation state tracking for Label Studio.
    Provides basic annotation state management with:
    - Simple 2-state workflow (CREATED → COMPLETED)
    ztasks.Annotationr   r   r   r   Tr   z6From annotation.task_id - denormalized for performancer   z>From annotation.task.project_id - denormalized for performancez>From annotation.completed_by_id - denormalized for performancer   r   r   c                       e Zd ZdZ ej
                  ddgd       ej
                  g dd       ej
                  g dd	       ej
                  g d
d      gZdgZy)AnnotationState.Metar   annotation_idr"   anno_current_state_idxr   )r   r6   r"   anno_task_state_idx)completed_by_idr6   r"   anno_user_report_idxr   anno_project_report_idxNr   r*   r+   r,   r-   r   $  se    	 FLL% 8?WXFLL ;BWXFLL CJ`aFLL >E^_
 7r+   r-   c                     |j                   j                  |j                   j                  |j                  r|j                  dS ddS )z4Get denormalized fields for AnnotationState creationN)r   r   r   )r~   r#   r   r   ra   s     r,   rb   z'AnnotationState.get_denormalized_fields0  sH     {{~~ ++009?9O9Ov55
 	
 VZ
 	
r+   N)r$   r%   r&   rj   r   ro   r   r   rm   r   r   r6   rk   r   r   r   r-   r|   rb   r*   r+   r,   r   r     s     #""#5^jkJ F4J4R4R]abE *f))!YG -,,!aJ 2f11D,lO
 
 
 
r+   r   projectc                       e Zd ZdZ ej
                  dej                  d      Z ej                  de	j                  d      Z ej                  ddd	      Z G d
 d      Zed        Zy)ProjectStateu   
    Core project state tracking for Label Studio.
    Provides basic project state management with:
    - Simple 3-state workflow (CREATED → IN_PROGRESS → COMPLETED)
    - Project lifecycle tracking
    zprojects.Projectr   r   r   Tr   z9From project.created_by_id - denormalized for performancer   c                       e Zd ZdZ ej
                  ddgd       ej
                  g dd       ej
                  ddgd	      gZdgZy
)ProjectState.Metar   r   r"   project_current_state_idxr   r   project_org_state_idxrl   project_org_reporting_idxNr   r*   r+   r,   r-   r   M  sX    	 FLLu 5<WXFLL CJabFLL!2E :A\]
 7r+   r-   c                 <    d|j                   r|j                   iS diS )z1Get denormalized fields for ProjectState creationcreated_by_idN)r   ra   s     r,   rb   z$ProjectState.get_denormalized_fieldsX  s.     V5I5IV11
 	
OS
 	
r+   N)r$   r%   r&   rj   r   ro   r   r   rm   r   r   r6   rk   r   r-   r|   rb   r*   r+   r,   r   r   :  s}      f 2fnn[ghG F4G4O4OZ^_E/F//D,gM	 	 
 
r+   r   ) rj   loggingr   typingr   r   r   django.confr   	django.dbr   django.db.modelsr	   r
   fsm.registryr   fsm.state_choicesr   r   r   	fsm.utilsr   r   r   	getLoggerr$   loggerr}   r   r   r   r   r*   r+   r,   <module>r      s   	   & &    0 - 
 G F			8	$y yF f&
	 &
 &
R l#+
i +
 $+
\ i "
9 "
 !"
r+   