
    ni6                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZ ddlmZ  ee          Z ej        d	          ZddZddZddZ G d d          ZdS )u  Business-logic service for graph admin management.

Handles type definitions, entity CRUD, dedup/merge, relationships,
placeholders, and statistics via Neo4j Cypher queries.

知识图谱管理服务模块。
提供面向管理后台的图谱操作接口，包括：
- 实体/关系类型定义的 CRUD（持久化为 _EntityType / _RelationType 元节点）
- 实体节点的搜索、编辑、删除和去重合并
- 关系的创建和删除
- 占位文档节点的管理
- 图谱统计信息聚合
    )annotationsN)Any)settings)
get_schema)Neo4jClientreload_valid_types)
get_loggerz^[A-Za-z_]\w{0,49}$rawr   returndictc                    | si S t          | t                    r| S 	 t          j        |           S # t          j        t
          f$ r i cY S w xY w)z;Parse properties_schema from Neo4j (stored as JSON string).)
isinstancer   jsonloadsJSONDecodeError	TypeError)r
   s    6D:\work\zm-rag\backend\app\core\graph_admin_service.py	_parse_psr       se     	#t 
z# ),   			s   1 AAlist[dict[str, Any]]c                 @    t                      } d | j        D             S )z8Load default entity types from config/graph_schema.yaml.c           	         g | ]K}|d          |                     dd          |                     dd          |                     dd          dLS )namedescription iconcolorr   r   r   r   get).0ets     r   
<listcomp>z._load_default_entity_types.<locals>.<listcomp>1   sk         vJ66-44FF62&&VVGR((		
 	
      )r   entity_typesschemas    r   _load_default_entity_typesr'   .   s1    \\F  %   r#   c                 @    t                      } d | j        D             S )z>Load default relationship types from config/graph_schema.yaml.c           	         g | ]K}|d          |                     dd          |                     dg           |                     dg           dLS r   r   r   source_labelstarget_labels)r   r   r+   r,   r   )r    rts     r   r"   z+_load_default_rel_types.<locals>.<listcomp>?   sk         vJ66-44VVOR88VVOR88		
 	
  r#   )r   relationship_typesr%   s    r   _load_default_rel_typesr/   <   s1    \\F  +   r#   c                  (   e Zd ZdZdPdZdQdZdQdZdRd
ZdRdZdSdZ		 	 dTdUdZ
dVdZdWdZdSdZ	 	 	 dXdYd ZdVd!ZdWd"ZdZd#Zd[d&Z	 	 	 	 	 d\d]d0Zd^d3Zd_d5Zd`d6Zdad7Z	 	 	 dbdcd=Z	 dddedCZ	 	 	 	 	 dfdgdGZ	 dhdidHZdjdJZdSdKZdkdNZdldOZdS )mGraphAdminServiceu!  Admin-level operations on the knowledge graph.

    知识图谱管理服务，提供类型管理、实体 CRUD、去重合并、
    统计信息等管理后台所需的全部图操作接口。
    内部维护实体类型和关系类型的内存缓存，减少 Neo4j 查询次数。
    neo4jr   r   Nonec                0    || _         i | _        i | _        d S N)_neo4j_entity_types_cache_rel_types_cache)selfr2   s     r   __init__zGraphAdminService.__init__R   s    >@ ;=r#   c                  K   | j         j                            t          j                  4 d{V }t                      D ]d}|                    d|d         |                    dd          |                    dd          |                    dd          	           d{V  et                      D ]d}|                    d
|d         |                    dd          |                    dg           |                    dg                      d{V  e	 ddd          d{V  n# 1 d{V swxY w Y   t          
                    d           dS )z@Write default _EntityType / _RelationType meta nodes if missing.databaseNziMERGE (t:_EntityType {name: $name}) ON CREATE SET t.description = $desc, t.icon = $icon, t.color = $colorr   r   r   r   r   )r   descr   r   zyMERGE (t:_RelationType {name: $name}) ON CREATE SET t.description = $desc, t.source_labels = $src, t.target_labels = $tgtr+   r,   r   r>   srctgtdefault_types_ensured)r6   driversessionr   neo4j_databaser'   runr   r/   loggerinfo)r9   rD   r!   r-   s       r   ensure_default_typesz&GraphAdminService.ensure_default_types[   s     ;%--x7N-OO 	 	 	 	 	 	 	SZ022  kk\Fr22++&&"-- "           .// 	 	kkE Fr223333 "          		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	( 	+,,,,,s   C'D--
D7:D7c                  K   | j         j                            t          j                  4 d{V }|                    d           d{V }|                                 d{V }d |D             | _        |                    d           d{V }|                                 d{V }d |D             | _        ddd          d{V  n# 1 d{V swxY w Y   t          t          | j                                                  t          | j                                                             t                              dt          | j                  t          | j                  	           dS )
zH(Re)load type definitions from Neo4j into memory and update module sets.r<   NzMATCH (t:_EntityType) RETURN t.name AS name, t.description AS description, t.icon AS icon, t.color AS color, t.properties_schema AS psc                    i | ]J}|d          
|d          |d          |d         pd|d         pd|d         pdt          |d                   dKS )r   r   r   r   r   ps)r   r   r   r   properties_schemar   r    rs     r   
<dictcomp>z8GraphAdminService.refresh_type_cache.<locals>.<dictcomp>}   s|     
( 
( 
( V9
(&	fI#$]#3#9rfIOwZ-2)21T7);); 
( 
( 
(r#   zMATCH (t:_RelationType) RETURN t.name AS name, t.description AS description, t.source_labels AS source_labels, t.target_labels AS target_labelsc           
         i | ]P}|d          
|d          |d          |d         pdt          |d         pg           t          |d         pg           dQS r*   listrO   s     r   rQ   z8GraphAdminService.refresh_type_cache.<locals>.<dictcomp>   s     	% 	% 	% V9	%&	fI#$]#3#9r%)!O*<*B%C%C%)!O*<*B%C%C	 	% 	% 	%r#   )node_labels	rel_typestype_cache_refreshed)r$   rV   )r6   rC   rD   r   rE   rF   datar7   r8   r   setkeysrG   rH   lenr9   rD   resultrecordss       r   refresh_type_cachez$GraphAdminService.refresh_type_caches   s\     ;%--x7N-OO %	 %	 %	 %	 %	 %	 %	SZ";;>       F
 #KKMM))))))G
( 
( !
( 
( 
(D$ #;;3       F #KKMM))))))G	% 	% !	% 	% 	%D!9%	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	 %	P 	D499;;<<$/446677	
 	
 	
 	
 	"T566$/00 	 	
 	
 	
 	
 	
s   BC
CCset[str]c                V    t          | j                                                  dhz  S )NDocument)rY   r7   rZ   r9   s    r   get_entity_type_namesz'GraphAdminService.get_entity_type_names   s&    4+002233zlBBr#   c                N    t          | j                                                  S r5   )rY   r8   rZ   rc   s    r   get_rel_type_namesz$GraphAdminService.get_rel_type_names   s    4(--//000r#   r   c                0  K   | j         j                            t          j                  4 d{V }|                    d           d{V }|                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   d |D             S )z6List all entity type definitions with instance counts.r<   Na  MATCH (t:_EntityType) OPTIONAL MATCH (n) WHERE any(l IN labels(n) WHERE l = t.name) AND NOT n:_EntityType AND NOT n:_RelationType RETURN t.name AS name, t.description AS description, t.icon AS icon, t.color AS color, t.properties_schema AS ps, count(n) AS instance_count ORDER BY t.namec           
         g | ]B}|d          |d         pd|d         pd|d         pdt          |d                   |d         dCS )r   r   r   r   r   rL   instance_count)r   r   r   r   rM   ri   rN   rO   s     r   r"   z7GraphAdminService.list_entity_types.<locals>.<listcomp>   st     

 

 

  &	 /52&	R7)r%.qw%7%7"#$4"5 

 

 

r#   r6   rC   rD   r   rE   rF   rX   r\   s       r   list_entity_typesz#GraphAdminService.list_entity_types   sL     ;%--x7N-OO 
	* 
	* 
	* 
	* 
	* 
	* 
	*SZ";;"       F #KKMM))))))G
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	*

 

 

 

 

 
	
   6A;;
BBr   Nr   strr   r   r   rM   dict | Nonedict[str, Any]c           	     F  K   t                               |          st          d|           | j        j                            t          j                  4 d {V }|                    d|           d {V }|	                                 d {V rt          d| d          |rt          j        |          nd}|                    d|||||	           d {V  	 |                                 d
}	|                    d|	 d| d           d {V  nA# t          $ r4}
t                              d|t!          |
                     Y d }
~
nd }
~
ww xY wd d d           d {V  n# 1 d {V swxY w Y   |                                  d {V  ||||dS )NzInvalid type name: r<   ,MATCH (t:_EntityType {name: $name}) RETURN tr   Entity type '' already existsr   zlCREATE (t:_EntityType {name: $name, description: $desc, icon: $icon, color: $color, properties_schema: $ps}))r   r>   r   r   rL   _name_uniqueCREATE CONSTRAINT  IF NOT EXISTS FOR (n:) REQUIRE n.name IS UNIQUEconstraint_create_failed)r   errorr   )_SAFE_IDENTIFIER_REmatch
ValueErrorr6   rC   rD   r   rE   rF   singler   dumpslower	ExceptionrG   warningrm   r_   )r9   r   r   r   r   rM   rD   r]   ps_strconstraint_nameexcs              r   create_entity_typez$GraphAdminService.create_entity_type   s      #((.. 	;9499:::;%--x7N-OO 	V 	V 	V 	V 	V 	V 	VSZ";;>T '        F ]]__$$$$$$ I !G!G!G!GHHH6GOTZ 1222RF++G$e	          V%)ZZ\\"?"?"?kk? ? ?"? ? ?           V V V9CPSHHUUUUUUUUV-	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V2 %%'''''''''[$QVWWWs=   BE1$9DE1
E(*EE1EE11
E;>E;updatesc           
       K   |                     dd           }d|i}| j        j                            t          j                  4 d {V }|                    d|           d {V }|                                 d {V st          d| d          g }d|i}dD ]e}	|	|v r_||	         W|	                    d	|	 d
|	            ||	         }
|	dk    r)t          |
t                    rt          j        |
          }
|
||	<   f|r* |j        dd                    |           fi | d {V  |r||k    r~t                              |          st          d|           |                    d| d| d| d           d {V }|                                 d {V }|r|d         nd}	 |                                 d}|                    d| d           d {V  n,# t$          $ r t&                              dd           Y nw xY w	 |                                 d}|                    d| d| d           d {V  n@# t$          $ r3}t&                              dt+          |                     Y d }~nd }~ww xY w|                    d ||!           d {V  ||d<   ||d"<   	 d d d           d {V  n# 1 d {V swxY w Y   |                                  d {V  |S )#Nnew_namer   r<   rq   rr   rs   ' not found)r   r   r   rM   t. = $rM   z(MATCH (t:_EntityType {name: $name}) SET , zInvalid new type name: 	MATCH (n:z#) WHERE NOT n:_EntityType REMOVE n:z SET n:z RETURN count(n) AS migratedmigratedr   ru   DROP CONSTRAINT z
 IF EXISTSFailed to drop constraintTexc_inforv   rw   rx   rename_constraint_failed)rz   z4MATCH (t:_EntityType {name: $old}) SET t.name = $newoldnewmigrated_instances)popr6   rC   rD   r   rE   rF   r~   r}   appendr   r   r   r   joinr{   r|   r   r   rG   r   rm   r_   )r9   r   r   r   result_inforD   check	set_partsparamskeyvalmigrate_resultrecr   old_constraintnew_constraintr   s                    r   update_entity_typez$GraphAdminService.update_entity_type   s     ;;z400'-tn;%--x7N-OO ;	= ;	= ;	= ;	= ;	= ;	= ;	=SZ!++>T &        E '''''' D !B!B!B!BCCC I&,d^FL & &'>>gcl&>$$%8#%8%83%8%8999!#,C111jd6K6K1"joo"%F3K !gkW9AUAUWW           "=H,,*00:: K$%Ix%I%IJJJ'.{{2 2 2 $2 2-52 2 2( ( " " " " " "
 +1133333333.183z??qO(,

%B%B%BN!++&S&S&S&STTTTTTTTTT  O O ONN#>NNNNNNOO(0(8(8%F%F%FN!++G^ G G"*G G G          ! O O ONN#=SXXNNNNNNNNNO kkJ( "          '/F#4<01<w;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	= ;	=z %%'''''''''sa   E&K46G+*K+&HKHK9IK
J)J
K
J+K
KKc                  K   | j         j                            t          j                  4 d {V }|                    d| d           d {V }|                                 d {V }|r(|d         dk    rt          d| d|d          d          |                    d	|
           d {V  	 |                    d|                                 d           d {V  n,# t          $ r t                              dd           Y nw xY wd d d           d {V  n# 1 d {V swxY w Y   |                                  d {V  |ddS )Nr<   r   z0) WHERE NOT n:_EntityType RETURN count(n) AS cntcntr   zCannot delete type '': z- instances exist. Delete all instances first.z,MATCH (t:_EntityType {name: $name}) DELETE trr   r   z_name_unique IF EXISTSr   Tr   r   deleted)r6   rC   rD   r   rE   rF   r~   r}   r   r   rG   r   r_   r9   r   rD   r]   r   s        r   delete_entity_typez$GraphAdminService.delete_entity_type0  s     ;%--x7N-OO 	K 	K 	K 	K 	K 	K 	KSZ";;RDRRR       F ''''''C s5zA~~ 24 2 2CJ 2 2 2  
 ++>T          KkkKtzz||KKK           K K K:TJJJJJK)	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K. %%'''''''''...s6   BD%51C'&D%'&DD%DD%%
D/2D/c                4  K   | j         j                            t          j                  4 d {V }|                    d           d {V }|                                 d {V }d |D             cd d d           d {V  S # 1 d {V swxY w Y   d S )Nr<   zMATCH (t:_RelationType) OPTIONAL MATCH ()-[r]->() WHERE type(r) = t.name WITH t, count(r) AS cnt RETURN t.name AS name, t.description AS description, t.source_labels AS source_labels, t.target_labels AS target_labels, cnt AS instance_count ORDER BY t.namec           	         g | ]H}|d          |d         pdt          |d         pg           t          |d         pg           |d         dIS )r   r   r   r+   r,   ri   )r   r   r+   r,   ri   rS   rO   s     r   r"   z4GraphAdminService.list_rel_types.<locals>.<listcomp>^  sx     	 	 	  fI#$]#3#9r%)!O*<*B%C%C%)!O*<*B%C%C&'(8&9 	 	 	r#   rj   r\   s       r   list_rel_typesz GraphAdminService.list_rel_typesO  sX      ;%--x7N-OO 	 	 	 	 	 	 	SZ";;"       F #KKMM))))))G	 	 !	 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   AB
BBr+   list[str] | Noner,   c                   K   t                               |          st          d|           | j        j                            t          j                  4 d {V }|                    d|           d {V }|	                                 d {V rt          d| d          |                    d|||pg |pg            d {V  d d d           d {V  n# 1 d {V swxY w Y   | 
                                 d {V  ||d	S )
NzInvalid rel type name: r<   .MATCH (t:_RelationType {name: $name}) RETURN trr   Relationship type 'rt   zdCREATE (t:_RelationType {name: $name, description: $desc, source_labels: $src, target_labels: $tgt})r?   )r   r   )r{   r|   r}   r6   rC   rD   r   rE   rF   r~   r_   )r9   r   r   r+   r,   rD   r   s          r   create_rel_typez!GraphAdminService.create_rel_typei  s     
 #((.. 	?=t==>>>;%--x7N-OO 	 	 	 	 	 	 	SZ!++@t &        E \\^^###### O !Mt!M!M!MNNN++=!'R]-@b	          	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 %%'''''''''[999s   A/C  
C*-C*c                  K   |                     dd           }d|i}| j        j                            t          j                  4 d {V }|                    d|           d {V }|                                 d {V st          d| d          g }d|i}dD ]4}	|	|v r.||	         &|	                    d	|	 d
|	            ||	         ||	<   5|r* |j        dd
                    |           fi | d {V  |r||k    rt                              |          st          d|           |                    d| d| d           d {V }
|
                                 d {V }|r|d         nd}|                    d||           d {V  ||d<   ||d<   	 d d d           d {V  n# 1 d {V swxY w Y   |                                  d {V  |S )Nr   r   r<   r   rr   r   r   )r   r+   r,   r   r   z*MATCH (t:_RelationType {name: $name}) SET r   zInvalid new rel type name: MATCH (a)-[r:z]->(b) CREATE (a)-[r2:zB]->(b) SET r2 = properties(r) DELETE r RETURN count(r) AS migratedr   r   z6MATCH (t:_RelationType {name: $old}) SET t.name = $newr   migrated_relationships)r   r6   rC   rD   r   rE   rF   r~   r}   r   r   r{   r|   r_   )r9   r   r   r   r   rD   r   r   r   r   r   r   r   s                r   update_rel_typez!GraphAdminService.update_rel_type  s     ;;z400'-tn;%--x7N-OO %	A %	A %	A %	A %	A %	A %	ASZ!++@t &        E '''''' J !Ht!H!H!HIIII&,d^FH / /'>>gcl&>$$%8#%8%83%8%8999")#,F3K !gkY499YCWCWYY         
  AH,,*00:: O$%M8%M%MNNN (/{{;D ; ;&.; ; ;( ( " " " " " "
 +1133333333.183z??qkkL( "          '/F#8@45@K%	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	A %	AN %%'''''''''s   EF88
GGc                  K   | j         j                            t          j                  4 d {V }|                    d| d           d {V }|                                 d {V }|r(|d         dk    rt          d| d|d          d          |                    d	|
           d {V  d d d           d {V  n# 1 d {V swxY w Y   |                                  d {V  |ddS )Nr<   zMATCH ()-[r:z]->() RETURN count(r) AS cntr   r   zCannot delete rel type 'r   z instances exist.z.MATCH (t:_RelationType {name: $name}) DELETE trr   Tr   )	r6   rC   rD   r   rE   rF   r~   r}   r_   r   s        r   delete_rel_typez!GraphAdminService.delete_rel_type  s     ;%--x7N-OO 	 	 	 	 	 	 	SZ";;AtAAA       F ''''''C s5zA~~ UtUUE
UUU   ++@t          	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 %%'''''''''...s   BC
CCc                  K   | j         j                            t          j                  4 d {V }|                    d           d {V }|                                 d {V }|r|d         nd}|                    d           d {V }|                                 d {V }|r|d         nd}|                    d           d {V }d |                                 d {V D             }|                    d           d {V }d	 |                                 d {V D             }|                    d
           d {V }|                                 d {V }|r|d         nd}|                    d           d {V }|                                 d {V }|r|d         nd}	d d d           d {V  n# 1 d {V swxY w Y   ||||	||dS )Nr<   zRMATCH (n) WHERE NOT n:_EntityType AND NOT n:_RelationType RETURN count(n) AS totaltotalr   z)MATCH ()-[r]->() RETURN count(r) AS totalzMATCH (n) WHERE NOT n:_EntityType AND NOT n:_RelationType UNWIND labels(n) AS lbl WITH lbl WHERE lbl <> '_EntityType' AND lbl <> '_RelationType' RETURN lbl AS label, count(*) AS cnt ORDER BY cnt DESCc                0    g | ]}|d          |d         dS )labelr   )r   count r    r   s     r   r"   z5GraphAdminService.get_graph_stats.<locals>.<listcomp>  s8     6 6 6" &)\CJGG 6 6 6r#   zIMATCH ()-[r]->() RETURN type(r) AS typ, count(r) AS cnt ORDER BY cnt DESCc                0    g | ]}|d          |d         dS )typr   )typer   r   r   s     r   r"   z5GraphAdminService.get_graph_stats.<locals>.<listcomp>  s8     5 5 5! $'u:E
CC 5 5 5r#   zsMATCH (n) WHERE NOT n:Document AND NOT n:_EntityType AND NOT n:_RelationType AND NOT (n)--() RETURN count(n) AS cntr   z@MATCH (d:Document {is_placeholder: true}) RETURN count(d) AS cnt)total_nodestotal_relationshipsorphan_nodesplaceholder_countnode_counts
rel_counts)r6   rC   rD   r   rE   rF   r~   rX   )
r9   rD   rP   r   r   
total_relsr   r   r   r   s
             r   get_graph_statsz!GraphAdminService.get_graph_stats  s_     ;%--x7N-OO -	9 -	9 -	9 -	9 -	9 -	9 -	9SZkk+       A 

""""""C*-4#g,,1K kk"MNNNNNNNNA

""""""C),3W!J kkI       A6 6,-FFHHnnnnnn6 6 6K kk[       A5 5+,6688^^^^^^5 5 5J kk9       A
 

""""""C),33u::!L kkR       A 

""""""C.1 8E

q[-	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9 -	9` '#-(!2&$
 
 	
s   FG
GG
es_doc_ids	list[str]c                  K   | j         j                            t          j                  4 d {V }|                    d           d {V }|                                 d {V }|r|d         nd}|r|d         nd}|dk    rt          ||z  d          nd}|                    d           d {V }|                                 d {V }|rt          |d	                   nt                      }t          |          }	t          |	|z
            }
d d d           d {V  n# 1 d {V swxY w Y   |d|
t          |          d
S )Nr<   zMATCH (n) WHERE NOT n:Document AND NOT n:_EntityType AND NOT n:_RelationType WITH count(n) AS total,      sum(CASE WHEN NOT (n)--() THEN 1 ELSE 0 END) AS no_rel RETURN total, no_relr   r   no_rel   g        zmMATCH (d:Document) WHERE d.is_placeholder IS NULL OR d.is_placeholder = false RETURN collect(d.doc_id) AS idsids)no_relation_ratioduplicate_candidatesmissing_in_graphtotal_es_docs)
r6   rC   rD   r   rE   rF   r~   roundrY   r[   )r9   r   rD   rP   r   total_entitiesr   ratio	neo4j_idses_setmissings              r   get_graph_healthz"GraphAdminService.get_graph_health  s&     ;%--x7N-OO 	. 	. 	. 	. 	. 	. 	.SZkk'       A 

""""""C-07S\\aN&)0S]]qF9G!9K9KE&>11555QTE kk2       A 

""""""C+.9CJCEEI__F&9,--G/	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.4 "'$% ' __	
 
 	
s   C$D))
D36D3      connection_countr   
str | Nonepageint	page_sizesort_byc                  K   |dz
  |z  }g }|r7||                                  v r!t                              |          rd| d}nd}|                    g d           ||d}	|r|                    d           ||	d<   |rd	d
                    |           nd}
|dk    rd}nd}| |
 d| d}| |
 d}| j        j                            t          j
                  4 d {V } |j        |fi |	 d {V }|                                 d {V } |j        |fi |	 d {V }|                                 d {V }|r|d         nd}d d d           d {V  n# 1 d {V swxY w Y   d |D             }||||dS )Nr   r   )z	MATCH (n))zNOT n:_EntityTypezNOT n:_RelationTypezNOT n:Documentskiplimitzn.name CONTAINS $name_filtername_filter WHERE  AND r   r   z
n.name ASCz	conn DESCz0 WITH n, size([(n)-[]-() | 1]) AS conn ORDER BY ze SKIP $skip LIMIT $limit RETURN elementId(n) AS id, labels(n) AS labels, properties(n) AS props, connz RETURN count(n) AS totalr<   r   r   c           	         g | ]S}|d          d |d         D             |d                              dd          t          |d                   |d         dTS )idc                    g | ]}|d v|	S )_EntityType_RelationTyper   r    ls     r   r"   z>GraphAdminService.list_entities.<locals>.<listcomp>.<listcomp>Z  s#    ___Q>^5^5^15^5^5^r#   labelspropsr   r   conn)r   r   r   
propertiesr   )r   r   rO   s     r   r"   z3GraphAdminService.list_entities.<locals>.<listcomp>W  sx     	
 	
 	
  g__ak___'
vr22"1W:..$%fI 	
 	
 	
r#   itemsr   r   r   )rd   r{   r|   extendr   r   r6   rC   rD   r   rE   rF   rX   r~   )r9   r   r   r   r   r   r   base_conditionsr|   r   where_clauseordercyphercount_cypherrD   r]   r^   count_result	count_recr   r   s                        r   list_entitieszGraphAdminService.list_entities  s      qI% &( 	Ud88::::?R?X?XY^?_?_:((((EEE"" $ $ $    +/!C!C 	)""#ABBB$(F=!DS[@o!>!>@@@Y[f EEE  +l + ++ + + 	 =l=== 	 ;%--x7N-OO 	; 	; 	; 	; 	; 	; 	;SZ&7;v8888888888F"KKMM))))))G!,\!D!DV!D!DDDDDDDL*1133333333I*3:Ig&&E	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	;	
 	
 	
 	
 	
 9UUUs   (A)E##
E-0E-	entity_iddict[str, Any] | Nonec                d  K   | j         j                            t          j                  4 d {V }|                    d|           d {V }|                                 d {V }|	 d d d           d {V  d S |d         }d |d         D             }|                    d|           d {V }|                                 d {V }d d d           d {V  n# 1 d {V swxY w Y   |j        d |j	        D             t          |          d	 |D             d
 |D             dS )Nr<   a$  MATCH (n) WHERE elementId(n) = $eid OPTIONAL MATCH (n)-[r]-(m) WHERE NOT m:_EntityType AND NOT m:_RelationType RETURN n, collect(DISTINCT {  id: elementId(m), labels: labels(m),   name: m.name, rel_type: type(r),   direction: CASE WHEN startNode(r) = n THEN 'out' ELSE 'in' END}) AS neighborseidnc                <    g | ]}|                     d           |S )r   r   r    r  s     r   r"   z7GraphAdminService.get_entity_detail.<locals>.<listcomp>w  s'    HHH1AEE$KKHQHHHr#   	neighborszMATCH (n)-[r]-(d:Document) WHERE elementId(n) = $eid AND (d.is_placeholder IS NULL OR d.is_placeholder = false) RETURN d.doc_id AS doc_id, d.title AS title, d.doc_number AS doc_number, type(r) AS rel_typec                    g | ]}|d v|	S r   r   r   s     r   r"   z7GraphAdminService.get_entity_detail.<locals>.<listcomp>  s#    [[[Q:Z1Z1Zq1Z1Z1Zr#   c           	         g | ]a}|d          d |d         pg D             |                     d          pd|                     d          pd|                     d          pddbS )r   c                    g | ]}|d v|	S r   r   r   s     r   r"   zBGraphAdminService.get_entity_detail.<locals>.<listcomp>.<listcomp>  s#    kkkQJjAjAjqAjAjAjr#   r   r   r   rel_type	direction)r   r   r   r  r  r   r  s     r   r"   z7GraphAdminService.get_entity_detail.<locals>.<listcomp>  s     	 	 	  D'kk1X;+<"kkkEE&MM/R !j 1 1 7R!"{!3!3!9r 	 	 	r#   c                \    g | ])}|d          pd|d         pd|d         pd|d         pdd*S )doc_idr   title
doc_numberr  )r  r  r  r  r   )r    ds     r   r"   z7GraphAdminService.get_entity_detail.<locals>.<listcomp>  sa          k/RwZ-2"#L/"7R !* 3	   r#   )r   r   r   r  related_docs)r6   rC   rD   r   rE   rF   r~   rX   
element_idr   r   )	r9   r  rD   r]   r   nodeneighbors_raw
doc_resultdocss	            r   get_entity_detailz#GraphAdminService.get_entity_detailc  sy     ;%--x7N-OO 	+ 	+ 	+ 	+ 	+ 	+ 	+SZ";;"  '        F ''''''C{!	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+$ s8DHHK(8HHHM  '{{B   +          J $********D;	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+@ /[[$+[[[t**	 	 '	 	 	    
 
 	
s   ;C$AC$$
C.1C.r   c                N  K   ||                                  vrt          d|           t                              |          st          d|           |                    d          st          d          | j        j                            t          j	                  4 d {V }	 |
                    d| d|           d {V }|                                 d {V }nh# t          $ r[}t          |          }d	|                                v sd
|                                v rt          d|d          d          | d }~ww xY w	 d d d           d {V  n# 1 d {V swxY w Y   |d         t          |d                   t!          |d                   dS )NzUnknown entity type: zInvalid label: r   zProperty 'name' is requiredr<   z
CREATE (n:zO $props) RETURN elementId(n) AS id, labels(n) AS labels, properties(n) AS props)r   zalready exists
constraintzEntity with name 'rt   r   r   r   )r   r   r   )rd   r}   r{   r|   r   r6   rC   rD   r   rE   rF   r~   r   rm   r   rT   r   )r9   r   r   rD   r]   r   r   errs           r   create_entityzGraphAdminService.create_entity  sz     224444<U<<==="((// 	86u66777~~f%% 	<:;;;;%--x7N-OO 	 	 	 	 	 	 	SZ&{{] ] ] ]$  +          
 #MMOO++++++   #hh#syy{{22lciikk6Q6Q$%^*V:L%^%^%^__ehh	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d)3x=))s7|,,
 
 	
s7   +E$-;C)(E$)
E3AE		EE$$
E.1E.c                v   K   | j                             ||           d {V }|t          d| d          |S )NzEntity 
 not found)r6   update_noder}   )r9   r  r   r]   s       r   update_entityzGraphAdminService.update_entity  sS      {..y*EEEEEEEE><y<<<===r#   c                R   K   | j                             |           d {V }d|i|S )Nr   )r6   delete_node)r9   r  r]   s      r   delete_entityzGraphAdminService.delete_entity  s=      {..y99999999i*6**r#   333333?2   	thresholdfloatr   c                \
  K   	 ddl m} n,# t          $ r t                              d           g cY S w xY w|r7||                                 v r!t                              |          rd| d}nd}| j        j	        
                    t          j                  4 d{V }|                    | d	           d{V }|                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   |sg S g }	i }
t          |          D ]\  }}|                    d
          pd}|                    d          pg }t#          |t$                    r|g}|	                    |d         |d         ||d           |g|z   D ]S}|                                                                }|r)|
                    |g                               |           Tg }t/                      }|
                                D ]+\  }}t3          |          dk     rt5          t3          |                    D ]}t5          |dz   t3          |                    D ]}||         ||         }}t7          t9          |	|         d         |	|         d         g                    }||v rM|                    |           |                    |	|         d         |	|         d
         |	|         d         |	|         d
         dd|	|         d         r|	|         d         d         ndd           Ҍ-i }t          |	          D ]R\  }}|d
         }|rC|d                                         }|                    |g                               |           S|                                D ]`\  }}t5          t3          |                    D ]<}t5          |dz   t3          |                    D ]}||         ||         }}t7          t9          |	|         d         |	|         d         g                    }||v rN|                    |	|         d
         |	|         d
                   dz  }||k    r|                    |           |                    |	|         d         |	|         d
         |	|         d         |	|         d
         t?          |d          d|	|         d         r|	|         d         d         ndd           >b|                     d d           |d|         S )zLDetect duplicate entity candidates using string similarity + alias matching.r   )fuzzz*rapidfuzz not installed; dedup unavailabler   r   zLMATCH (n) WHERE NOT n:Document AND NOT n:_EntityType AND NOT n:_RelationTyper<   NzU RETURN elementId(n) AS id, labels(n) AS labels, n.name AS name, n.aliases AS aliasesr   r   aliasesr   r   )r   r   r   r1     r   g      ?alias_match)entity_a_identity_a_nameentity_b_identity_b_name
similarity
match_typer   g      Y@   edit_distancec                    | d         S )Nr8  r   )cs    r   <lambda>z5GraphAdminService.detect_duplicates.<locals>.<lambda>2  s
    ao r#   T)r   reverse)!	rapidfuzzr0  ImportErrorrG   rz   rd   r{   r|   r6   rC   rD   r   rE   rF   rX   	enumerater   r   rm   r   stripr   
setdefaultrY   r   r[   rangetuplesortedaddWRatior   sort)r9   r   r-  r   r0  r|   rD   r]   r^   entities	alias_mapirP   r   r1  aa_lower
candidates
seen_pairsr   indicesja_idxb_idxpair_keybucketsent_bucketsims                                 r   detect_duplicatesz#GraphAdminService.detect_duplicates  sq     	&&&&&&& 	 	 	LLEFFFIII	  	Ud88::::?R?X?XY^?_?_:((((EE@ 
 ;%--x7N-OO 	* 	* 	* 	* 	* 	* 	*SZ";; 7 7 7       F #KKMM))))))G	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*  	I *,	g&& 	@ 	@DAq55==&BDeeI&&,"G'3'' $")OOgH+"	     Vg% @ @''))//++ @(("55<<Q???@
 ,.
+.55
 &OO-- 	 	LC7||a3w<<((  q1uc'll33  A#*1:wqz5E$VXe_T-BHUOTXDY,Z%[%[\\H:-- NN8,,,%%'/t'<)1%)@'/t'<)1%)@&)&3AI%QYAZ!b%!:1!=!=`b' '    & )+)) 	6 	6FAsv;D 61gmmoo""3++221555  	 	IAv3v;;''  q1uc&kk22  A#)!9fQi5E$VXe_T-BHUOTXDY,Z%[%[\\H:-- ++huof&=xv?VWWZ__Ci''"x000"))+3E?4+@-5e_V-D+3E?4+@-5e_V-D*/Q--*9EMe_U]E^%fXe_X%>q%A%Adf+ +   * 	55tDDD&5&!!s    &44"9C--
C7:C7T
primary_idsecondary_id	add_aliasboolc                  K   | j         j                            t          j                  4 d{V }|                    d|           d{V }|                                 d{V }|st          d| d          |d         pd}|d	         pg }t          |t                    r|g}|                    d
|           d{V }	|	
                                 d{V }
d}|
D ]}|d         }||k    r|d         }|d         pi }|d         }t                              |          sF|dk    r$|                    d| d|||           d{V  n#|                    d| d|||           d{V  |dz  }g }|r|r|                    d|           d{V }|                                 d{V }|rt          |d	         pg           ng }t          |t                    r|g}t          t                              ||gz   |z                       }|                    d||           d{V  |}|                    d|           d{V  ddd          d{V  n# 1 d{V swxY w Y   |||dS )zXMerge secondary entity into primary: migrate relationships, add alias, delete secondary.r<   NzOMATCH (n) WHERE elementId(n) = $eid RETURN n.name AS name, n.aliases AS aliasesr	  zSecondary entity r%  r   r   r1  zMATCH (s)-[r]-(t) WHERE elementId(s) = $sid RETURN elementId(t) AS tid, type(r) AS rtype, properties(r) AS rprops, CASE WHEN startNode(r) = s THEN 'out' ELSE 'in' END AS direction)sidr   tidrtyperpropsr  outzUMATCH (p) WHERE elementId(p) = $pid MATCH (t) WHERE elementId(t) = $tid MERGE (p)-[r:z]->(t) SET r += $props)pidrc  r   zUMATCH (p) WHERE elementId(p) = $pid MATCH (t) WHERE elementId(t) = $tid MERGE (t)-[r:z]->(p) SET r += $propsr   z?MATCH (n) WHERE elementId(n) = $pid RETURN n.aliases AS aliasesrg  z<MATCH (n) WHERE elementId(n) = $pid SET n.aliases = $aliases)rg  r1  z3MATCH (n) WHERE elementId(n) = $sid DETACH DELETE n)r]  r   r1  )r6   rC   rD   r   rE   rF   r~   r}   r   rm   rX   r{   r|   rT   r   fromkeys)r9   r]  r^  r_  rD   
sec_resultsec_recsec_namesec_aliasesrels_result	rels_datar   relrc  rd  re  r  r1  
pri_resultpri_recnew_aliasess                        r   merge_entitiesz GraphAdminService.merge_entities5  s      ;%--x7N-OO N	 N	 N	 N	 N	 N	 N	SZ&{{>   +          J
 '--////////G O !M\!M!M!MNNNv,"H!),2K+s++ ,*m !(S !	 !, ! !      K *..00000000IH   %j*$$GX,",	*0077 %%!++F(-F F F 'Cv	 &           "++F(-F F F 'Cv	 &          A "$G &X &#*;;U" $/ $ $      
 !+ 1 1 3 3333333<CK$wy17R888gs++ (&iG"4==H:1E1S#T#TUUkkR"K "          & ++E           WN	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	 N	b %&.
 
 	
s   H(I--
I7:I7r  	source_id	target_idc                  K   |dz
  |z  }|r7||                                  v r!t                              |          rd| d}nd}g }||d}	|r|                    d           ||	d<   |r|                    d           ||	d	<   |rd
d                    |           nd}
| |
 d}| |
 d}| j        j                            t          j	                  4 d {V } |j
        |fi |	 d {V }|                                 d {V } |j
        |fi |	 d {V }|                                 d {V }|r|d         nd}d d d           d {V  n# 1 d {V swxY w Y   d |D             }||||dS )Nr   r   z]->(b)zMATCH (a)-[r]->(b)r   zelementId(a) = $sidrb  zelementId(b) = $tidrc  r   r   r   z RETURN elementId(r) AS id, type(r) AS rtype, properties(r) AS props, elementId(a) AS src_id, a.name AS src_name, labels(a) AS src_labels, elementId(b) AS tgt_id, b.name AS tgt_name, labels(b) AS tgt_labels ORDER BY rtype SKIP $skip LIMIT $limitz RETURN count(r) AS totalr<   r   r   c                    g | ]u}|d          |d         |d         |d         pdt          |d         pg           |d         |d         pdt          |d         pg           t          |d	         pi           d
	vS )r   rd  src_idsrc_namer   
src_labelstgt_idtgt_name
tgt_labelsr   )	r   r   ru  source_namer+   rv  target_namer,   r   )rT   r   rO   s     r   r"   z8GraphAdminService.list_relationships.<locals>.<listcomp>  s     
 
 
  g'
x[ }2!%ao&;!<!<x[ }2!%ao&;!<!<"1W:#344
 

 
 
r#   r   )rf   r{   r|   r   r   r6   rC   rD   r   rE   rF   rX   r~   )r9   r  ru  rv  r   r   r   r|   where_partsr   r   r  r  rD   r]   r^   r  r  r   r   s                       r   list_relationshipsz$GraphAdminService.list_relationships  s      qI% 	)D$;$;$=$===BUB[B[\dBeBe=4H444EE(E!#*.!C!C 	&4555%F5M 	&4555%F5M@KS<k!:!:<<<QS  5l 5 5 5 	  HHHH;%--x7N-OO 	; 	; 	; 	; 	; 	; 	;SZ&7;v8888888888F"KKMM))))))G!,\!D!DV!D!DDDDDDDL*1133333333I*3:Ig&&E	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	;
 
 
 
 
 9UUUs   A)E
E$'E$c                  K   ||                                  vrt          d|           t                              |          st          d|           | j        j                            t          j                  4 d {V }|	                    d| d|||pi            d {V }|
                                 d {V }|st          d          	 d d d           d {V  n# 1 d {V swxY w Y   |d         |d	         ||d
S )NzUnknown relationship type: zInvalid relationship type: r<   zVMATCH (a) WHERE elementId(a) = $sid MATCH (b) WHERE elementId(b) = $tid CREATE (a)-[r:zB]->(b) SET r += $props RETURN elementId(r) AS id, type(r) AS rtype)rb  rc  r   z!Source or target entity not foundr   rd  )r   r   ru  rv  )rf   r}   r{   r|   r6   rC   rD   r   rE   rF   r~   )r9   ru  rv  r  r   rD   r]   r   s           r   create_relationshipz%GraphAdminService.create_relationship  s      4224444E8EEFFF"((22 	GE8EEFFF;%--x7N-OO 
	F 
	F 
	F 
	F 
	F 
	F 
	FSZ";;>!)> > > 9J4D" '        F ''''''C F !DEEEE
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F 
	F d)L""	
 
 	
s   AC++
C58C5rel_idc                F   K   | j                             |           d {V S r5   )r6   delete_relationship_by_id)r9   r  s     r   delete_relationshipz%GraphAdminService.delete_relationship  s.      [::6BBBBBBBBBr#   c                0  K   | j         j                            t          j                  4 d {V }|                    d           d {V }|                                 d {V }d d d           d {V  n# 1 d {V swxY w Y   d |D             S )Nr<   a#  MATCH (d:Document {is_placeholder: true}) OPTIONAL MATCH (src:Document)-[:REFERENCES]->(d) WHERE src.is_placeholder IS NULL OR src.is_placeholder = false RETURN elementId(d) AS id, d.doc_id AS doc_id, d.doc_number AS doc_number, collect({doc_id: src.doc_id, title: src.title}) AS referencersc                h    g | ]/}|d          |d         pd|d         pdd |d         D             d0S )r   r  r   r  c                b    g | ],}|                     d           |d          pd|d         pdd-S )r  r   r  )r  r  r   )r    refs     r   r"   zBGraphAdminService.list_placeholders.<locals>.<listcomp>.<listcomp>	  sT          wwx(( "8}2S\=ORPP     r#   referencers)r   r  r  r  r   rO   s     r   r"   z7GraphAdminService.list_placeholders.<locals>.<listcomp>  sq     
 
 
  gH++o3    /     		 	
 
 
r#   rj   r\   s       r   list_placeholdersz#GraphAdminService.list_placeholders  sM     ;%--x7N-OO 		* 		* 		* 		* 		* 		* 		*SZ";;Q       F #KKMM))))))G		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		* 		*
 
 
 
 
 	
rl   placeholder_idreal_doc_idc                  K   | j         j                            t          j                  4 d{V }|                    d|           d{V }|                                 d{V st          d| d          |                    d|           d{V }|                                 d{V st          d	| d          |                    d
||           d{V }|                                 d{V }|r|d         nd}|                    d|           d{V  ddd          d{V  n# 1 d{V swxY w Y   |||dS )z^Migrate REFERENCES relationships from placeholder to a real document, then delete placeholder.r<   NzQMATCH (d:Document) WHERE elementId(d) = $pid AND d.is_placeholder = true RETURN drh  zPlaceholder r%  z*MATCH (d:Document {doc_id: $did}) RETURN d)didzReal document zMATCH (src)-[r:REFERENCES]->(ph:Document) WHERE elementId(ph) = $pid MATCH (real:Document {doc_id: $did}) CREATE (src)-[r2:REFERENCES]->(real) SET r2 = properties(r) DELETE r RETURN count(*) AS migrated)rg  r  r   r   z<MATCH (d:Document) WHERE elementId(d) = $pid DETACH DELETE d)r  r  r   )r6   rC   rD   r   rE   rF   r~   r}   )	r9   r  r  rD   r   
real_checkr   r   r   s	            r   link_placeholderz"GraphAdminService.link_placeholder  s      ;%--x7N-OO #	 #	 #	 #	 #	 #	 #	SZ!++7" &        E
 '''''' L !J!J!J!JKKK  '{{<  +          J $**,,,,,,,, K !I+!I!I!IJJJ $+;;. # $/ $ $      N '--////////C*-4s:1H ++N"          A#	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	L -&&.
 
 	
s   C6D;;
EEc                R  K   | j         j                            t          j                  4 d {V }|                    d|           d {V }|                                 d {V }d d d           d {V  n# 1 d {V swxY w Y   t          |o|d         dk              S )Nr<   zoMATCH (d:Document) WHERE elementId(d) = $pid AND d.is_placeholder = true DETACH DELETE d RETURN count(d) AS cntrh  r   r   )r6   rC   rD   r   rE   rF   r~   r`  )r9   r  rD   r]   r   s        r   delete_placeholderz$GraphAdminService.delete_placeholderA  sP     ;%--x7N-OO 	( 	( 	( 	( 	( 	( 	(SZ";;9 #	 '        F ''''''C	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( C*CJN+++s   8A==
B
B)r2   r   r   r3   )r   r3   )r   r`   r   r   )r   r   r   N)r   rm   r   rm   r   rm   r   rm   rM   rn   r   ro   )r   rm   r   ro   r   ro   )r   rm   r   ro   )r   NN)
r   rm   r   rm   r+   r   r,   r   r   ro   )r   ro   )r   r   r   ro   )NNr   r   r   )r   r   r   r   r   r   r   r   r   rm   r   ro   )r  rm   r   r  )r   rm   r   ro   r   ro   )r  rm   r   ro   r   ro   )r  rm   r   ro   )Nr+  r,  )r   r   r-  r.  r   r   r   r   )T)r]  rm   r^  rm   r_  r`  r   ro   )NNNr   r   )r  r   ru  r   rv  r   r   r   r   r   r   ro   r5   )
ru  rm   rv  rm   r  rm   r   r  r   ro   )r  rm   r   r`  )r  rm   r  rm   r   ro   )r  rm   r   r`  ) __name__
__module____qualname____doc__r:   rI   r_   rd   rf   rk   r   r   r   r   r   r   r   r   r   r  r  r#  r'  r*  r\  rt  r  r  r  r  r  r  r   r#   r   r1   r1   J   s        > > > >- - - -02
 2
 2
 2
hC C C C1 1 1 1
 
 
 
4 =?:> X  X  X  X  XDB B B BH/ / / />   6 -/*.*.: : : : :,, , , ,\/ / / /(7
 7
 7
 7
r
 
 
 
N !)BV BV BV BV BVH7
 7
 7
 7
r
 
 
 
8   + + + + !	m" m" m" m" m"f 	[
 [
 [
 [
 [
F  $ $ $:V :V :V :V :VB -1
 
 
 
 
>C C C C
 
 
 
4-
 -
 -
 -
^	, 	, 	, 	, 	, 	,r#   r1   )r
   r   r   r   r  )r  
__future__r   r   retypingr   
app.configr   app.core.graph_schema_loaderr   app.infrastructure.neo4j_clientr   r   app.utils.loggerr	   r  rG   compiler{   r   r'   r/   r1   r   r#   r   <module>r     s1    # " " " " "  				             3 3 3 3 3 3 K K K K K K K K ' ' ' ' ' '	H		 !bj!788 	 	 	 	      @, @, @, @, @, @, @, @, @, @,r#   