
    hJ                        S SK JrJrJrJr  S SKrS SKJr  S SKJr  S SK	r	S SK
J
r
Jr  S SKrS SKrS SKrS SKrS SKJrJr  S SKrS SKrS SKrS SKrS SK
J
r
Jr  \R.                  " \5      r " S S5      rg)	    )capture_exceptioncapture_messageset_tagset_contextN)MongoClientObjectIddatetime	timedelta)MONGODB_URI
MONGODB_DBc                      \ rS rSrS rS^S jrS rS rS rS r	S r
S	 rS^S
 jrS rS rS rS rS rS rS rS rS rS_S jrS`S jrS rSaS jrS rS rSbS jrS rS rS rS rS  r S! r!S" r"S# r#S$ r$ScS% jr%ScS& jr&S' r'SdS( jr(SeS) jr)SfS* jr*S`S+ jr+SfS, jr,SgS- jr-ShS. jr.S/ r/SiS0 jr0SiS1 jr1SiS2 jr2SjS3 jr3SiS4 jr4SiS5 jr5SiS6 jr6S7 r7S8 r8S9 r9SiS: jr:SiS; jr;SiS< jr<S= r=S> r>S? r?SiS@ jr@SA rASB rBSC rCSD rDSE rESF rFSG rSH rGSiSI jrHSJ rISK rJSL rKSiSM jrLSN rMSO rNSP rOSkSQ jrPSlSR jrQSS rRST rSSU rTSmSV jrUSdSW jrVSX rWSY rXSnSZ jrYS[ rZS\ r[S]r\g)oMongoHandler   c                 j    [        [        SS9U l        U R                  R                  5         U R                  [           U l        U R
                  R                  U l        U R
                  R                  U l	        U R
                  R                  U l        U R
                  R                  U l        [        R                  S5        g ! [         R"                  R$                  [         R"                  R&                  4 a1  n[        R)                  S[+        U5       35        [-        S5      eS nAff = f)Ni  )serverSelectionTimeoutMSz!Successfully connected to MongoDBzFailed to connect to MongoDB: zDCould not connect to MongoDB. Please check your connection settings.)r   r   clientserver_infor   db
test_cases
collection	analyticsanalytics_collectionuser_sessionsuser_sessions_collectionusersusers_collectionloggerinfopymongoerrorsConnectionFailureServerSelectionTimeoutErrorerrorstr	Exception)selfes     7D:\Projects\AI-TestCaseGenerator\utils\mongo_handler.py__init__MongoHandler.__init__   s    	d%kDQDKKK##%kk*-DG"gg00DO(,(9(9D%,0GG,A,AD)$(GGMMD!KK;<00'..2\2\] 	dLL9#a&BCbcc	ds   CC	 	8D2,D--D2c           	          U R                   R                  SUR                  5       05      nU(       a  SSS.$ [        R                  " 5       n[        R
                  " UR                  S5      U5      n[        [        R                  " 5       5      UR                  5       UUU[        R                  " 5       SSS.nU R                   R                  U5        [        R                  S	U S
U 35        SSUS   US   US   US   S.S.$ ! [         a0  n	[        R!                  S[        U	5       35        SSS.s Sn	A	$ Sn	A	ff = f)zCreate a new user accountemailF#User with this email already existssuccessmessageutf-8NT)_idr.   passwordnamerole
created_at
last_login	is_activezSuccessfully created user: z with role: User created successfullyr4   r6   r7   idr.   r6   r7   )r1   r2   userzError creating user: Failed to create user)r   find_onelowerbcryptgensalthashpwencoder&   uuiduuid4r   utcnow
insert_oner   r    r'   r%   )
r(   r.   r5   r6   r7   existing_usersalthashed_passworduser_docr)   s
             r*   create_userMongoHandler.create_user&   s4   %	J 11::GU[[];STM#(5Z[[ >>#D$mmHOOG,DdKO 4::<(+&oo/"!	H !!,,X6KK5eWLOP6"5/%g.$V,$V,		 	  	JLL0Q9:$1HII	Js#   6D	 CD	 	
E%D>8E>Ec                 D    U R                   R                  SS05      nU(       a  SSS.$ U R                  XUSS9nUS   (       a  [        R	                  SU 35        S	S
S.$ U$ ! [
         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z:Create the initial admin user (should only be called once)r7   adminFzAdmin user already existsr0   )r7   r1   z!Successfully created admin user: TzAdmin user created successfullyzError creating admin user: Failed to create admin userN)r   r@   rN   r   r    r'   r%   r&   )r(   r.   r5   r6   existing_adminresultr)   s          r*   create_admin_userMongoHandler.create_admin_userO   s    	P!22;;VW<MNN#(5PQQ %%et'%JFi ?wGH#'4UVV 	PLL6s1vh?@$1NOO	Ps(   (A% 7A% #A% %
B/%BBBc           	          U R                   R                  SUR                  5       05      nU(       d  SSS.$ UR                  SS5      (       d  SSS.$ [        R
                  " UR                  S5      US	   5      (       a  U R                   R                  S
US
   0SS[        R                  " 5       005        U R                  US
   5      n[        R                  SU 35        SSUS
   US   US   UR                  SS5      S.US.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zAuthenticate user loginr.   FzInvalid email or passwordr0   r:   TzAccount is deactivatedr3   r5   r4   $setr9   z!Successfully authenticated user: zLogin successfulr6   r7   r>   r<   )r1   r2   r>   tokenzError authenticating user: zAuthentication failedN)r   r@   rA   getrB   checkpwrE   
update_oner   rH   generate_jwt_tokenr   r    r'   r%   r&   )r(   r.   r5   r>   rY   r)   s         r*   authenticate_userMongoHandler.authenticate_userc   sW   &	J((117EKKM2JKD#(5PQQ 88K..#(5MNN ~~hoog6Z8HII%%00DK(lHOO,=>? //U<?wGH#1"5k!%g $V $ 8	 #
 
 $)5PQQ 	JLL6s1vh?@$1HII	Js/   6D D B6D D 
E%E EEc                     U R                   R                  SU05      nU(       a+  UR                  SS5      (       a  UR                  S5      S:H  $ g! [         a+  n[        R                  S[        U5       35         SnAgSnAff = f)	zCheck if a user is an adminr4   r:   Tr7   rQ   FzError checking admin status: Nr   r@   rZ   r'   r   r%   r&   r(   user_idr>   r)   s       r*   is_adminMongoHandler.is_admin   sw    	((115'2BCDd33xx'722 	LL8QAB	s   AA 
B!BBc                     U R                  U5      (       d  SSS.$ [        U R                  R                  0 SSSSSSSSS.5      5      nU H`  nSU;   a  [	        US   5      US'   SU;   a  US   R                  5       US'   SU;   d  M>  US   (       a  US   R                  5       OS	US'   Mb     S
US.$ ! [         a0  n[        R                  S[	        U5       35        SSS.s S	nA$ S	nAff = f)zGet all users (admin only)F)Access denied. Admin privileges required.r0      r4   r.   r6   r7   statusr8   r9   r:   r4   r8   r9   NT)r1   r   zError getting all users: Failed to retrieve users)	rd   listr   findr&   	isoformatr'   r   r%   )r(   admin_user_idr   r>   r)   s        r*   get_all_usersMongoHandler.get_all_users   s   	M==//#(5`aa..33B
9 
 
E D="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&   $e44 	MLL4SVH=>$1KLL	Ms)   B6 A*B6 *B6 6
C0 %C+%C0+C0c                 ~    U R                  U5      (       d  SSS.$ US;  a  SSS.$ U R                  R                  SU0SSU005      nUR                  S	:  a#  [        R                  S
U SU 35        SS
U 3S.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zUpdate user role (admin only)Frg   r0   rQ   r>   'Invalid role. Must be 'admin' or 'user'r4   rX   r7   r   User role updated to 
 by admin Tz User not found or role unchangedzError updating user role: zFailed to update user roleN	rd   r   r\   modified_countr   r    r'   r%   r&   )r(   ro   target_user_idnew_rolerT   r)   s         r*   update_user_roleMongoHandler.update_user_role   s    	O==//#(5`aa 00#(5^__ **55'&(+,F
 $$q(3H:ZWX#'6KH:4VWW#(5WXX 	OLL5c!fX>?$1MNN	Os.   B 
B AB =B 
B<%B71B<7B<c                     U R                  U5      (       d  SSS.$ U R                  R                  SU0SSU005      nUR                  S:  a/  U(       a  SOS	n[        R                  S
U SU 35        SS
U S3S.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z&Toggle user active status (admin only)Frg   r0   r4   rX   r:   r   	activateddeactivatedzUser rv   Tz successfullyz"User not found or status unchangedzError toggling user status: zFailed to update user statusNrw   )r(   ro   ry   r:   rT   status_textr)   s          r*   toggle_user_statusMongoHandler.toggle_user_status   s    	Q==//#(5`aa **55'+y12F
 $$q(-6kMeK=
=/JK#'eK=4VWW#(5YZZ 	QLL7Ax@A$1OPP	Qs)   B A B >B 
B=%B82B=8B=c                 <    U R                  U5      (       d  SSS.$ U R                  X#XE5      nUS   (       a&  [        R                  SU SU SU 35        SS	U 3S.$ U$ ! [         a0  n[        R                  S
[        U5       35        SSS.s SnA$ SnAff = f)z"Create a new user account by adminFrg   r0   r1   zUser created by admin : z with role Tz$User created successfully with role Error creating user by admin: r?   N)rd   rN   r   r    r'   r%   r&   )r(   ro   r.   r5   r6   r7   rT   r)   s           r*   create_user_by_admin!MongoHandler.create_user_by_admin   s    	J==//#(5`aa %%etBFi 4]O2eWKX\W]^_#'6Z[_Z`4abb 	JLL9#a&BC$1HII	Js)   A! AA! A! !
B+%BBBc                 l    U R                  U5      (       d  SSS.$ X:X  a  SSS.$ U R                  R                  SU05      nUR                  S:  a   [        R                  SU SU 35        S	S
S.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zDelete a user (admin only)Frg   r0   zCannot delete your own accountr4   r   zUser deleted by admin r   TzUser deleted successfullyUser not foundzError deleting user: zFailed to delete userN)	rd   r   
delete_onedeleted_countr   r    r'   r%   r&   )r(   ro   ry   rT   r)   s        r*   delete_userMongoHandler.delete_user   s    	J==//#(5`aa .#(5UVV **55un6MNF##a'4]O2nEUVW#'4OPP#(5EFF 	JLL0Q9:$1HII	Js.   A9 	A9 AA9 4A9 9
B3%B.(B3.B3c                 J    U R                  U5      (       d  SSS.$ U R                  R                  0 5      nU R                  R                  SS05      nU R                  R                  SS05      nU R                  R                  SS05      nS	S
KJnJn  UR
                  " 5       R                  SS	S	S	S	S9nU R                  R                  SSU005      n	UUX#-
  UUU	S.n
SU
S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z Get user statistics (admin only)Frg   r0   r:   Tr7   rQ   r>   r   r
   rh   dayhourminutesecondmicrosecondr8   $gte)total_usersactive_usersinactive_usersadmin_usersregular_usersnew_users_this_month)r1   
statisticszError getting user statistics: z"Failed to retrieve user statisticsN)rd   r   count_documentsr   r   rH   replacer'   r   r%   r&   )r(   ro   r   r   r   r   r   r   	first_dayr   statsr)   s               r*   get_user_statistics MongoHandler.get_user_statistics  s=   !	W==//#(5`aa //??CK  00@@+tATUL //??@QRK 11AA66BRSM 5 )11aaRSab1cI#'#8#8#H#H,Y_ajXkIl#m   + ,"-"<*!.(<E  $599 	WLL:3q6(CD$1UVV	Ws#   C( C
C( (
D"2%DD"D"c                     U R                   R                  SU0SS05      nU(       a`  SU;   a  [        US   5      US'   SU;   a  US   R                  5       US'   SU;   a"  US   (       a  US   R                  5       OSUS'   SUS.$ S	S
S.$ ! [         a0  n[
        R                  S[        U5       35        S	SS.s SnA$ SnAff = f)zGet user details by IDr4   r5   r   r8   r9   NTr1   r>   Fr   r0   zError getting user by ID: zFailed to retrieve user)r   r@   r&   rn   r'   r   r%   rb   s       r*   get_user_by_idMongoHandler.get_user_by_id=  s    	L((115'2BAE D D="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&#'66#(5EFF 	LLL5c!fX>?$1JKK	Ls$   BB 	B 
C%C=CCc                     U R                   R                  SU05      nU(       d  SSS.$ UR                  S5      S:w  a
  X:w  a  SSS.$ SS	/nUR                  S5      S:X  a  UR                  SS	/5        UR	                  5        VVs0 s H  u  pgXe;   d  M  Xg_M     nnnU(       d  SS
S.$ U R                   R                  SU0SU05      n	U	R                  S:  a   [        R                  SU SU 35        SSS.$ SSS.$ s  snnf ! [         a0  n
[        R                  S[        U
5       35        SSS.s Sn
A
$ Sn
A
ff = f)zYUpdate user profile (admin can update any user, regular users can only update themselves)r4   FzCurrent user not foundr0   r7   rQ   z4Access denied. You can only update your own profile.r6   r.   zNo valid fields to updaterX   r   zUser profile updated by r   TzProfile updated successfullyzNo changes madezError updating user profile: zFailed to update profileN)r   r@   rZ   extenditemsr\   rx   r   r    r'   r%   r&   )r(   current_user_idry   updatescurrent_userallowed_fieldskvfiltered_updatesrT   r)   s              r*   update_user_profile MongoHandler.update_user_profileU  sl   #	M00995/:RSL#(5MNN '727X#(5kll %g.N'72%%vw&78 29XADWX##(5PQQ **55')*F
 $$q(66Gr.IYZ[#'4RSS#(5FGG  Y"  	MLL8QAB$1KLL	MsM   (D D 
?D 	DDD -AD =D D 
E%D=7E=Ec                 T    U R                   R                  SU05      nU(       d  SSS.$ [        R                  " UR	                  S5      US   5      (       d  SSS.$ [        R
                  " 5       n[        R                  " UR	                  S5      U5      nU R                   R                  SU0SSU005      nUR                  S	:  a  [        R                  S
U 35        SSS.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zChange user passwordr4   Fr   r0   r3   r5   zCurrent password is incorrectrX   r   zPassword changed for user: TzPassword changed successfullyzFailed to update passwordzError changing password: zFailed to change passwordN)r   r@   rB   r[   rE   rC   rD   r\   rx   r   r    r'   r%   r&   )	r(   rc   current_passwordnew_passwordr>   rK   hashed_new_passwordrT   r)   s	            r*   change_passwordMongoHandler.change_password|  s,   	N((115'2BCD#(5EFF >>"2"9"9'"BDDTUU#(5TUU >>#D"(--0C0CG0Ld"S **55 *&9:;F
 $$q(9'CD#'4STT#(5PQQ 	NLL4SVH=>$1LMM	Ns/   (C- 2C- B	C- (C- -
D'7%D"D'"D'c                     U R                  U5      (       d  SSS.$ [        R                  " 5       n[        R                  " UR	                  S5      U5      nU R
                  R                  SU0SSU005      nUR                  S:  a   [        R                  S	U S
U 35        SSS.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zReset user password by adminFrg   r0   r3   r4   rX   r5   r   zPassword reset by admin z for user: TPassword reset successfullyr   z#Error resetting password by admin: Failed to reset passwordN)rd   rB   rC   rD   rE   r   r\   rx   r   r    r'   r%   r&   )r(   ro   ry   r   rK   r   rT   r)   s           r*   reset_password_by_admin$MongoHandler.reset_password_by_admin  s    	M==//#(5`aa >>#D"(--0C0CG0Ld"S **55'*&9:;F
 $$q(6}o[Q_P`ab#'4QRR#(5EFF 	MLL>s1vhGH$1KLL	Ms)   B/ BB/ *B/ /
C)9%C$C)$C)c                 *    SSK nSSKnSSKJnJn  UR	                  S5      nUR
                  " UR                  5       5      R                  5       nUR                  " 5       U" SS9-   nUUUUR                  " 5       SS.n	U R                  R                  R                  U	5      n
U
R                  (       a  [        R                  S	U 35        S
XhS.$ SSS.$ ! [         a0  n[        R!                  S[#        U5       35        SSS.s SnA$ SnAff = f)z1Create a password reset token for the given emailr   Nr
       rh   hoursF)r.   
token_hash
expires_atr8   usedz(Password reset token created for email: T)r1   rY   r   zFailed to create reset tokenr0   z%Error creating password reset token: )secretshashlibr   r   token_urlsafesha256rE   	hexdigestrH   r   password_reset_tokensrI   inserted_idr   r    r'   r%   r&   )r(   r.   r   r   r   r   rY   r   r   
reset_datarT   r)   s               r*   create_password_reset_token(MongoHandler.create_password_reset_token  s     	Q4 ))"-E 7AACJ "*YQ-??J ((&oo/J WW22==jIF!!FugNO#'%RR#(5STT 	QLL@QIJ$1OPP	Qs$   CC C 
D"%DDDc                     SSK nSSKJn  UR                  " UR                  5       5      R	                  5       nU R
                  R                  R                  USSUR                  " 5       0S.5      nU(       a  SUS   S	.$ SS
S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z<Verify a password reset token and return user email if validr   Nr   F$gtr   r   r   Tr.   )r1   r.   Invalid or expired reset tokenr0   z&Error verifying password reset token: zFailed to verify reset token)r   r   r   rE   r   r   r   r@   rH   r'   r   r%   r&   )r(   rY   r   r   r   reset_recordr)   s          r*   verify_password_reset_token(MongoHandler.verify_password_reset_token  s    	Q) !7AACJ  7788AA($hoo&78C L #',w2GHH#(5UVV 	QLLA#a&JK$1OPP	Qs$   B B B 
C%B=7C=Cc                      SSK nSSKJn  UR                  " UR                  5       5      R	                  5       nU R
                  R                  R                  USSUR                  " 5       0S.5      nU(       d  SSS.$ US	   n[        R                  " 5       n[        R                  " UR                  S
5      U5      n	U R                  R                  S	U0SSU	005      n
U
R                  S:  a\  U R
                  R                  R                  SUS   0SSUR                  " 5       S.05        [        R!                  SU 35        SSS.$ SSS.$ ! ["         a0  n[        R%                  S['        U5       35        SSS.s SnA$ SnAff = f)z-Use a password reset token to change passwordr   Nr   Fr   r   r   r0   r.   r3   rX   r5   r4   T)r   used_atz'Password reset successfully for email: r   r   z"Error using password reset token: r   )r   r   r   rE   r   r   r   r@   rH   rB   rC   rD   r   r\   rx   r   r    r'   r%   r&   )r(   rY   r   r   r   r   r   r.   rK   r   user_resultr)   s               r*   use_password_reset_token%MongoHandler.use_password_reset_token  s   +	M) !7AACJ  7788AA($hoo&78C L  #(5UVV )E >>#D"(--0C0CG0Ld"S //::% *&9:;K
 ))A---88L/0dx7HIJ
 EeWMN#'4QRR#(5EFF 	MLL=c!fXFG$1KLL	Ms+   A=E  CE E 
F%FFFc                 *    U R                  U5      (       d  SSS.$ SSUSS.0SUSS.0/0n[        U R                  R                  US	S
05      R	                  U5      5      nU H`  nSU;   a  [        US   5      US'   SU;   a  US   R                  5       US'   SU;   d  M>  US   (       a  US   R                  5       OSUS'   Mb     SU[        U5      S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z*Search users by name or email (admin only)Frg   r0   z$orr6   i)z$regexz$optionsr.   r5   r   r4   r8   r9   NT)r1   r   countzError searching users: zFailed to search users)rd   rl   r   rm   limitr&   rn   lenr'   r   r%   )r(   ro   queryr   search_queryr   r>   r)   s           r*   search_usersMongoHandler.search_users"  s<   	K==//#(5`aa 3?@C@AL ..33LAC uU|E
 D="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&   $ec%jII 	KLL23q6(;<$1IJJ	Ks)   C BC #4C 
D"%DDDNc           
          U R                  U5      (       d  SSS.$ 0 nU(       a  X$S'   [        U R                  R                  USSSSS.5      R	                  SS5      R                  U5      5      nU H8  nS	U;   a  [        US	   5      US	'   SU;   d  M"  US   R                  5       US'   M:     S
U[        U5      S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z#Get user activity logs (admin only)Frg   r0   rc   rh   )rc   r8   source_typerj   r8   r4   T)r1   logsr   z"Error getting user activity logs: z Failed to retrieve activity logsN)rd   rl   r   rm   sortr   r&   rn   r   r'   r   r%   )r(   ro   rc   r   r   r   logr)   s           r*   get_user_activity_logs#MongoHandler.get_user_activity_logsE  s   	U==//#(5`aa E#*i  ,,U 	5 
 tL"%eeEl4D C<!$SZCJ3&(+L(9(C(C(EC%	   $TCIFF 	ULL=c!fXFG$1STT	Us)   C  A6C  (C   
C:
%C5/C:5C:c           	          U R                  U5      (       d  SSS.$ [        U[        5      (       d  SSS.$ Sn/ nU H  nUR                  S5      nUR                  S5      nU(       a  U(       d  UR	                  SU 35        MI  US	;  a  UR	                  S
U SU 35        Mh  U R
                  R                  SU0SSU005      nUR                  S:  a%  US-  n[        R                  SU SU SU 35        M  UR	                  SU 35        M     SSU S3UUS.$ ! [         a0  n	[        R                  S[        U	5       35        SSS.s Sn	A	$ Sn	A	ff = f)z#Bulk update user roles (admin only)Frg   r0   z.Invalid format. Expected list of user updates.r   rc   r7   z$Missing user_id or role for update: rs   zInvalid role 'z' for user r4   rX   rh   ru   rv   r   zFailed to update role for user TzBulk update completed. z users updated.)r1   r2   updated_countr"   z!Error in bulk update user roles: zFailed to perform bulk updateN)rd   
isinstancerl   rZ   appendr   r\   rx   r   r    r'   r%   r&   )
r(   ro   user_updatesr   r"   updaterc   rz   rT   r)   s
             r*   bulk_update_user_roles#MongoHandler.bulk_update_user_rolesf  s   -	R==//#(5`aa lD11#(5effMF& **Y/!::f-hMM$H"QR#44MMN8*Ky"QR ..99G$fh/0
 ((1,!Q&MKK"7zM?Z\]d\e fgMM$CG9"MN- '2  4]O?S!. 	   	RLL<SVHEF$1PQQ	Rs(   D D C'D 
E)%EEEc                     U R                  U5      (       d  SSS.$ [        U R                  R                  0 SS05      5      nU H`  nSU;   a  [	        US   5      US'   SU;   a  US   R                  5       US'   SU;   d  M>  US   (       a  US   R                  5       OS	US'   Mb     US
:X  a  SUS
S.$ US:X  a  SS	KnSS	KnUR                  5       nU(       aC  US   R                  5       nUR                  XxS9n	U	R                  5         U	R                  U5        UR                  5       n
UR                  5         SU
SS.$ SSS.$ ! [         a0  n[         R#                  S[	        U5       35        SSS.s S	nA$ S	nAff = f)zExport user data (admin only)Frg   r0   r5   r   r4   r8   r9   NjsonT)r1   dataformatcsv)
fieldnameszUnsupported format typezError exporting user data: zFailed to export user data)rd   rl   r   rm   r&   rn   r   ioStringIOkeys
DictWriterwriteheader	writerowsgetvaluecloser'   r   r%   )r(   ro   format_typer   r>   r   r   outputr   writercsv_datar)   s               r*   export_user_dataMongoHandler.export_user_data  s   *	O==//#(5`aa ..33BA9  E
 D="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&  f$#'&II%!&qJ ^^F^JF&&($$U+!??,#'UKK#(5NOO 	OLL6s1vh?@$1MNN	Os6   E	 A#E	 1E	 6BE	 E	 	
F%E>8F>Fc                      U R                   R                  SU05      nU(       d  SSS.$ [        U R                  R	                  SU0SSSSSS.5      R                  SS	5      R                  S
5      5      nU H8  nSU;   a  [        US   5      US'   SU;   d  M"  US   R                  5       US'   M:     U R                  R                  SU05      nSSK
J
nJn  UR                  " 5       R                  SSSSSS9nU R                  R                  USU0S.5      n	U R                  R                  SU0SSSS.5      n
U
(       a3  SU
;   a  [        U
S   5      U
S'   SU
;   a  U
S   R                  5       U
S'   US   US   US   UR                  SS5      UR                  S5      (       a  US   R                  5       OSUR                  S5      (       a  US   R                  5       OSS.UU	U
S.US.nUR                  S5      S:X  aE  U R                  U5      nUS   (       a  US   US'   U R!                  US
S9nUS   (       a  US   US '   S!US".$ ! ["         a0  n[$        R'                  S#[        U5       35        SS$S.s SnA$ SnAff = f)%.Get user dashboard data with role-based accessr4   Fr   r0   rc   rh   r4   titler8   r   rj   r8   r   
   r   r
   r   r   rc   r8   )r4   r  r8   r6   r.   r7   r>   Nr9   r=   r6   r.   r7   r8   r9   total_test_cases
this_monthlast_generated)	user_infor   recent_test_casesrQ   r1   r   admin_statistics)r   r   recent_activityTr1   dashboard_data#Error getting user dashboard data: !Failed to retrieve dashboard data)r   r@   rl   r   rm   r   r   r&   rn   r   r   r   rH   r   rZ   r   r   r'   r   r%   )r(   rc   r>   user_test_cases	test_caser  r   r   r   this_month_countr  r  admin_statsr  r)   s                  r*   get_user_dashboard_data$MongoHandler.get_user_dashboard_data  s   I	V((115'2BCD#(5EFF #4??#7#7G$AQqTUV$ d<$UU2Y0O -	I%'*9U+;'<Ie$9,.7.E.O.O.QIl+	 -  $>>	7?ST 5 )11aaRSab1cI#>>"%y1@   "__55G$AQ7N
 N*,/u0E,FN5)>13A,3O3Y3Y3[N<0 u+ L!'] HHVV4DHHH\DZDZ$|"4">">"@`dDHHH\DZDZ$|"4">">"@`d )9"2&4
 &5N$ xx7*"66w?y)9D\9RN#56 #'"="=gR"="P"9-8G8ON#45#~FF 	VLL>s1vhGH$1TUU	Vs*   (I A,I F7I 
J%JJJc                     U R                  U5      (       d  SSS.$ U R                  R                  0 5      nU R                  R                  0 5      nU R                  R                  0 5      n[        U R                  R                  0 SSSSSS.5      R                  SS5      R                  S5      5      nU H8  nS	U;   a  [        US	   5      US	'   SU;   d  M"  US   R                  5       US'   M:     U R                  U5      nUS
-  US-  US-  S.nUUUUUS   (       a  UR                  S0 5      O0 USS.n	SU	S.$ ! [         a0  n
[        R                  S[        U
5       35        SSS.s Sn
A
$ Sn
A
ff = f)z Get system overview (admin only)Frg   r0   rh   )r4   r  r8   rc   r   r8   r   r  r4   i   i   i   )test_cases_size
users_sizeanalytics_sizer1   r   healthy)r  r   total_analyticsr  user_statisticsstorage_infosystem_healthT)r1   system_overviewzError getting system overview: z"Failed to retrieve system overviewN)rd   r   r   r   r   rl   rm   r   r   r&   rn   r   rZ   r'   r   r%   )r(   ro   r  r   r'  r  r  
user_statsr)  r+  r)   s              r*   get_system_overview MongoHandler.get_system_overview  s   2	W==//#(5`aa  $>>rB//??CK"77GGKO !%T__%9%9" ? & tL"%eeBi!1 /	I%'*9U+;'<Ie$9,.7.E.O.O.QIl+	 / 11-@J $4d#:)C/"1D"8L %5*#2#4GQR[G\:>>,#Cbd ,!*O  $HH 	WLL:3q6(CD$1UVV	Ws*   E B;E A$E 
E;%E60E;6E;c                 F    U R                  U5      (       d  SSS.$ US-
  U-  nU R                  R                  0 5      n[        U R                  R	                  0 SSSSSSSSS.5      R                  SS5      R                  U5      R                  U5      5      nU H  nSU;   a  [        US   5      US'    S	S
K	J	n  SU;   a*  [        US   U5      (       a  US   R                  5       US'   SU;   a@  US   b  [        US   U5      (       a$  US   (       a  US   R                  5       OSUS'   M  M  M     XS-   S-
  U-  n	SUUUUU	X):  US:  S.S.$ ! [         a     M  f = f! [         a0  n
[        R                  S[        U
5       35        SSS.s Sn
A
$ Sn
A
ff = f)z*Get all users with pagination (admin only)Frg   r0   rh   ri   r8   r   r4   r   r   r9   NT)current_pageper_pager   total_pageshas_nexthas_prev)r1   r   
paginationzError getting paginated users: rk   )rd   r   r   rl   rm   r   skipr   r&   r   r   rn   r'   r   r%   )r(   ro   pager1  r6  r   r   r>   _dtr2  r)   s              r*   get_all_users_paginated$MongoHandler.get_all_users_paginatedH  s   :	M==//#(5`aa 1H(D //??CK ..33B
9 
 tL"%dd4jx
BE D="%d5k"2DK8#t+
4;Ms0S0S-1,-?-I-I-K\*#t+l1C1KzZ^_kZlnqOrOrOST`OaT,-?-I-I-Kgk\* Ps+  '1A5(BK  $( (#.#. $ 2 $q  ! (  	MLL:3q6(CD$1KLL	MsH   E& BE& 9A8E1#E& 
E#E& "E##E& &
F 0%FF F c                     U R                  U5      (       d  SSS.$ Sn U R                  R                  S5        0 n/ SQnU HT  n US:X  a  U R                  nO%US	:X  a  U R
                  nOUS
:X  a  U R                  nWR                  0 5      nSUS.X5'   MV     SSK	J	n	J
n
  U	R                  " 5       U
" SS9-
  nU R                  R                  SSU005      U R
                  R                  SSU005      U R                  R                  SSU005      S.nSnUS:X  a  SnO'[        S UR                  5        5       5      (       a  SnSUUUUU	R                  " 5       R                  5       S.S.$ ! [         a    Sn GNFf = f! [         a  nS[        U5      S.X5'    SnAGMc  SnAff = f! [         a0  n[        R!                  S[        U5       35        SSS.s SnA$ SnAff = f)%Get system health status (admin only)Frg   r0   r&  ping	unhealthy)r   r   r   r   r   r   rj   document_count)rj   r%   Nr   r
   rh   daysr8   r   r9   )new_users_24hnew_test_cases_24hactive_users_24hcriticalc              3   0   #    U  H  oS    S:H  v   M     g7f)rj   r>  N ).0cols     r*   	<genexpr>1MongoHandler.get_system_health.<locals>.<genexpr>  s     Y=Xc]k1=X   warningT)overall_statusdatabase_statuscollections_statusr  	timestamp)r1   r*  zError getting system health: z Failed to retrieve system health)rd   r   commandr'   r   r   r   r   r&   r   r   nowanyvaluesrn   r   r%   )r(   ro   	db_statusrQ  collectionscollection_namer   r   r)   r   r   	yesterdayr  overall_healths                 r*   get_system_healthMongoHandler.get_system_health  s   C	U==//#(5`aa "I('
 "$>K#.&'1%)%:%:
(L8%)__
(K7%)%>%>
 '66r:E"+*/;&7 $/, 5 )::I "&!6!6!F!FW]_hViGj!k&*oo&E&E|V\^gUhFi&j$($9$9$I$I<Z`bkYlJm$nO 'NK'!+Y=O=V=V=XYYY!*  &4'0*<'6!)!9!9!;"	 	[  ('	(, ! "-!$Q;&77D  	ULL8QAB$1STT	Usp   F. F. E2 F. AFCF. 2F>F. FF. 
F+F&F. &F++F. .
G(8%G#G(#G(c           
          U R                  U5      (       d  SSS.$ SSKJnJn  U R                  R	                  0 5      nU R                  R	                  SS05      nU R                  R	                  SS05      nU R                  R	                  S	S
05      nUR
                  " 5       U" SS9-
  nU R                  R	                  SSU005      n	SSSS0SS0S.0SSSSSS.0SS0SSSS SSS!.0S"S#S$00/n
[        U R                  R                  U
5      5      nU HO  nSU;   a  [        US   5      US'   S%U;   a  [        US%   5      US%'   S&U;   d  M9  US&   R                  5       US&'   MQ     SS'SS0S(.0/n[        U R                  R                  U5      5      nS
UUUUU	S).US*S+ UUR
                  " 5       R                  5       S,.S-.$ ! [         a0  n[        R                  S.[        U5       35        SS/S.s S*nA$ S*nAff = f)0z(Get detailed user analytics (admin only)Frg   r0   r   r
   r7   rQ   r>   r:   T   rA  r8   r   $group$user_id$sumrh   $max$created_at)r4   test_case_countlast_activityz$lookupr   r4   r  )from
localFieldforeignFieldas$unwindz
$user_info$project$_idz$user_info.namez$user_info.email)rc   	user_name
user_emailre  rf  $sortre  r   rc   rf  $source_typer4   r   )r   r   r   r   users_created_30dNr  )r(  user_activitysource_distributiongenerated_at)r1   r   z'Error getting detailed user analytics: z!Failed to retrieve user analytics)rd   r   r   r   r   rT  rl   r   	aggregater&   rn   r'   r   r%   )r(   ro   r   r   r   r   r   r   thirty_days_agors  pipelinert  activitysource_pipelineru  r)   s                   r*   get_detailed_user_analytics(MongoHandler.get_detailed_user_analytics  s   \	V==//#(5`aa4 //??CK//??@QRK 11AA66BRSM00@@+tATUL 'llnyb/AAO $ 5 5 E E|V\^mUnFo p
 ),2A;*0-)@  '&+(-)	  | #)%6&8+,)*! /49HB !!:!:8!DEM *H$&)(5/&:HUO(*-hy.A*BHY'"h.080I0S0S0UH_- * -"(!O #'t'@'@'Q"R   (3'2)6(4->( &33B%7+>$,LLN$<$<$>    	VLLB3q6(KL$1TUU	Vs*   G D2G A7G 
H%H :H Hc           	          U R                  U5      (       d  SSS.$ / SQnU H  nXB;  d  X$   (       a  M  SSU 3S.s  $    U R                  R                  SUS   05      nU(       a  SSS.$ U R                  US   5      nUS	   US   UUR	                  S
S5      UR	                  SS5      [
        R                  " 5       SSS.nU R                  R                  U5      nUR                  (       a  SS[        UR                  5      S.$ SSS.$ ! [         a0  n	[        R                  S[        U	5       35        SSS.s Sn	A	$ Sn	A	ff = f)z'Create a new user by admin (admin only)Frg   r0   )r6   r.   r5   zMissing required field: r.   r/   r5   r6   r7   r>   r:   TNactive)r6   r.   r5   r7   r:   r8   r9   rj   r;   )r1   r2   rc   r?   r   )rd   r   r@   hash_passwordrZ   r   rT  rI   r   r&   r'   r   r%   )
r(   ro   	user_datarequired_fieldsfieldrJ   rL   rM   rT   r)   s
             r*   r   r   -  si   -	J==//#(5`aa <O()1A1A',;STYSZ9[\\ )
 !11::GYwEW;XYM#(5Z[[ #00:1FGO "&)"7++!ff5&]];=&lln""	H **55h?F!!#:"6#5#56  $)5LMM 	JLL9#a&BC$1HII	Js:   D D 	D  -D .BD D 
E
%E?E
E
c           	          U R                  U5      (       d  SSS.$ SSKJn  [        U R                  R	                  0 SS05      5      nU H`  nSU;   a  [        US   5      US'   SU;   a  US   R                  5       US'   S	U;   d  M>  US	   (       a  US	   R                  5       OS
US	'   Mb     [        U R                  R	                  0 5      5      nU H8  nSU;   a  [        US   5      US'   SU;   d  M"  US   R                  5       US'   M:     [        U R                  R	                  0 5      5      nU H8  nSU;   a  [        US   5      US'   SU;   d  M"  US   R                  5       US'   M:     UR                  " 5       R                  5       USS.UUU[        U5      [        U5      [        U5      S.S.n	SU	S.$ ! [         a0  n
[        R                  S[        U
5       35        SSS.s S
n
A
$ S
n
A
ff = f)zExport system data (admin only)Frg   r0   r   r   r5   r4   r8   r9   NrR  z1.0)exported_atexported_byversion)r   r  r'  )export_infor   r   r   r   T)r1   r   zError exporting system data: zFailed to export system data)rd   r   rl   r   rm   r&   rn   r   r   rT  r   r'   r   r%   )r(   ro   r   r   r>   r   r  r   analyticexport_datar)   s              r*   export_system_dataMongoHandler.export_system_data^  s   5	Q==//#(5`aa) ..33BQHIED="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&  doo22267J'	I%'*9U+;'<Ie$9,.7.E.O.O.QIl+	 ( T66;;B?@I%H$&)(5/&:HUO(*,4[,A,K,K,MH[)	 & $,<<>#;#;#=#0$ 
 (&#&u:(+J'*9~K   $[99 	QLL8QAB$1OPP	Qs8   G A)G 
A*G 8AG A&G 
G;%G60G;6G;c                 6    U R                  U5      (       d  SSS.$ [        R                  " 5       R                  5       SSSS.[        R                  " 5       [	        SS	9-
  R                  5       SS
SS.[        R                  " 5       [	        SS	9-
  R                  5       SSSS.[        R                  " 5       [	        SS	9-
  R                  5       SSSS./nSUS.$ ! [
         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zGet system logs (admin only)Frg   r0   r    zSystem started successfullySystem)rR  levelr2   sourcerh   r   zUser authentication successfulAuth   rN  High memory usage detected   r%   zDatabase connection timeoutDatabaseT)r1   r   zError getting system logs: zFailed to retrieve system logsN)	rd   r   rT  rn   r   r'   r   r%   r&   )r(   ro   	mock_logsr)   s       r*   get_system_logsMongoHandler.get_system_logs  s   %	S==//#(5`aa
 "*!9!9!;#<&	 #+,,.913E"E!P!P!R#?$	 #+,,.913E"E!P!P!R&;&	 #+,,.913E"E!P!P!R$<(	'I6  $Y77 	SLL6s1vh?@$1QRR	Ss#   C C C 
D(%DDDc                     U R                  U5      (       d  SSS.$ SSKJn  UR                  " 5       R                  5       USS.U R                  R                  0 5      U R                  R                  0 5      U R                  R                  0 5      S.nS	S
US.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z!Create system backup (admin only)Frg   r0   r   r   full)r8   
created_bybackup_type)backup_infousers_counttest_cases_countanalytics_countTz"System backup created successfully)r1   r2   r  zError creating system backup: zFailed to create system backupN)rd   r   rT  rn   r   r   r   r   r'   r   r%   r&   )r(   ro   r   backup_datar)   s        r*   create_system_backup!MongoHandler.create_system_backup  s    	S==//#(5`aa)
 #+,,.":":"<"/#) 
  $44DDRH$(OO$C$CB$G#'#<#<#L#LR#P	K  ?*   	SLL9#a&BC$1QRR	Ss#   B A>B 
C&%CCCc                 |    U R                  U5      (       d  SSS.$ [        [        [        [        [        [        S.nUR                  5        H)  u  pEXB;   d  M  [	        X$   U5      (       a  M!  SSU 3S.s  $    SSUS.$ ! [
         a0  n[        R                  S	[        U5       35        SS
S.s SnA$ SnAff = f)z#Update system settings (admin only)Frg   r0   )enableRegistrationrequireEmailVerificationmaxTestCasessessionTimeoutemailNotificationsadminAlertszInvalid setting type for Tz$System settings updated successfully)r1   r2   settingsz Error updating system settings: z Failed to update system settingsN)	rd   boolintr   r   r'   r   r%   r&   )r(   ro   r  valid_settingskey
value_typer)   s          r*   update_system_settings#MongoHandler.update_system_settings  s    	U==//#(5`aa '+,0 #"%&*#N $2#7#7#9?:hmZ+P+P',;TUXTY9Z[[ $:
  A$   	ULL;CF8DE$1STT	Us4   B 9B B /	B 9B 
B;%B60B;6B;c           	          U R                  U5      (       d  SSS.$ SSKJn  / n U" U5      nUR                  SU05        UR                  SU05        SSSSSSSSS.nS	nU H'  nU R
                  R                  X5      nU(       d  M'    O   U(       d  SS
S.$ [        US   5      US'    SSKJn	  SU;   a*  [        US   U	5      (       a  US   R                  5       US'   SU;   a<  US   b  [        US   U	5      (       a"  US   (       a  US   R                  5       OS	US'   SUS.$ ! [         a     Nf = f! [         a     N!f = f! [         a0  n
[        R                  S[        U
5       35        SSS.s S	n
A
$ S	n
A
ff = f)zGet user details (admin only)Frg   r0   r   r   r4   rh   ri   Nr   r   r8   r9   Tr   zError getting user details: zFailed to retrieve user details)rd   bsonr	   r   r'   r   r@   r&   r   r   rn   r   r%   )r(   ro   ry   r	   query_candidatesuser_object_id
projectionr>   qr8  r)   s              r*   get_user_detailsMongoHandler.get_user_details  s   7	T==//#(5`aa%  "!).!9 ''(?@ ##UN$;< 	J D%,,55aD4 &
 #(5EFF d5k*DK44'JtL7I3,O,O)-l);)E)E)GD&4'T,-?-G:VZ[gVhjmKnKnKOP\K]l);)E)E)GcgD&  $T22O  H  
  	TLL7Ax@A$1RSS	Tsw   E	 E	 D) AE	 
E	 E	 ,A8D9 $E	 )
D63E	 5D66E	 9
EE	 EE	 	
F%E>8F>Fc                     U R                  U5      (       d  SSS.$ SSKJn  / n U" U5      nUR                  SU05        UR                  SU05        SnSnU H)  n	U R
                  R                  U	5      nU(       d  M'  U	n  O   U(       d  SSS.$ S	U;   a  US	   (       d  SS
S.$ SU;   a  US   (       d  SSS.$ SU;   aD  US   UR                  S5      :w  a,  U R
                  R                  SUS   05      n
U
(       a  SSS.$ SU;   a  US   S;  a  SSS.$ 0 nS	U;   a  US	   US	'   SU;   a  US   US'   SU;   a  US   US'   SU;   a  [        US   5      US'   U R
                  R                  USU05      nUR                  S:  a  SSS.$ SSS.$ ! [         a     GNbf = f! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z!Update user by admin (admin only)Frg   r0   r   r   r4   Nr   r6   zName cannot be emptyr.   zEmail cannot be emptyzEmail already existsr7   rs   rt   r:   rX   TzUser updated successfullyzNo changes made to userzError updating user by admin: zFailed to update user)rd   r  r	   r   r'   r   r@   rZ   r  r\   rx   r   r%   r&   )r(   ro   ry   r  r	   r  r  rJ   chosen_queryr  email_existsupdate_datarT   r)   s                 r*   update_user_by_admin!MongoHandler.update_user_by_admin?  s]   D	J==//#(5`aa%  "!).!9 ''(?@ ##UN$;< !ML% $ 5 5 > >q A =#$L	 &
 !#(5EFF "9V+<#(5KLL)#Ig,>#(5LMM )#	'(:m>O>OPW>X(X#44==w	RYHZ>[\',9OPP "y'8@Q'Q#(5^__ K"&/&7F#)#'0'9G$"&/&7F#i'+/	+0F+GK( **55lV[DYZF$$q(#: 
 $)5NOOi  l  	JLL9#a&BC$1HII	Jsq   F' F' F <F' F' F' (F' =A	F' F' A5F' F' 
F$ F' #F$$F' '
G!1%GG!G!c                     U R                  U5      (       d  SSS.$ 0 nUS;   a  [        U R                  R                  0 SS05      5      nU H`  nSU;   a  [	        US   5      US'   SU;   a  US   R                  5       US'   S	U;   d  M>  US	   (       a  US	   R                  5       OS
US	'   Mb     XCS'   US;   an  [        U R                  R                  0 SSSSSSS.5      5      nU H8  nSU;   a  [	        US   5      US'   SU;   d  M"  US   R                  5       US'   M:     XcS'   US;   al  [        U R                  R                  0 SSSSS.5      5      nU H8  n	SU	;   a  [	        U	S   5      U	S'   SU	;   d  M"  U	S   R                  5       U	S'   M:     XS'   U[        R                  " 5       R                  5       U[        UR                  S/ 5      5      [        UR                  S/ 5      5      [        UR                  S/ 5      5      S.US'   [        R                  SU SU S35        SUS.$ ! [         a0  n
[        R                  S[	        U
5       35        SSS.s S
n
A
$ S
n
A
ff = f)zBackup user data (admin only)Frg   r0   r  r   r5   r   r4   r8   r9   Nr   r  r   rh   )r4   r  r8   rc   r   rj   r   r  r   )r4   r8   typer   r   )r  r8   r  r   r  r'  metadatazBackup created by admin r   z backupT)r1   r  zError creating backup: zFailed to create backup)rd   rl   r   rm   r&   rn   r   r   r   rH   r   rZ   r   r    r'   r%   )r(   ro   r  r  r   r>   r   r  r   r  r)   s              r*   backup_user_dataMongoHandler.backup_user_data  s   M	L==//#(5`aaK//T2277=  
 "D}&)$u+&6U#t+-1,-?-I-I-K\*#t+OST`OaT,-?-I-I-Kgk\* " (-G$44!$//"6"6r"# #$< # 
 ",I	)+.y/?+@	%(#y02;L2I2S2S2U	,/	 ", -7L)33 !:!:!?!?"#	E " 	 !*H(*-huo*>#x/19,1G1Q1Q1S.	 !* ,5K(  +&oo/99;+";??7B#?@$'b(I$J#&{{B'G#H'K
# KK2=/K=PWXY#K@@ 	LLL23q6(;<$1JKK	Ls8   H5 A+H5 A<H5 A.H5 >B6H5 5
I/?%I*$I/*I/c                 `    U R                  U5      (       d  SSS.$ [        U[        5      (       a  SU;  a  SSS.$ Sn/ nUS;   a  SU;   a   US    H  nS	U;   a&  US	   (       a  [        R                  " US	   5      US	'   S
U;   a&  US
   (       a  [        R                  " US
   5      US
'   U R
                  R                  U5      nUR                  (       a  US-  nM  UR                  SUR                  SS5       35        M     US;   a  SU;   a   US    H  n	S	U	;   a&  U	S	   (       a  [        R                  " U	S	   5      U	S	'   U R                  R                  U	5      nUR                  (       a  US-  nMb  UR                  SU	R                  SS5       35        M     US;   a  SU;   a}   US    Hs  n
S	U
;   a&  U
S	   (       a  [        R                  " U
S	   5      U
S	'   U R                  R                  U
5      nUR                  (       a  US-  nMb  UR                  S5        Mu     [        R                  SU SU S35        SSU S3UUS .$ ! [         a(  nUR                  S[        U5       35         SnAGNySnAff = f! [         a(  nUR                  S[        U5       35         SnAGNSnAff = f! [         a'  nUR                  S[        U5       35         SnANSnAff = f! [         a0  n[        R!                  S![        U5       35        SS"S.s SnA$ SnAff = f)#z*Restore user data from backup (admin only)Frg   r0   r  zInvalid backup data formatr   r  r   r8   r9   rh   zFailed to restore user: r.   UnknownzError restoring users: Nr  r   zFailed to restore test case: r  zError restoring test cases: r  r   zError restoring analytic datazError restoring analytics: z$Data restoration completed by admin r   z restoreTzRestoration completed. z items restored.)r1   r2   restored_countr"   zError restoring data: zFailed to restore data)rd   r   dictr   fromisoformatr   rI   r   r   rZ   r'   r&   r   r   r   r    r%   )r(   ro   r  restore_typer  r"   r>   rT   r)   r  r  s              r*   restore_user_dataMongoHandler.restore_user_data  sB   W	K==//#(5`aa k400Jk4Q#(5QRRNF00W5KF
 !,G 4'4/D4F191G1G\HZ1[D.'4/D4F191G1G\HZ1[D. "&!6!6!A!A$!G!--*a/N"MM,DTXXgW`EaDb*cd !5" 55,+:UK
 &1%>	'94<9P6>6L6LYWcMd6eIl3 "&!;!;I!F!--*a/N"MM,I)--X_ajJkIl*mn &? 449SJ
 %0$<'838N5=5K5KHUaLb5cH\2 "&!:!:!E!Eh!O!--*a/N"MM,IK %= KK>}oRP\~]efg4^4DDTU"0 	 ] ! FMM$;CF8"DEEF* ! KMM$@Q"IJJK* ! JMM$?Ax"HIIJ  	KLL1#a&:;$1IJJ	Ks   K3 K3 K3 B;I 	K3 BJ
 %K3 2A<J? .&K3 
JJ<K3 JK3 

J<J71K3 7J<<K3 ?
K0	K+&K3 +K00K3 3
L-=%L("L-(L-c                 b    U R                   R                  SU05      nU(       d  SSS.$ UR                  SS5      nSSSSSSSSSSSS.SSSSSSSSSSSS.S	.nUR                  X4S   5      nSUUS
.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z"Get user permissions based on roler4   Fr   r0   r7   r>   Tcan_create_userscan_delete_userscan_update_user_rolescan_view_all_userscan_view_system_statscan_backup_datacan_restore_datacan_export_datacan_manage_systemcan_view_analyticscan_manage_test_casesrs   )r1   permissionsr7   z Error getting user permissions: #Failed to retrieve user permissionsNra   )r(   rc   r>   r7   r  user_permissionsr)   s          r*   get_user_permissions!MongoHandler.get_user_permissions3  s    /	X((115'2BCD#(5EFF88FF+D
 )-(,-1*.-1'+(,'+)-*.-1 ).(--2*/-2',(-',).*.-1K:  +t5HI  /   	XLL;CF8DE$1VWW	Xs#   (A4 AA4 4
B.>%B)#B.)B.c                     U R                   R                  SU05      nU(       d  SSS.$ UR                  S5      S:w  a  SSS.$ U(       aC  U R                  U5      nUS   (       d  SS	S.$ US
   R                  US5      (       d	  SSU S3S.$ SSS.$ ! [         a0  n[
        R                  S[        U5       35        SSS.s SnA$ SnAff = f)zEValidate if user has admin access and specific permission if requiredr4   Fr   r0   r7   rQ   rg   r1   r  r  zAccess denied. z permission required.TzAccess grantedzError validating admin access: zFailed to validate accessN)r   r@   rZ   r  r'   r   r%   r&   )r(   rc   required_permissionr>   r  r)   s         r*   validate_admin_access"MongoHandler.validate_admin_accessf  s    	N((115'2BCD#(5EFFxx7*#(5`aa""77@"9-',9^__"=1556I5QQ',?K^J__t9uvv#0@AA 	NLL:3q6(CD$1LMM	Ns4   (B B &B ,"B B 
C%C	C	Cc                     U R                  U5      (       d  SSS.$ 0 nU(       a  X%S'   U(       a  X5S'   / nSU[        U5      SS.$ ! [         a0  n[        R	                  S	[        U5       35        SS
S.s SnA$ SnAff = f)z!Get user audit trail (admin only)Frg   r0   rc   action_typeTz'Audit trail feature not yet implemented)r1   
audit_logsr   r2   z Error getting user audit trail: zFailed to retrieve audit trailN)rd   r   r'   r   r%   r&   )r(   ro   rc   r  r   r   r  r)   s           r*   get_user_audit_trail!MongoHandler.get_user_audit_trail~  s    	S==//#(5`aa E#*i '2m$ J  (ZD	   	SLL;CF8DE$1QRR	Ss"   A )A 
B%A<6B<Bc                 r    UUUU[         R                  " 5       SSS.nU R                  R                  nUR	                  U5      nUR
                  (       a   [        R                  SU SU 35        SSS.$ SS	S.$ ! [         a0  n[        R                  S
[        U5       35        SSS.s SnA$ SnAff = f)z!Log admin actions for audit trailN)ro   r  	target_iddetailsrR  
ip_address
user_agentzAdmin action logged: z by TzAction logged successfullyr0   FzFailed to log actionzError logging admin action: zFailed to log admin action)r   rH   r   admin_audit_logsrI   r   r   r    r'   r%   r&   )	r(   ro   r  r  r  audit_entryaudit_collectionrT   r)   s	            r*   log_admin_actionMongoHandler.log_admin_action  s    	O "/*&"%__.""K  $ww77%00=F!!3K=]OTU#'4PQQ#(5KLL 	OLL7Ax@A$1MNN	Os$   A4A< 7A< <
B6%B1+B61B6c                 8    U R                  U5      (       d  SSS.$ 0 nU(       a  X$S'   [        U R                  R                  USSSSSSSS.5      R	                  SS5      R                  U5      5      nU HT  nS	U;   a  [        US	   5      US	'   S
U;   a  US
   R                  5       US
'   SU;   d  M>  US   R                  5       US'   MV     SU[        U5      S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z)Get user session information (admin only)Frg   r0   rc   rh   )r4   rc   r8   rf  r  r  r:   rf  r   r4   r8   T)r1   sessionsr   zError getting user sessions: z Failed to retrieve user sessionsN)rd   rl   r   rm   r   r   r&   rn   r   r'   r   r%   )r(   ro   rc   r   r   r  sessionr)   s           r*   get_user_sessionsMongoHandler.get_user_sessions  s6   "	U==//#(5`aa E#*i  D99>>u!"G  tOR(u7H $G#%(%8GEN7*,3L,A,K,K,MGL)"g-/6/G/Q/Q/SGO, $  $CMRR 	ULL8QAB$1STT	Us)   C BC 6(C 
D)%DDDc                     U R                  U5      (       d  SSS.$ 0 nU(       a  X$S'   U(       a  X4S'   U R                  R                  USS[        R                  " 5       S.05      nUR
                  S:  a8  [        R                  S	U S
UR
                   S35        SUR
                   S3S.$ SSS.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z$Terminate user sessions (admin only)Frg   r0   rc   r4   rX   )r:   terminated_atr   z"User sessions terminated by admin r   z	 sessionsTz! sessions terminated successfullyzNo sessions found to terminatez!Error terminating user sessions: zFailed to terminate sessionsN)rd   r   update_manyr   rH   rx   r   r    r'   r%   r&   )r(   ro   rc   
session_idr   rT   r)   s          r*   terminate_user_sessions$MongoHandler.terminate_user_sessions  s    	Q==//#(5`aa E#*i )e 22>>ux?PQRF
 $$q(@rRXRgRgQhhqrs#'v7L7L6MMn4opp#(5UVV 	QLL<SVHEF$1OPP	Qs)   B6 BB6 1B6 6
C0 %C+%C0+C0c                 L    U R                  U5      (       d  SSS.$ 0 nU(       a  X$S'   [        U R                  R                  USSSSSS.5      R	                  SS5      R                  U5      5      nU H`  nS	U;   a  [        US	   5      US	'   S
U;   a  US
   R                  5       US
'   SU;   d  M>  US   (       a  US   R                  5       OSUS'   Mb     SU[        U5      S.$ ! [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z#Get user login history (admin only)Frg   r0   rc   rh   )r4   r.   r6   r9   r8   r9   r   r4   r8   NT)r1   login_historyr   z"Error getting user login history: z Failed to retrieve login history)rd   rl   r   rm   r   r   r&   rn   r   r'   r   r%   )r(   ro   rc   r   r   r   r>   r)   s           r*   get_user_login_history#MongoHandler.get_user_login_history  s9    	U==//#(5`aa E#*i  ..33E<  tL"%eeEl4E D="%d5k"2DK4')-l);)E)E)GD&4'KOP\K]l);)E)E)GcgD&   $ec%jQQ 	ULL=c!fXFG$1STT	Us)   C) BC) 44C) )
D#3%DD#D#c                     U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  Xe" SS9-
  nO5US	:X  a	  Xe" SS
9-
  nO&US:X  a	  Xe" SS9-
  nOUS:X  a	  Xe" SS9-
  nOXe" SS9-
  nSSU00nU(       a  X(S'   [	        U R
                  R                  SU0SSSS0SS0SSSSS/0SS/00S.0/5      5      n	/ n
U	 H  nU R                  R                  SUS   0SSSS.5      nU(       d  M1  [        US   5      US   US    UR                  S!S"5      US#   UR                  S$S5      UR                  S%S5      S&-  S'.nU
R                  U5        M     U
R                  S( S)S*9  S)UUR                  5       UR                  5       U
[        U
5      S+.$ ! [         a0  n[         R#                  S,[        U5       35        SS-S.s S.nA$ S.nAff = f)/z)Get user performance metrics (admin only)Frg   r0   r   r
   r   rh   rA  weekweeksmonthr_  yearm  r8   r   rc   $matchr`  ra  rb  $avg$completion_time$cond$eq$status	completed)r4   r  avg_completion_timesuccess_rater4   r6   r.   r7   r6   r.   r7   r>   r  r  r  d   )rc   r6   r.   r7   r  r  r  c                     U S   $ )Nr  rH  xs    r*   <lambda>;MongoHandler.get_user_performance_metrics.<locals>.<lambda>^  s
    A.@,A    Tr  reverse)r1   time_period
start_dateend_dateuser_metricsr   z(Error getting user performance metrics: z&Failed to retrieve performance metricsN)rd   r   r   rH   rl   r   rw  r   r@   r&   rZ   r   r   rn   r   r'   r   r%   )r(   ro   rc   r  r   r   rT  r   r   test_case_metricsr"  metricr>   user_metricr)   s                  r*   get_user_performance_metrics)MongoHandler.get_user_performance_metrics"  s[   G	[==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 "FJ#78E#*i  !%T__%>%>5!%)/,24F+G%+gK@X8Y[\^_7`-a$b	 @ & ! L+,,55ufUm6LO  4#&ve}#5 $V!%g $ 8,23E,F/5zz:OQR/S(.

>1(E(K#K !''4# ,( "A4P  *(224MMO ,"<0   	[LLCCF8LM$1YZZ	[s*   F$ CF$ >B%F$ $
G.%GGGc                     U R                  U5      (       d  SSS.$  U R                  R                  5         Sn0 nS H+  n U R
                  U   nUR                  0 5      nSUS.XE'   M-     S	SKn UR                  S
S9n	UR                  5       n
UR                  S5      nU	U
R                  UR                  SS.nSnUS:w  a  SnUR                  5        H  nUS   S:w  d  M  Sn  O   U[        R                  " 5       R!                  5       USS.UU/ S.nUS:X  a  US   R#                  S5        UR%                  SS	5      S:  a  US   R#                  S5        UR%                  SS	5      S:  a  US   R#                  S5        UR%                  SS	5      S:  a  US   R#                  S 5        S!US".$ ! [         a  nS[	        U5       3n SnAGNSnAff = f! [         a  nS[	        U5       3S	S.XE'    SnAGM  SnAff = f! [         a	    SSS.n GN\f = f! [         a0  n[&        R)                  S#[	        U5       35        SS$S.s SnA$ SnAff = f)%r<  Frg   r0   r&  zunhealthy: N)r   r   r   r   r?  r   rh   )interval/	available)cpu_percentmemory_percentdisk_percentrj   zpsutil not availablez5Install psutil package for system resource monitoring)rj   r2   r>  rj   MongoDB)rj   
connection)rO  rR  databaserX  system_resourcesrecommendationsr3  z/Check database connection and collection accessr,  P   zHigh CPU usage detectedr-  r  r.  Z   zLow disk space detectedT)r1   health_statusz$Error getting system health status: z'Failed to retrieve system health status)rd   r   r   r'   r&   r   r   psutilr,  virtual_memory
disk_usagepercentImportErrorrV  r   rH   rn   r   rZ   r   r%   )r(   ro   rW  r)   rQ  rY  r   r   r7  r,  memorydiskr2  rO  collection_statusr6  s                   r*   get_system_health_status%MongoHandler.get_system_health_statusm  s   V	\==//#(5`aa3'')%	
 "$#X!%!9J&66r:E"+*/;&7	 $Y $00!0<..0((- $/&,nn$(LL)	$  'NI%!,%7%>%>%@!$X.);%0N &A #1%__.88:'"+  2$4#%
M ,/0778ij##M15:/0778QR##$4a82=/0778TU##NA6;/0778QR#mDDS  3)#a&2	3 ! $/Ax"8*+;&77&  4V$ V  	\LL?AxHI$1Z[[	\s   H F5 H 'G)H 2AH =$H %CH 5
G?GH GH 
H%G?8H ?HH HH HH 
I'%IIIc                 2    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSSS.0SS.SS0SS0S.0SSSS0SSS 00S!S"SS#.0S$.0S%S&S00/5      5      n[	        U R                  R                  SSSU000SSSSS.0SS0S'.0S%S&S00/5      5      n[	        U R                  R                  SS(SU000SSSS)S.0SS0S*.0S%S&S00/5      5      n	0 n
UnX::  a+  UR                  S5      nUSSSS0 S+.X'   X" SS9-  nX::  a  M+  U HC  nUS&   nX;   d  M  US,   X   S,'   US-   X   S-'   US.    H  nUS/   nUS0   nUX   S.   U'   M     ME     U H  nUS&   nX;   d  M  US1   X   S1'   M     U	 H  nUS&   nX;   d  M  US2   X   S2'   M     [	        U
R                  5       5      nUR                  S3 S49  S5UUR                  5       UR                  5       U[        U5      S6.$ ! [         a0  n[        R                  S7[!        U5       35        SS8S.s S9nA$ S9nAff = f):z&Get user activity summary (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  $dateToString%Y-%m-%drd  r   daterq  )rE  r   rb  	$addToSetra  )r4   r   r   z	$_id.date$count$sizez$users$push$_id.source_typer   r   )r4   r  unique_userssource_typesrp  r4   r4   	new_usersr9   $last_loginr4   r   )rE  r  rL  rO  r   rM  r  rL  rM  r   r   rO  r   c                     U S   $ )NrE  rH  r  s    r*   r  8MongoHandler.get_user_activity_summary.<locals>.<lambda>6  s    QvYr  r  T)r1   r  r   r!  activity_summary
total_daysz%Error getting user activity summary: z#Failed to retrieve activity summaryN)rd   r   r   rH   rl   r   rw  r   strftimerV  r   rn   r   r'   r   r%   r&   )r(   ro   r  r   r   rT  r   rU  user_registration_summarylogin_activity_summarycombined_summarycurrent_datedate_strsummarysource_type_infor   r   activity_summary_listr)   s                      r*   get_user_activity_summary&MongoHandler.get_user_activity_summary  s   z	X==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
  $DOO$=$=L6:*>?@!0ZQ^2_ `'5 %a[):6  &)/(:%+gx-@$A+=%-"%	
 
 5!*%+? %  2 )-T-B-B-L-LL6:*>?@+
M-Z["(!  5!*%N . )% &*$*?*?*I*IL6:*>?@+
M-Z[%+QK  5!*%K + &"  " &L%'00<$()$%!"$%$&. * 	q 11 % ,"5>/ELM_E`$./ABAHAX$.~> -4N,C(&6}&E 0 9RW(2>B;O -D , 5"5>/>Ek>R$.{; 5 2"5>/AHAX$.~> 2 %))9)@)@)B$C!!&&+>&?  *(224MMO$9!"78   	XLL@QIJ$1VWW	Xs=   I EI >I AI I 7A$I 
J&%JJJc                     U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  nU R                  R                  0 5      nU R                  R                  SSU005      nU R                  R                  SSU005      n	[        U R                  R                  SSSU005      5      n
US:  a  X-  S-  OSnUS:  a  X-  S-  OSnUS:  a
  Xy-
  U-  S-  OSn[        U R                  R                  SSSU000SSSS0S.0SSSS0SS0SS0S.0/5      5      nU(       a  US   OSSSS.n[        U R                  R                  SSSU000SS SS0S!.0S"S#S$00/5      5      n[        U R                  R                  SS%SS0S!.0S"S#S$00/5      5      nUUR                  5       UR                  5       UUU	U
[        US&5      [        US&5      [        US&5      [        US'   S&5      US(   US)   S.UUS*.nS+US,.$ ! [         a0  n[        R                  S-[!        U5       35        SS.S.s SnA$ SnAff = f)/z(Get user engagement metrics (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r9   r   r8   rc   r  r  r`  ra  rb  )r4   activity_countNr  z$activity_countrc  $min)r4   avg_activity_per_usermax_activitymin_activity)re  rf  rg  rq  rr  rp  r   r   z$roler  re  rf  rg  )r  r   r!  r   r   rO  users_with_activityengagement_rateactivity_rateretention_rateactivity_statssource_type_distributionrole_distributionT)r1   engagement_metricsz'Error getting user engagement metrics: z%Failed to retrieve engagement metrics)rd   r   r   rH   r   r   r   r   distinctrl   rw  rn   roundr'   r   r%   r&   )r(   ro   r  r   r   rT  r   r   r   rO  rh  ri  rj  rk  user_activity_frequencyrl  rm  rn  ro  r)   s                       r*   get_user_engagement_metrics(MongoHandler.get_user_engagement_metricsE  s   k	Z==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 //??CK  00@@vz2B L
 --==vz2? I
 #&doo&>&>yvz2K ' #
 EPRSO|9C?YZOITWX0>D^_MP[^_P_{6+EKefN '+4??+D+DL6:*>?@%'-qk  .46G-H%+->$?%+->$?	 F , '# <S4Q7)* ! !YN (,DOO,E,EL6:*>?@)$a[  7B-(G - ($ !%T%:%:%D%D"$a[  7B-(F & !  +(224MMO* ,&':#(!#<!&}a!8"'":-2>BY3Z\]-^$2>$B$2>$B#
 -E%6#"(  $;MNN 	ZLLB3q6(KL$1XYY	Zs#   I H0I 
J%J=JJc                     U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSS0SSSSS/0SS/00S.0SSSSSSS/0S /0S!.0/5      5      n/ nU Hi  n	Sn
U	S"   S:  a2  U	S#   S$:  a  S%n
O&U	S#   S&:  a  S'n
OU	S#   S(:  a  S)n
OU	S#   S*:  a  S+n
OSn
UR                  U	S,   U
[        U	S#   S+5      U	S"   S-.5        Mk     U(       a`  [        S. U 5       5      [        U5      -  n0 n[        SS/5       H/  n[        U Vs/ s H  oS0   U:X  d  M  UPM     sn5      US1U 3'   M1     O"Sn[        SS/5       Vs0 s H	  nS1U 3S_M     nn/ nU H  nU R                  R                  S2US,   0SSSSS3.5      nU(       d  M2  UR                  US,   US4   US5   UR                  S6S75      US0   US#   US"   UR                  S5      (       a  US   R                  5       OS8S9.5        M     UR!                  S: S;S<9  UUR                  5       UR                  5       [        US+5      U[        U5      U[        U Vs/ s H  oS#   S$:  d  M  UPM     sn5      [        U Vs/ s H  nS&US#   s=::  a  S$:  d  M  O  M  UPM     sn5      [        U Vs/ s H  nS(US#   s=::  a  S&:  d  M  O  M  UPM     sn5      [        U Vs/ s H  nS*US#   s=::  a  S(:  d  M  O  M  UPM     sn5      [        U Vs/ s H  oS#   S*:  d  M  UPM     sn5      S=.S>.nS;US?.$ s  snf s  snf s  snf s  snf s  snf s  snf s  snf ! ["         a0  n[$        R'                  S@[)        U5       35        SSAS.s S8nA$ S8nAff = f)Bz2Get user feedback and ratings metrics (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  ra  rb  r  r  r  r  )r4   r  successful_test_casesrl  rm  z	$multiply$dividez$successful_test_casesz$total_test_casesr  )rc   r  r  r  r  r5     r4     F   r  <   r  rc   )rc   satisfaction_scorer  r  c              3   *   #    U  H	  oS    v   M     g7fr|  NrH  rI  us     r*   rK  9MongoHandler.get_user_feedback_metrics.<locals>.<genexpr>  s     &ZHY1)='>HY      r|  score_r4   r6   r.   r7   r8   r6   r.   r7   r>   N)rc   r6   r.   r7   r|  r  r  
user_sincec                     U S   $ Nr|  rH  r  s    r*   r  8MongoHandler.get_user_feedback_metrics.<locals>.<lambda>	  s
    CWAXr  Tr  )	excellentgoodaveragebelow_averagepoor)r  r   r!  overall_satisfactionsatisfaction_distributiontotal_users_analyzeduser_satisfaction_detailssuccess_rate_summary)r1   feedback_metricsz%Error getting user feedback metrics: z#Failed to retrieve feedback metrics)rd   r   r   rH   rl   r   rw  r   rq  sumr   ranger   r@   rZ   rn   r   r'   r   r%   r&   )r(   ro   r  r   r   rT  r   test_case_success_ratesuser_satisfactionr%  r|  avg_satisfactionr  r   r  !activity_satisfaction_correlationr>   user_detailsr  r)   s                       r*   get_user_feedback_metrics&MongoHandler.get_user_feedback_metrics  s   {	X==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 '+4??+D+DL6:*>?@%)/EI{3K+LaQR*S T.  %()#&)ACV(WX&%	 	F , '#. !#6%&"12Q6">2b8-.*$^4:-.*$^4:-.*$^4:-.*-.*!((*95*<$)+n*Eq$I(34F(G	*   7, !#&&ZHY&Z#Z]`ar]s#s ,.)q!A>AN_  CAN_eycz~c1N_  CA  ?B-qcl; % $% FKAqk,RkvaS\1_k),R 13-)#44==ud9o>V"#	Y    <5<<#'	? ,V 4!-g!6 , 0 0 @.23G.H(,^(<,01C,DP\P`P`amPnPnl<&@&J&J&Ltx	> 	 *, .227Xbf2g  +(224MMO(-.>(B-F(+,=(>-N!$1B%^1BAFW[]F]a1B%^!_,= ^,=qqGXA][]A]A],= ^_"/@#a/@!B!NJ[D`^`D`AD`A/@#ab%(5F)g5F"PQR`PaJfdfJf!Jf!5F)g%h,= X,=q>ARUWAW,= XY) "  $9IJJa CA -SJ &_ ^#a)g X  	XLL@QIJ$1VWW	Xs   N2 EN2 8N
N
"N2 0N 4N2 8B9N2 1NNN2 N.N2N8N2 N#N##N#)N2 8N(N(N(N2 )N-9N-?N2 #N2 2
O,<%O'!O,'O,c                   ^  U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a  XT" SS9-
  nS	nO,US
:X  a  XT" SS9-
  nSnOUS:X  a  XT" SS9-
  nS	nO
XT" SS9-
  nS	n[	        U R
                  R                  SSSU000SSUSS.0SS0S.0SSS00/5      5      n[	        U R                  R                  SSSU000SSUSS.0SS0SSS00S.0SSS00/5      5      n	[	        U R
                  R                  SSSU000SSUS S.0SS0S!.0SSS00/5      5      n
0 mUnX::  a  US:X  a  UR                  S	5      nO>US
:X  a'  UR                  S-
  S"-  S-   nUR                   S#U 3nOUR                  S	5      nUSSSSSSS$.TU'   US:X  a	  X" SS9-  nOUS
:X  a	  X" SS9-  nOX" SS9-  nX::  a  M  U H  nUS   nUT;   d  M  US%   TU   S%'   M     U	 H&  nUS   nUT;   d  M  US&   TU   S&'   US'   TU   S''   M(     U
 H  nUS   nUT;   d  M  US(   TU   S('   M     [        TR                  5       5      n[        U5       H  u  nnUS:  aF  UUS-
     nTU   S%   nTU   S%   nUS:  a  UU-
  U-  S)-  nO
US:  a  S)OSn[        US*5      TU   S+'   [        U4S, jUS-US-     5       5      nUS:  a  TU   S(   U-  S)-  nOSn[        US*5      TU   S.'   M     [	        TR!                  5       5      n[        S/ U 5       5      n[#        S0 U 5       5      (       a:  [        S1 U 5       5      [%        U Vs/ s H  nUS+   S:w  d  M  UPM     sn5      -  OSnU(       a  [        S2 U 5       5      [%        U5      -  OSnUUR'                  5       UR'                  5       U[        US*5      [        US*5      UU(       a  [)        US3 S49OS-U(       a  [)        US5 S49OS-[%        U5      S6.S7.nS8US9.$ s  snf ! [*         a0  n[,        R/                  S:[1        U5       35        SS;S.s S-nA$ S-nAff = f)<z#Get user growth trends (admin only)Frg   r0   r   r
   r	  r_  rA  %Y-%mquarterr5  z%Y-Q%qr
  r  r  r8   r   r`  rB  rd  rD  rb  rh   rN  rp  r4   rH  rF  ra  )r4   total_activitiesrL  r9   rP  rQ  r  z-Q)periodrO  r  rL  r   growth_raterj  rO  r  rL  r   r  r  r  c              3   4   >#    U  H  nTU   S    v   M     g7frO  NrH  )rI  pcombined_trendss     r*   rK  6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  s     +cUbPQOA,>{,KUbs   Nrj  c              3   *   #    U  H	  oS    v   M     g7fr  rH  rI  trends     r*   rK  r  	  s     !UBT"4BTr  c              3   0   #    U  H  oS    S:g  v   M     g7fr  r   NrH  )rI  ts     r*   rK  r  	  s=       |o  \n  WX  L  }M  QR  }R  \nrM  c              3   @   #    U  H  oS    S:w  d  M  US    v   M     g7fr  rH  r  s     r*   rK  r  	  s&     !tDV5`mZnrsZs"6%"6DV   c              3   *   #    U  H	  oS    v   M     g7f)rj  NrH  r  s     r*   rK  r  	  s     #[HZu/$:HZr  c                     U S   $ )Nr  rH  r  s    r*   r  5MongoHandler.get_user_growth_trends.<locals>.<lambda>	  s    PQR_P`r  rT  c                     U S   $ )Nrj  rH  r  s    r*   r  r  	  s    RSTcRdr  )best_growth_periodbest_activity_periodtotal_periods)r  r   r!  total_new_usersaverage_growth_rateaverage_activity_ratetrendsr]  T)r1   growth_trendsz"Error getting user growth trends: z Failed to retrieve growth trends)rd   r   r   rH   rl   r   rw  r   rW  r	  r
  sortedr   	enumeraterq  r  rV  rU  r   rn   maxr'   r   r%   r&   ) r(   ro   r  r   r   rT  r   date_formatuser_registration_trendsuser_activity_trendsuser_login_trendsr[  
period_keyr  r  periodsr   r  prev_period
prev_userscurrent_usersr  total_users_in_periodrj  growth_trends_listr  r  avg_growth_rateavg_activity_rater  r)   r  s                                   @r*   get_user_growth_trends#MongoHandler.get_user_growth_trends3	  s   Z	U==//#(5`aa 5//#Cg% 9"#55
%	) 9"#55
&& 9##66
% 9##66
% (,D,A,A,K,KL6:*>?@+]-[\"(!  5!*%M - ($ $((A(AL6:*>?@+]-[\)/%,{J.G$H 
 5!*%C ) $  !%T%:%:%D%DL6:*>?@+]-[\%+QK  5!*%F & ! !O &L%')!-!6!6w!?J I-+11A5!;a?G$0$5$5#6b	!BJ!-!6!6w!?J )!"()$%$%#$%&/
+ ') I2$66L I- I2$66L I2$66L1 %6 2"5\
0?D[?QOJ/< 2 ."5\
0FKL^F_OJ/0BCBGBWOJ/?	 . +"5\
0BGBWOJ/? + _1134G&w/	6q5")!A#,K!0!=k!JJ$3F$;K$HM!A~(5
(Bj'PTW&W-:Q->cA=B;PQ=ROF+M: ),+cU\]a^_`a^aUb+c(c%(1,%4V%<^%LOd%dhk$kM$%M;@PQ;R'8) 0. "&o&<&<&>!? "!UBT!UUO y|  |o  \n  |o  yo  yoc!tDV!ttwz  HZ  |t  HZ  CD  ^_  `m  ^n  rs  ^s|}  HZ  |t  xu  u  uvO zL#[HZ#[ [^abt^u u  RS  +(224MMO#2',_a'@)./@!)D,ew#.@F`*a  ~Bi{C0BHd,e  BF%();%<M  $mDD% |t(  	ULL=c!fXFG$1STT	UsU   P F)P 	P P <(P (D)P P
"P
(B"P P 
Q
%Q?Q
Q
c                     U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO&US	:X  a	  XT" S
S9-
  nOUS:X  a	  XT" SS9-
  nOXT" S
S9-
  n/ nUnX::  Ga  X" SS9-   n	[	        U R
                  R                  SUU	S.0SSS.5      5      n
U
(       a  [        U
5      nU
 Vs/ s H  oS   PM	     nn/ SQn0 nU H_  nX" US-
  S9-   nUU" SS9-   nU R                  R                  SU0UUS.S.5      nUS:  a  UU-  S-  OSnU[        US5      S.USU 3'   Ma     UR                  UR                  5       U	R                  5       UUS.5        U	nX::  a  GM  [        U5      nUS:  aU  [        S U 5       5      U-  n[        S U 5       5      U-  n[        S U 5       5      U-  n[        S U 5       5      U-  nOS=n=n=nn/ nU H  nUR                  " US   5      nUR                  " US    5      n	SUS!   S"   S#   -
  nUR                  UR                  S$5       S%U	R                  S$5       3US&   US!   S'   S#   US!   S"   S#   [        US5      S(.5        M     [	        U R                  R!                  S)SS*U000S+S,S-S0S.S/0S0S/0S1.0S2S3SS4S5S6S7/0S8/0S9.0/5      5      nU(       a=  [        S: U 5       5      [        U5      -  n[        S; U 5       5      [        U5      -  n OS=nn UUR                  5       UR                  5       UU[        US5      [        US5      [        US5      [        US5      S<.U[        U5      [        US5      [        U S5      S=.S>.n!S?U!S@.$ s  snf ! ["         a0  n"[$        R'                  SA[)        U"5       35        SSBS.s SCn"A"$ SCn"A"ff = f)Dz(Get user retention analysis (admin only)Frg   r0   r   r
   r  ry  r  r	  r5  rA  r     rh   r8   r   z$lt)r4   r8   r4   )rh   r  r  ry  z$inr  r  r  )r   rk  week_)cohort_start
cohort_endcohort_sizeretention_datac              3   6   #    U  H  oS    S   S   v   M     g7f)r  week_1rk  NrH  rI  cohorts     r*   rK  ;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>
  "     *~n}dj2B+CH+MN^+_n}   c              3   6   #    U  H  oS    S   S   v   M     g7f)r  week_2rk  NrH  r  s     r*   rK  r  
  r  r  c              3   6   #    U  H  oS    S   S   v   M     g7f)r  week_3rk  NrH  r  s     r*   rK  r  
  r  r  c              3   6   #    U  H  oS    S   S   v   M     g7f)r  week_4rk  NrH  r  s     r*   rK  r  
  r  r  r  r  r  r  rk  rC  z to r  r  )cohort_periodr  week_1_retentionweek_4_retention
churn_rater  r   r`  ra  rb  rd  rd  rc  )r4   r  first_activityrf  rl  rm  rw  	$subtract$last_activity$first_activity \&)rc   r  lifetime_daysc              3   *   #    U  H	  oS    v   M     g7f)r  NrH  rI  r>   s     r*   rK  r  K
  s     'aJ`$_(=J`r  c              3   *   #    U  H	  oS    v   M     g7fr  NrH  r  s     r*   rK  r  L
  s     -jSi43E.FSir  )r  week_2_retentionweek_3_retentionr  )r  average_lifetime_daysaverage_test_cases_per_user)r  r   r!  total_cohortscohort_analysisoverall_retention_metricschurn_analysisuser_lifetime_analysisT)r1   retention_analysisz'Error getting user retention analysis: z%Failed to retrieve retention analysisN)rd   r   r   rH   rl   r   rm   r   r   r   rq  r   rn   r  r  rW  rw  r'   r   r%   r&   )#r(   ro   r  r   r   rT  r   r  current_cohort_startr  cohort_usersr  r>   cohort_user_idsretention_periodsr  r  period_start
period_endr   rk  r  avg_week_1_retentionavg_week_2_retentionavg_week_3_retentionavg_week_4_retentionr  r  r  r  r  avg_lifetime_daysavg_test_cases_per_userr  r)   s#                                      r*   get_user_retention_analysis(MongoHandler.get_user_retention_analysis	  s'   U	Z==//#(5`aa 5//#Cf$ 91#55
' 9"#55
	) 9##66
 9"#55
 !O $. &-1IA4FF
  $D$9$9$>$>  4)#@
 A.%0  1  "%l"3K?K&L|tE{|O&L )5%%'N"3'1IF1H4M'M%1IA4F%F
 (,'F'F(-'?(4'1+H ( P[]^,*Ds*Jde,8.3NA.F<vh'78 #4& $**(<(F(F(H&0&:&:&<'2*8	,  (2$[ '-`  0Mq '**~n}*~'~  BO  (O$'**~n}*~'~  BO  (O$'**~n}*~'~  BO  (O$'**~n}*~'~  BO  (O$lmm$m';m>RUi  N)'55f^6LM%33F<4HI
 !6*:#;H#EFV#WW
%%(4(=(=j(I'J$zObObcmOnNo%p#)-#8(./?(@(JK[(\(./?(@(JK[(\"'
A"6'  *  &*$//*C*CL6:*>?@%)/'-}&=&,m%<	  %()!(+;=N*OP/$&	 	E + &"* &$''aJ`'a$adgh~d$!*--jSi-j*jmp  rH  nI  +I'>??!$;  +(224MMO!.#2(-.BA(F(-.BA(F(-.BA(F(-.BA(F	. #1,/0F,G-23Da-H389PRS3T+"(  $;MNN[ 'M^  	ZLLB3q6(KL$1XYY	Zs=   N B#N  NB&N 7HN N 
O
%O?O
O
c                 ^    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSS0SS0S.0SSS00/5      5      n[	        U R
                  R                  SSSU000SSS0SS0S.0SSS00/5      5      n[	        U R
                  R                  SSSU000SSSS.SS0S.0SSSSS S!.0SS 0S".0SS#S$00/5      5      n	[	        U R
                  R                  SSSU000SSSS%S&SS'.0SS0S(.0SS0S).0S*S+SS,S-S.00S/S0S,S-S.00/0S1S2.0/5      5      n
/ nU
 H  nU R                  R                  SUS3   0SSSS4.5      nU(       d  M1  US5   nSnUS6:  a  S7nOUS8:  a  S9nOUS:  a  S:nOS;nUR                  [        US3   5      US<   US=   UR                  S>S?5      US#   US@   [        US5   SA5      USB.5        M     UR                  SC SDSE9  / nU Hd  nUS   nUSF   nSGnSHUs=::  a  SI:  a  O  OSJnO(SIUs=::  a  SK:  a  O  OSLnOSKUs=::  a  SM:  a  O  OSNnOSOnUR                  UUUUSP SQ3SR.5        Mf     / n/ SSQnU H(  nUS   nUSF   nUR                  UUUS-
     UST.5        M*     UUR                  5       UR                  5       UUU	U
UU(       a  [        USU SV9OSWU(       a  [        USX SV9OSW[!        U5      [!        U Vs/ s H  nUSY   SZ;   d  M  UPM     sn5      S[.S\.	nSDUS].$ s  snf ! ["         a0  n[$        R'                  S^[        U5       35        SS_S.s SWnA$ SWnAff = f)`z'Get user behavior patterns (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  z$hourrd  rb  rr  rp  r4   z
$dayOfWeekra  rq  )rc   r   z$_id.user_idrI  rJ  rG  rK  )r4   rM  r  r  r   rB  rC  rD  )rE  time)r4   r  r  rl  rm  rH  z	$setUnionz$sessions.daterw  z$total_activitiesz	$sessions)rc   r  unique_daysavg_activities_per_daysession_patternsrc   r  r  rx  	Very Highr  HighMediumLowr6   r.   r7   r>   r  r  )rc   r6   r.   r7   r  r  r  engagement_scorec                     SSSSS.U S      $ )Nry  r  r  rh   )r  r  r  r  r  rH  r  s    r*   r  9MongoHandler.get_user_behavior_patterns.<locals>.<lambda>
  s#    	4
 "#4%r  Tr  r    r     Morning   	Afternoon   EveningNight02dz:00)r   r  rc  formatted_time)SundayMondayTuesday	WednesdayThursdayFridaySaturday)
day_numberday_namerc  c                     U S   $ Nrc  rH  r  s    r*   r  r    s
    QGWEXr  rT  Nc                     U S   $ r*  rH  r  s    r*   r  r    s
    1EUCVr  r  )r  r  )	peak_hourpeak_dayr  high_engagement_users)	r  r   r!  hourly_activityweekly_patternssource_type_preferencesuser_session_patternsengagement_patternsr]  )r1   behavior_patternsz&Error getting user behavior patterns: z$Failed to retrieve behavior patterns)rd   r   r   rH   rl   r   rw  r   r@   r   r&   rZ   rq  r   rn   r  r   r'   r   r%   )r(   ro   r  r   r   rT  r   r/  daily_activityr1  r2  r3  user_patternr  activity_frequencyr  peak_usage_times	hour_datar   r   r0  	day_namesday_datar'  r  r4  r)   s                              r*   get_user_behavior_patterns'MongoHandler.get_user_behavior_patternsj
  ss   x	Y==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 #4??#<#<L6:*>?@#]3$a[  5!*%> $ O "$//";";L6:*>?@(-8$a[  5!*%= # N '+4??+D+DL6:*>?@#-'5 %a[  )+=%-"% *0(:	 	 -r23'F , '#. %))B)BL6:*>?@%%4Ub6c$d%,m$<"! *0	 	 %()$+k;K-L#M/8;NQX[fhxZyPz:{.|(3 D * %!, #% 5#44==ulS\F]>^a    <)56N)O&'($)Q.+6(+q0+1(+q0+3(+0('..#&|I'>#? ,V 4!-g!6 , 0 0 @,89K,L'3M'B27E]8^`a2b,<	0 	- !6D  $$ *%
 /3 % 4  ",	 '!'* >r>"+K4_"_"-K4_"_"+K")K '' #.&+)-c
#&6	)  -, !OfI*%e_
 )&&", )*q. 9&+( 	 +  +(224MMO#3#2+B)>':]m%5;X!Ysw[jO9V Wpt,/0C,D-0=P  2D=PTUVhTi  nC  UC!=P  2D  .E	!"  $:KLL	 2D  	YLLA#a&JK$1WXX	YsB   M2 F M2 FM2 M-M-M2 -M2 2
N,<%N'!N,'N,c                 l	    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSS0SS0SS0SS0SSSSS/0S/00S .0/5      5      n/ nU H  n	U R                  R                  S!U	S!   0SSSSS".5      n
U
(       d  M2  SnU
R                  S5      (       a  XZS   -
  R                  nU R                  U	S#   U	S$   U[        U	S%   5      5      nUR                  [        U	S!   5      U
S&   U
S'   U
R                  S(S)5      UU	S#   [        U	S%   5      U	S%   UU	S$   (       a  [        U	S$   S*5      OSS+.
5        M     0 nU H$  nUS,   nX;  a  / X'   X   R                  U5        M&     0 nUR!                  5        H  u  nn[        U5      nUS:  a  [#        S- U 5       5      U-  OSnUS:  a  [#        S. U 5       5      U-  OSnUS:  a  [#        S/ U 5       5      U-  OSnUU(       a  [        U[        U5      -  S0-  S*5      OS[        US*5      [        US*5      [        US*5      US1.X'   M     0 nUR!                  5        H  u  nnUS2   (       d  M  0 nUS2    H'  nUS%    H  nUR                  US5      S-   UU'   M     M)     [%        UR!                  5       S3 S4S59nUS6S7 U R'                  US8   5      U R)                  US9   5      S:.UU'   M     0 nUR!                  5        H  u  nn/ nUS;:X  a  UR+                  / S<Q5        OgUS=:X  a  UR+                  / S>Q5        OMUS?:X  a  UR+                  / S@Q5        O3USA:X  a  UR+                  / SBQ5        OUSC:X  a  UR+                  / SDQ5        UUU'   M     UUR-                  5       UR-                  5       [        U5      UUUUU(       a  [/        UR!                  5       SE SF9S   OS6U(       a  [/        UR!                  5       SG SF9S   OS6[        U5      SH.SI.	nS4USJ.$ ! [0         a0  n[2        R5                  SK[        U5       35        SSLS.s S6nA$ S6nAff = f)Mz+Get user segmentation analysis (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  ra  rb  rF  rq  rd  rd  rc  r  rw  r  r  r  r  )r4   r  rM  r  rf  avg_daily_activityr4   r  r  r?  rM  r6   r.   r7   r>   r  )
rc   r6   r.   r7   segmentr  source_types_usedrM  user_age_daysr?  r@  c              3   *   #    U  H	  oS    v   M     g7fr  rH  r  s     r*   rK  >MongoHandler.get_user_segmentation_analysis.<locals>.<genexpr>  s     $JEq'9%:Er  c              3   *   #    U  H	  oS    v   M     g7f)rB  NrH  r  s     r*   rK  rD    s     "Eu!_#5ur  c              3   *   #    U  H	  oS    v   M     g7f)rA  NrH  r  s     r*   rK  rD    s     &Mu!)<'=ur  r  )r   
percentageavg_test_casesavg_age_daysavg_source_typesr   r   c                     U S   $ Nrh   rH  r  s    r*   r  =MongoHandler.get_user_segmentation_analysis.<locals>.<lambda>  s    [\]^[_r  Tr  Nr  rH  rJ  )preferred_source_typesactivity_levelengagement_levelPower Users)z3Provide advanced features and customization optionsz7Offer priority support and early access to new featuresz#Consider beta testing opportunitiesActive Users)z0Encourage exploration of additional source typesz0Provide tips for optimizing test case generationz+Offer training materials and best practicesRegular Users)z7Increase engagement through notifications and remindersz'Provide onboarding and tutorial contentz%Offer incentives for consistent usageOccasional Users)zImprove onboarding experiencezProvide quick-start templateszSend re-engagement campaigns	New Users)z Provide comprehensive onboardingz Offer guided tours and tutorialszSet up welcome series emailsc                     U S   S   $ )Nrh   r   rH  r  s    r*   r  rM    s    UVWXUYZgUhr  rT  c                     U S   S   $ )Nrh   rH  rH  r  s    r*   r  rM    s    YZ[\Y]^nYor  )largest_segmentmost_active_segmenttotal_segments)	r  r   r!  r  segment_groupssegment_statisticssegment_behaviorsegment_recommendationsr]  )r1   segmentation_analysisz*Error getting user segmentation analysis: z(Failed to retrieve segmentation analysis)rd   r   r   rH   rl   r   rw  r   r@   rZ   rB  _determine_user_segmentr   r   r&   rq  r   r  r  _get_activity_level_description!_get_engagement_level_descriptionr   rn   r  r'   r   r%   )r(   ro   r  r   r   rT  r   user_activity_datauser_segmentsrt  r  rB  r@  r[  r>   r\  r   r   rH  rI  rJ  r]  r   source_type_countsr   sorted_source_typesr^  r3  r_  r)   s                                 r*   get_user_segmentation_analysis+MongoHandler.get_user_segmentation_analysis&  s   s	]==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 "&doo&?&?L6:*>?@%)/%0.$A'-}&=&,m%<%!,/?AR.S T 3(!+ A ' "( M!3#44==umTYFZ>["#	^    <$%M#''55),L/I)I(O(O #::%&89%&:;%M.9:	G "((#&}U';#< ,V 4!-g!6 , 0 0 @#*,9:L,M-0~1N-O(5n(E)6_l  nB  `CeMBV4WYZ.[  IJ* - "4H  N%y/0.0N+'..t4	 & "$"0"6"6"8!%j\gjk\k$JE$J!J[!XqrWbefWfs"Eu"EESlm_jmn_n3&Mu&M#MP[#[tu  $/Xe%s=7I)IC)ORS"Tkl&+NA&>$),$:(-.>(B"/"+ #9   ""4":":"<>>)+& %g+/+?K>P>T>TU`bc>dgh>h.{; ,@ !/
 +11C1I1I1KQ_im*n' 3Fbq2I*.*N*NuUeOf*g,0,R,RSXYkSl,m1$W- #=$ ')#"4":":"<"$m+#** , 
 .#** , 
 /#** , 
  22#** , 
 +#** ,  4C'0E #=J  +(224MMO(+M(:"0&8$4+B qCs+=+C+C+EKh'ijk'l  IM xJ3/A/G/G/IOo+pqr+s  PT&)*<&=%!   $>STT 	]LLEc!fXNO$1[\\	]s1   Q9 CQ9 7GQ9 F,Q9 9
R3%R.(R3.R3c                 T    US::  a  gUS:  a  US:  a  gUS:  a  US:  a  gUS	:  a  g
g)z'Helper method to determine user segment   rU  2   r  rQ     rh   rR  rx  rS  rT  rH  )r(   r  r?  rB  source_types_counts        r*   r`  $MongoHandler._determine_user_segment  sA    A#(:a(? #(:a(?!""%r  c                 .    US:  a  gUS:  a  gUS:  a  gg)z/Helper method to get activity level descriptionrx  r  r  r  rh   r  r  rH  )r(   rH  s     r*   ra  ,MongoHandler._get_activity_level_description  s&    Qq q r  c                 .    US:  a  gUS:  a  gUS:  a  gg)z1Helper method to get engagement level descriptionr  r  r  r  rh   r  r  rH  )r(   rJ  s     r*   rb  .MongoHandler._get_engagement_level_description  s&    q ""r  c                 
    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n/ SQn0 nU R                  R                  SSU005      n	U	SSS.US'   U R                  R                  SU0SSS.S.5      n
U
U	S:  a  [        X-  S-  S5      OSU	S:  a  [        X-
  U	-  S-  S5      OSS.US'   [        U R                  R                  SSSU005      5      nUU	S:  a  [        X-  S-  S5      OSU
S:  a  [        X-
  U
-  S-  S5      OSS.US'   [        U R                  R                  SSSU000SSS S0S!.0SS"SS000/5      5      nUU	S:  a  [        X-  S-  S5      OSUS:  a  [        X-
  U-  S-  S5      OSS.US#'   [        U R                  R                  SSSU000SSS$S%0S&.0SS'SS(S)0S/000/5      5      nUU	S:  a  [        X-  S-  S5      OSUS:  a  [        X-
  U-  S-  S5      OSS.US*'   [        U R                  R                  SSSU000SSS S0S!.0SS"SS+000/5      5      nUU	S:  a  [        X-  S-  S5      OSUS:  a  [        X-
  U-  S-  S5      OSS.US,'   [        U R                  R                  SSSU000SSS S0S!.0SS"SS-000/5      5      nUU	S:  a  [        X-  S-  S5      OSUS:  a  [        X-
  U-  S-  S5      OSS.US.'   U	S:  a  [        X-  S-  S5      OSn[        S/ UR                  5        5       5      [        U5      -  n/ n[        UR                  5       S0 SS19SS2 nU HJ  u  nnUS3   S:  d  M  UR                  S4UR!                  S5S65      R#                  5        S7US3    S835        ML     [        UR                  5       S9 SS19SS2 nU HJ  u  nnUS:   S:  d  M  UR                  S;UR!                  S5S65      R#                  5        S<US:    S=35        ML     [%        U R                  R                  SSSU000SSS>S%S?S@.0S S0SA.0SBSCSD00SESF0/5      5      n/ nU HT  n[        USG   SH SI9nU Vs/ s H  nUSJ   PM
     nnUR                  ['        USK   5      UUSC   [        U5      SL.5        MV     UUR)                  5       UR)                  5       UUU	U[        US5      USM.UU/ SNQSO.	nSUSP.$ s  snf ! [*         a0  n[,        R/                  SQ['        U5       35        SSRS.s SnA$ SnAff = f)Sz0Get user conversion funnel analysis (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  )
registeredfirst_loginfirst_test_casemultiple_test_casesmultiple_source_typesregular_user
power_userr8   r   r  )r   rG  dropoffrt  TN$exists$ner8   r9   r  ru  rc   rv  r  r`  ra  rb  )r4   re  re  rw  rF  rq  )r4   rM  z$exprrH  z$source_typesrx  rx  ry  rl  rz  c              3   *   #    U  H	  oS    v   M     g7f)rG  NrH  )rI  stages     r*   rK  :MongoHandler.get_user_conversion_funnel.<locals>.<genexpr>  s     &]H\u\':H\r  c                     U S   S   $ )Nrh   r{  rH  r  s    r*   r  9MongoHandler.get_user_conversion_funnel.<locals>.<lambda>  s    1ir  r  r  r{  zBiggest dropoff at _ z stage: %c                     U S   S   $ )Nrh   rG  rH  r  s    r*   r  r    s    AaDDVr  rG  zBest performing stage: z with z% conversionrI  rd  )r   rR  )r4   journeyr  rp  r  r   z$limitr  r  c                     U S   $ NrR  rH  r  s    r*   r  r    s    !K.r  rT  r   r4   )rc   journey_pathr  journey_length)total_registeredoverall_conversion_rateaverage_stage_conversionfinal_stage_users)z9Focus on reducing dropoff at identified bottleneck stagesz/Implement onboarding improvements for new usersz=Create engagement campaigns for users at risk of dropping offz8Provide incentives for progression through funnel stagesz?Analyze successful user journeys for optimization opportunities)	r  r   r!  funnel_stagesfunnel_dataoverall_metricsfunnel_insightsuser_journeysr3  )r1   conversion_funnelz&Error getting user conversion funnel: z$Failed to retrieve conversion funnel)rd   r   r   rH   r   r   rq  r   r   rp  rw  r  rV  r  r   r   r   r  rl   r&   rn   r'   r   r%   )r(   ro   r  r   r   rT  r   r  r  r  first_login_usersusers_with_test_casesusers_with_multiple_test_casesusers_with_multiple_sourcesr   power_usersr  avg_stage_conversionr  biggest_dropoffsr  r   best_stagesuser_journey_datar  r  sorted_journeystepr  r  r)   s                                  r*   get_user_conversion_funnel'MongoHandler.get_user_conversion_funnel   s   L	Y==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
M K  $44DDvz2F   *!)K% !% 5 5 E E%z2*.t<G !
 +XhklXle%6%IC%ORSTrsjz}~j~5#3#GK["[^a"adef  EF*K& %((@(@vz2M ) %! /\lop\pe%:%MPS%SVWXvw qB  EF  qF5#4#LPa"adg"gjkl  LM.K)* .11J1JL6:*>?@%(.{  -{;<L 2 .* 8euxyeye%C%VY\%\_`a  @A BW  Z[  B[5#8#Y]r"rux"x{|}  ab2K-. +.doo.G.GL6:*>?@%%0.$A  Gf/I1.M%NOPI / +' 5bruvbve%@%SVY%Y\]^|} Qo  rs  Qs5#A#_  dB  #B  EH  #H  KL  M  yz4K/0   9 9L6:*>?@%(.{  -{;<; ! M 'TdghThe]%E%KaPno }X  [\  }\5#>#NRm"mps"svwx  bc+K' doo77L6:*>?@%(.{  -|<=9  K %RbefRfe[%Cc%IANlm^kno^o5=#>-"ORU"UXYZuv)K% [kmnZne[-Kc-QTU&Vtu##&&]HZHZH\&]#]`cdo`p#p  !O  &k&7&7&9?Xbfghjijk/t	?Q&#**-@sTWAXA^A^A`@aaijnoxjyizz{+|}  0
 !!2!2!4:V`defhghiK*t%)#**-DU]]SVX[E\EbEbEdDeeklpq}l~k  @L  ,M  N  +
 !%T__%>%>L6:*>?@%+9)6"  *0	 	 -r232@ & !" M,!'	(:@X!Y AOO] 3O$$"75>2$0(/0B(C&),&7	&  -  +(224MMO!.*(8/F056JA0N)4	$ $3!.$!.  $:KLLA  PD  	YLLA#a&JK$1WXX	YsD   T= NT= 3A)T=  BT= 7T8A1T= 8T= =
U7%U2,U72U7c                   ^'^(  U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSS0SSSSS/0SS/00SSSSS/0SS/00SS0SS0SS0S .0/5      5      n/ nU GH  n	U	S!   n
U
S:  a  U	S"   U
-  S#-  OSnSn[        US$-  S%5      S&-  n[        U
S'-  S%5      S(-  n[        [        U	S)   5      S*-  S%5      S+-  nSnU	R                  S,5      (       a+  U	S,   nUS-::  a  S.nOUS/::  a  S&nOUS0::  a  S1nOUS2::  a  S+nOS3nX-   U-   U-   nUS4:  a  S5nOUS6:  a  S7nOUS8:  a  S9nOUS::  a  S;nOS<nU R                  R                  S=U	S=   0SSSSS>.5      nU(       d  GM  UR                  [        U	S=   5      US?   US@   UR                  SASB5      [        US*5      U[        US*5      U
[        U	S)   5      [        U	R                  S,S5      S*5      UR                  S5      (       a  US   R                  5       OSCSD.5        GM     U(       Ga  [!        SE U 5       5      [        U5      -  n[        U Vs/ s H  nUSF   S5:X  d  M  UPM     sn5      [        U Vs/ s H  nUSF   S7:X  d  M  UPM     sn5      [        U Vs/ s H  nUSF   S9:X  d  M  UPM     sn5      [        U Vs/ s H  nUSF   S;:X  d  M  UPM     sn5      [        U Vs/ s H  nUSF   S<:X  d  M  UPM     sn5      SG.n[        U Vs/ s H  nUSH   SI:  d  M  UPM     sn5      [        U Vs/ s H  nSJUSH   s=::  a  SI:  d  M  O  M  UPM     sn5      [        U Vs/ s H  nSKUSH   s=::  a  SJ:  d  M  O  M  UPM     sn5      [        U Vs/ s H  nS-USH   s=::  a  SK:  d  M  O  M  UPM     sn5      [        U Vs/ s H  nUSH   S-:  d  M  UPM     sn5      SL.nOSn0 n0 n/ n[#        USM SNSO9SCS% nU(       a:  UR                  SP[        [!        SQ U 5       5      [        U5      -  S*5       35        U Vs/ s H  nUSF   SR;   d  M  UPM     nnU(       a=  [!        SS U 5       5      [        U5      -  nUR                  ST[        US*5       SU35        [        U5      S:  Ga3  U Vs/ s H  nUSH   PM
     snm(U Vs/ s H  nUSV   PM
     snm'[        U5      n[!        U'U(4SW j[%        U5       5       5      n[!        T(5      n[!        T'5      n[!        SX T( 5       5      n [!        SY T' 5       5      n!UU-  UU-  -
  UU -  UU-  -
  UU!-  UU-  -
  -  S.-  -  n"['        U"5      SZ:  a   UR                  S[[        U"S*5       S\35        ON['        U"5      S.:  a   UR                  S][        U"S*5       S\35        OUR                  S^[        U"S*5       S\35        / n#UR                  S;S5      UR                  S<S5      -   S:  a  U#R)                  / S_Q5        UR                  S`S5      S:  a  U#R)                  / SaQ5        [        U5      S:  aQ  [!        Sb U 5       5      [        U Vs/ s H  nUS,   S:  d  M  UPM     sn5      -  n$U$S0:  a  U#R                  Sc5        UUR                  5       UR                  5       [        U5      [        US*5      UUUUU#US6:  a  SdOSeSf[+        5       ;   a  [        U5      OSSg[+        5       ;   a  [        U5      OSSh.Si.n%SNU%Sj.$ s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf ! [,         a0  n&[.        R1                  Sk[        U&5       35        SSlS.s SCn&A&$ SCn&A&ff = f)mz8Get user satisfaction and feedback analysis (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  ra  rb  r  r  r  r  failedrF  rq  r  r  rc  rd  )r4   r  rv  failed_test_casesrM  r  rf  r  rv  r  rl  rx  皙?r  333333?rM  r  皙?r  r{        ?i,  iX  g433333?i  皙?g      @Very Satisfiedg      @	Satisfiedg      @Neutralg      ?DissatisfiedVery Dissatisfiedr4   r  r6   r.   r7   r>   N)rc   r6   r.   r7   r|  satisfaction_levelr  r  rA  r  r  c              3   *   #    U  H	  oS    v   M     g7fr~  rH  r  s     r*   rK  BMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>B  s     *dRc$0D+ERcr  r  )r  r  r  r  r  r  r5  r4  rz  )zExcellent (90-100%)zGood (80-89%)zAverage (70-79%)zBelow Average (60-69%)Poor (<60%)c                     U S   $ r  rH  r  s    r*   r  AMongoHandler.get_user_satisfaction_and_feedback.<locals>.<lambda>^  s
    QG[E\r  Tr  z5Top performers have an average satisfaction score of c              3   *   #    U  H	  oS    v   M     g7fr~  rH  r  s     r*   rK  r  `  s/       k\  M[  HI  nB  lC  M[r  )r  r  c              3   *   #    U  H	  oS    v   M     g7f)r  NrH  r  s     r*   rK  r  e  s     &YBXQ'8BXr  z7Low satisfaction users have an average success rate of r  r|  c              3   :   >#    U  H  nTU   TU   -  v   M     g 7fNrH  )rI  r   satisfaction_scoressuccess_scoress     r*   rK  r  o  s#     ZQYA^A.1DQ1GGQYs   c              3   *   #    U  H	  oU-  v   M     g 7fr  rH  )rI  r  s     r*   rK  r  r  s     ;NqUNr  c              3   *   #    U  H	  oU-  v   M     g 7fr  rH  )rI  ys     r*   rK  r  s  s     @,?qU,?r  ffffff?zStrong correlation (z') between success rate and satisfactionzModerate correlation (zWeak correlation ()z7Focus on improving success rates for dissatisfied usersz1Provide additional training and support resourcesz)Implement user feedback collection systemr  )z(Investigate causes of high failure ratesz(Improve error handling and user guidancez&Consider simplifying complex workflowsc              3   @   #    U  H  oS    S:  d  M  US    v   M     g7f)r  r   NrH  r  s     r*   rK  r    s'     )~L]qcxay|}a}*B!,A*BL]r  z?Optimize test case generation process to reduce completion time	ImprovingzNeeds Attentiontop_performerslow_satisfaction_users)satisfaction_trendtop_performers_countimprovement_needed_count)r  r   r!  r  r  r  success_rate_distributionr  feedback_insightsimprovement_recommendationsr]  )r1   satisfaction_analysisz.Error getting user satisfaction and feedback: z(Failed to retrieve satisfaction analysis)rd   r   r   rH   rl   r   rw  minr   rZ   r   r@   r   r&   rq  rn   r  r  r  absr   localsr'   r   r%   ))r(   ro   r  r   r   rT  r   r"  satisfaction_datar%  total_casesr  r|  success_scoreactivity_scorediversity_scorecompletion_scoreavg_timer  r  r  r  r  r  r  r  r  avg_success_ratensum_xysum_xsum_ysum_x2sum_y2correlationr  r  r  r)   r  r  s)                                          @@r*   "get_user_satisfaction_and_feedback/MongoHandler.get_user_satisfaction_and_feedback  s.
   X	]==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
   9 9L6:*>?@%)/EI{3K+LaQR*S T. EIx3H+I1a*P Q* &1.$A,24F+G&,m%< ; ! L$ !#+)*<=]hkl]l,C D{ RUX Xrs &'" !$L2$5q 9C ? "%[2%5q!9C!? #&c+n*E&F&JA"NQT"T $% ??#899*+@AH2~+2(!S+2(!S+2(!T)+2(+2( &3%Co%UXh%h" &,)9&'3.)4&'3.)2&'3.)7&)<&  $44==ukRWFX>Y"#	\    <%,,#&{5'9#: ,V 4!-g!6 , 0 0 @.34F.J.@(-lA(>,7-0^1L-M/4[__EZ\]5^`a/bP\P`P`amPnPnl<&@&J&J&Ltx. q  ,N !'**dRc*d'dgjk|g}'}$ '*6G*w6G1MaKbfvKv16G*w&x!$1B%m1BAaH\F]alFla1B%m!n"/@#i/@!AFZD[_hDhA/@#ij$'4E(s4EqK_I`drIr4E(s$t),9J-}9JAaPdNei|N|a9J-})~-) ,/;L/h;LaPQR`PaegPg;L/h+i%(5F)g5F"PQR`PaJfdfJf!Jf!5F)g%h(+8I,j8I1RSTUcSdMigiMiQMiQ8I,j(k.1>O2p>OSUYZ[iYjSomoSo1So1>O2p.q#&3D'_3Da.HY\^H^3D'_#`-) ()$,.),.) !# $$5;\fjklnmnoN!((+`afgj  k\  M[  k\  h\  _b  cq  _r  hr  tu  bv  aw  *x  y 2C  &H1BAaH\F]  bG  GGa1B"  &H%#&&YBX&Y#Y\_`v\w#w !((+bchiy{|c}b~~  *A  B $%)=N!O=N!N"3=N!OHY&ZHY1q)='>HY&Z# )*ZQVWXQYZZN+/0;N;;@,?@@ 6zEEM9q6zETYM?Y^_bh^hkpsxkx^x>y  B  >B  B{#c)%,,/CE+WXDYCZ  [B  .C  D%+%,,/EeKYZF[E\  ]D  .E  F%,,/A%UVBWAXX  .A  B +-'(,,^Q?B[B_B_`suvBwwz{{+22 4  ),,]A>B+22 4  $%)&))~L])~&~  BE  Rc  FD  Rc  MN  gh  i~  g  BC  gC  GH  Rc  FD  BE  'E#&,/667xy  +(224MMO(+,=(>(-.BA(F-F-F->%6/J9MPS9S+YjCSW]W_C_C,?efOgkqksOs4J0Kyz%!$  $>STTA +x%m#i(s-}
 0i)g,j2p'_  &H "P&ZJ FD0  	]LLI#a&RS$1[\\	]s7  _ F3_ C_ -^>^_ ^
$^
*_ 9^
^_ ^0^6_ ^^_ .^$?^$_ ^)
,^)
0^)
6_ ^.^.!^.'_ 6^3^3^3_ '^88^8>A&_ $^=5^=;A_ _$_ +_:F_ _
%_
+B_ A_ 
`%` ``c                 	    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nO5US	:X  a	  XT" SS
9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSSSSS.0SS0SS0SS0S.0SSS00/5      5      n/ n/ n	/ n
/ nU GHO  nUS    nU R                  R                  S U0SSSSSS!.5      nU(       d  M6  US   nUS"   nUS#   nU(       a%  U(       a  UU-
  R                  nUS:  a  UU-  nOUnOSnU(       a  UU-
  R                  OSnU R                  UUUUS$   5      nU R                  U5      n[        U5      US%   US&   UR                  S'S(5      UUUS)   US*   US+   S,.	nUR                  U5        US)   S-:  a  U	R                  U5        GM  US*   S.:  a  U
R                  U5        GM2  US+   S/::  d  GM>  UR                  U5        GMR     U(       a  [        S0 U 5       5      [!        U5      -  n[        S1 U 5       5      [!        U5      -  n[        S2 U 5       5      [!        U5      -  n[!        U Vs/ s H  nUS3   S-:  d  M  UPM     sn5      n[!        U Vs/ s H  nUS*   S.:  d  M  UPM     sn5      n[!        U Vs/ s H  nUS+   S/::  d  M  UPM     sn5      nOS=n=nnS=n=nn/ nUS4:  a"  UR                  S5[#        US6-  S5       S735        US-:  a"  UR                  S8[#        US6-  S5       S935        US::  a"  UR                  S;[#        US6-  S5       S<35        US:  a  UR                  U S=35        US:  a  UR                  U S>35        / n U	(       a  U R%                  / S?Q5        U
(       a  U R%                  / S@Q5        U(       a  U R%                  / SAQ5        U R'                  X5      n!UUR)                  5       UR)                  5       [!        U5      [#        USB5      [#        USB5      [#        USB5      UUUSC.UU	U
USD.UU U!US4:  a  SEO	USF:  a  SGOSHUS-:  a  SEO	US::  a  SGOSHUS4:  a  SIO	US/:  a  SJOSKSL.SM.n"SNU"SO.$ s  snf s  snf s  snf ! [*         a0  n#[,        R/                  SP[        U#5       35        SSQS.s SRn#A#$ SRn#A#ff = f)Sz*Get user predictive analytics (admin only)Frg   r0   r   r
   r   rh   rA  r  r  r	  r_  r
  r  r  r8   r   r`  ra  rI  rd  rq  r  )rR  r   rj   rb  rd  rc  )r4   
activitiesr  r  rf  rp  r  r   r4   )r6   r.   r7   r8   r9   r  rf  r  r6   r.   r7   r>   
churn_riskgrowth_potentialr  )	rc   r6   r.   r7   predictionsuser_category
risk_scorer  r  r  皙?r  c              3   *   #    U  H	  oS    v   M     g7f)r  NrH  r  s     r*   rK  =MongoHandler.get_user_predictive_analytics.<locals>.<genexpr>  s     $O>N|_>Nr  c              3   *   #    U  H	  oS    v   M     g7f)r  NrH  r  s     r*   rK  r         *[JZQ-?+@JZr  c              3   *   #    U  H	  oS    v   M     g7f)r  NrH  r  s     r*   rK  r     r  r  r  333333?zHigh overall churn risk (r  z#%) - implement retention strategieszStrong growth potential (z%%) - focus on expansion opportunitiesr  zLow engagement levels (z#%) - implement engagement campaignsz8 users at high churn risk - prioritize retention effortsz6 users with high growth potential - focus on expansion)z:Implement targeted retention campaigns for high-risk usersz+Provide personalized support and incentivesz.Analyze common patterns among churn-risk users)zCOffer advanced features and premium options to high-potential usersz1Provide upselling and cross-selling opportunitiesz'Create loyalty programs for power users)z4Send re-engagement campaigns to low-engagement usersz-Provide onboarding improvements and tutorialszImplement gamification elementsr  )average_churn_riskaverage_growth_potentialaverage_engagement_scorehigh_risk_usershigh_potential_userslow_engagement_users)churn_risk_usersgrowth_potential_usersengagement_opportunitiesr  r  r  r  GoodFairPoor)overall_risk_levelgrowth_opportunityengagement_status)r  r   r!  r  predictive_metricsuser_predictionsuser_categoriespredictive_insightsaction_recommendationspredictive_trendsr]  T)r1   predictive_analyticsz)Error getting user predictive analytics: z'Failed to retrieve predictive analyticsN)rd   r   r   rH   rl   r   rw  r   r@   rB  _predict_user_behavior_categorize_user_for_predictionr&   rZ   r   r  r   rq  r   _calculate_predictive_trendsrn   r'   r   r%   )$r(   ro   r  r   r   rT  r   user_activity_patternsr  r  r  r  r6  rc   r  r  r  rf  activity_perioddaily_activity_ratedays_since_last_activityr  r  user_predictionavg_churn_riskavg_growth_potentialavg_engagement_scorer  r  r  r  r  r  r  r  r)   s$                                       r*   get_user_predictive_analytics*MongoHandler.get_user_predictive_analytics  sf   J	\==//#(5`aa 5//#Ce# 9!#44
& 91#55
' 9"#55
& 9##66
 9"#55
 &*$//*C*CL6:*>?@%)6+9&/"# *0'-}&=&,m%<  -r23E + &"&  "!%'"')$ 6&u-  $44==ug>N"#"#Q    <'34F'G$%12B%CN$0$AM &-+8>+I*O*O*Q.2B_2T/2B/./+ N[m0C/I/I`a, #'"="=(+0$\2	#K %)$H$H$UM $'w< ,V 4!-g!6 , 0 0 @'2)6&1,&?,78J,K,78J,K
'O %++O< #<0C7(//@$%78C?.55oF$%78C?077H !7D  !$$O>N$O!ORUVfRg!g'**[JZ*['[^abr^s's$'**[JZ*['[^abr^s's$ #&2B&]2BQaoY\F\q2B&]"^'*7G+h7G!1M_K`dgKgA7G+h'i$'*7G+h7G!1M_K`dgKgA7G+h'i$OPPP!58LPQQQ"69M #%##**-Fu^^aMacdGeFf  gJ  ,K  L#c)#**-FuMadgMgijGkFl  mR  ,S  T#c)#**-DUK_beKeghEiDj  kN  ,O  P"#**o->>v+wx#a'#**.B-CCy+z{ &("&-- /  &&-- /  (&-- /  !% A ABR `  +(224MMO(+,<(=*/*B056JA0N056JA0N'6,@,@' %5(8.D0H$
 (;*@%64BS4H&ZhknZnhty4H34N&`twz`zT\  AF3G#3M]qtw]wSY  ~D-$ :  $=QRRc '^+h+hb  	\LLDSVHMN$1Z[[	\sn   R3 CR3 ?DR3 B R3 R$R$R3 .R)?R)R3 R.&R.,F7R3 $R3 3
S-=%S("S-(S-c                    SnUS:  a  US-  nO#US:  a  US-  nOUS:  a  US-  nOUS:  a  US	-  nUS	:  a  US-  nOUS
:  a  US-  nOUS:  a  US	-  nUS:  a  US-  nOUS:  a  US	-  n[        U5      S:  a  U Vs/ s H  ofS   PM	     nnUR                  5         / n[        S[        U5      5       H*  n	Xy   XyS-
     -
  R                  n
UR	                  U
5        M,     U(       a"  [        U5      [        U5      -  nUS:  a  US	-  nSnUS:  a  US-  nO#US:  a  US-  nOUS
:  a  US-  nOUS	:  a  US	-  nUS:  a  US-  nOUS:  a  US-  nOUS:  a  US	-  n[        S U 5       5      n[        U5      S:  a  US-  nO[        U5      S:  a  US	-  nUS::  a  US	-  nSnUS:  a  US-  nO#US
:  a  US-  nOUS:  a  US-  nOUS	:  a  US	-  nUS::  a  US-  nOUS::  a  US-  nOUS::  a  US	-  nUS:  a  US-  nOUS:  a  US	-  n[        U5      S:  a  US	-  n[        US5      [        US5      [        US5      S.$ s  snf )z&Helper method to predict user behaviorr   r_  r     r  rj  r  r  r  r        ?rx  r  rh   rR  r  rl  c              3   *   #    U  H	  oS    v   M     g7fr   NrH  )rI  as     r*   rK  6MongoHandler._predict_user_behavior.<locals>.<genexpr>  s     @Z]+Zr  )r  r  r  )r   r   r  rB  r   r  setr  )r(   r  r
  r  r  r  r  
timestampsgapsr   gapavg_gapr  rM  r  s                  r*   r  #MongoHandler._predict_user_behaviorz  s2    
 $b(#J%*#J%)#J%)#J $#J 3&#J 3&#J a#J"#J z?Q2<=*QK.*J=OOD1c*o.!}zA#6<<C  / d)c$i/Q;#%J  !## A%# C'# C'# r!###"# @Z@@|!#!## $q(#  !## C'# C'# C'# $q(#%*#%*# r!#"# |!# j#. #$4c : #$4c :
 	
Y >s   ?I
c                 t    US   nUS   nUS   nUS:  a  gUS:  a  gUS::  a  g	US:  a  US
:  a  gUS:  a  gg)z6Helper method to categorize users based on predictionsr  r  r  r  zHigh Churn Riskr  zHigh Growth Potentialr  zLow Engagementr  z
Power Userr  zEngaged UserzStandard UserrH  )r(   r  r  r  r  s        r*   r  ,MongoHandler._categorize_user_for_prediction  sf     .
&'9:&'9:$$*$#$)9S)@$!"r  c                 x   U(       d  0 $ 0 nU H  nUS   nXS;  a  SX5'   X5==   S-  ss'   M     [        U5      n0 nUR                  5        H  u  pX[        X-  S-  S5      Xu'   M     / n	[        UR                  5       S SS9 H$  u  pZU
S	:  d  M  U	R	                  U S
U
 S35        M&     UUU	[        U5      S.$ )z,Helper method to calculate predictive trendsr  r   rh   r  r  c                     U S   $ rL  rH  r  s    r*   r  ;MongoHandler._calculate_predictive_trends.<locals>.<lambda>  s    WXYZW[r  Tr  rl  r   z
% of users)category_distributioncategory_percentagesdominant_trendstotal_categories)r   r   rq  r  r   )r(   r  r  category_countsr>   categoryr   r%  r   r&  rG  s              r*   r  )MongoHandler._calculate_predictive_trends  s    I $DO,H.,-)%*%	 % *+!.446OH-2E4G33NPQ-R *  7 $*+?+E+E+G^ei$j HR&&(2j\'LM %k
 &5$8. #O 4	
 	
r  c                 p    U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nODUS	:X  a	  XT" S
S9-
  nO5US:X  a	  XT" SS9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n0 nU R	                  U5      nUS   (       a  US   US'   U R                  X5      n	U	S   (       a  U	S   US'   U R                  X5      n
U
S   (       a  U
S   US'   U R                  XS9nUS   (       a  XS'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  X5      nUS   (       a  US   US'   U R                  U5      nUS   (       a  US   US'   U R!                  U5      nUS   (       a  US    US!'   U R#                  Xr5      nU R%                  U5      nU R'                  U5      nU R)                  U5      nUUR+                  5       UR+                  5       UUUUU[-        U5      U R/                  U5      UR+                  5       [-        U5      [-        U5      S".S#.	nS$US%.$ ! [0         a0  n[2        R5                  S&[7        U5       35        SS'S.s S(nA$ S(nAff = f))zCGet comprehensive user analytics combining all metrics (admin only)Frg   r0   r   r
   r   rh   rA  r  rj  r	  r_  r  r5  r
  r  r1   r   r(  rU  ro  )r  performance_metricsr4  r_  r  r  r  r  r  r+  r6  r*  )total_metrics_analyzeddata_completenessanalysis_timestamprecommendations_countinsights_count)	r  r   r!  overall_health_scoreexecutive_summarykey_insightsstrategic_recommendationsanalytics_datar]  T)r1   comprehensive_analyticsz,Error getting comprehensive user analytics: z*Failed to retrieve comprehensive analyticsN)rd   r   r   rH   r   r`  rs  r&  r<  rg  r  r  r  r  r  r-  r?  _generate_executive_summary_generate_key_insights#_generate_strategic_recommendations_calculate_overall_health_scorern   r   _calculate_data_completenessr'   r   r%   r&   )r(   ro   r  r   r   rT  r   r6  r,  rU  ro  r,  r4  r_  r  r  r  r  r  r+  r*  r3  r4  r5  r2  r7  r)   s                              r*    get_comprehensive_user_analytics-MongoHandler.get_comprehensive_user_analytics  s   |	_==//#(5`aa 5//#Ce# 9!#44
& 9!#44
' 9"#55
	) 9"#55
& 9##66
 9"#55
  N 11-@J)$4>|4L01  $==mY	*5EFX5Y12 "&!A!A-!]!),7IJ^7_34 #'"C"CM"C"k"9-8K45 !% ? ? [ +6GH[6\23 %)$G$G$c!$Y/:OPg:h67 !% ? ? [ +6GH[6\23 "&!A!A-!]!),7IJ^7_34 !77SMY'2?2P/ %)$K$KM$g!$Y/:OPg:h67 $(#E#Em#a #I.9MNd9e56 #66}EOy)4CDU4V01 !99-HMY'2?2P/ !% @ @ ]  66~FL )-(P(PQ_(`% $(#G#G#W   +(224MMO(<%6 ,-F"0.1..A)-)J)J>)Z*---/-01J-K&),&7'#$  $@WXX 	_LLGAxPQ$1]^^	_s#   K; KK; ;
L5%L0*L50L5c           	         SU S3/ 0 / / / S.nSU;   aU  US   nUS   R                  SUR                  SS5       3S	UR                  S
S5       3SUR                  SS5       3/5        SU;   a-  US   nUR                  SS5      UR                  SU5      S.US'   SU;   aB  US   nUS   R                  SUR                  SS5       3SUR                  SS5       S3/5        SU;   a>  US   nUR                  S0 5      R                  SS5      nUS   R                  SU 35        SU;   aC  US   n	US   R                  S U	R                  S!S5       S3S"U	R                  S#S5       S3/5        U$ )$z.Generate executive summary from analytics dataz(Comprehensive user analytics report for z period)overviewkey_highlightsperformance_overviewr  risksopportunitiesr(  rA  zTotal users: r   r   zActive users: r   zNew users this month: r   r,  r  )r  r  rB  r  r  zTotal new users: r  zAverage growth rate: r  r  r  r]  r  r  rC  zOverall churn risk level: ro  rD  zEngagement rate: ri  zActivity rate: rj  )r   rZ   r   )
r(   r6  r  r]  r   perfr  pred
risk_level
engagements
             r*   r8  (MongoHandler._generate_executive_summary  s    C;-wW $&
 ."#45E$%,,		- ;<= >1!= >?(3I1)M(NO.  !N2!"78D(,(B#xx{C/G*+ n,#O4FH$$#FJJ/@!$D#EF'

3H!(L'MQO&  "^3!"89D)R0445I9UJG##&@$MN  >1'(<=JO$++#JNN3Da$H#IK!*..!"D!EQG- 
 r  c                 *   / nSU;   a3  US   nUR                  SS5      S:  a  UR                  SUS    S35        SU;   a,  US   nUR                  SS5      S:  a  UR                  S	5        S
U;   a<  US
   nUR                  S0 5      R                  SS5      S:  a  UR                  S5        SU;   a]  US   nUR                  S5      (       aB  [        S US    5       5      [        US   5      -  nUR                  S[	        US5       35        U$ )z)Generate key insights from analytics datar  r  r   zUser growth is positive with z
 new usersro  ri  rk  zGUser engagement is below optimal levels - consider engagement campaignsr  r  r  rz  z<First-week retention needs improvement - focus on onboardingr,  r"  c              3   *   #    U  H	  oS    v   M     g7fr  rH  r  s     r*   rK  6MongoHandler._generate_key_insights.<locals>.<genexpr>  s     $YDXq'9%:DXr  Average test cases per user: rh   )rZ   r   r  r   rq  )r(   r6  insightsr  rH  	retentionrE  rH  s           r*   r9  #MongoHandler._generate_key_insights  s6    n,#O4Fzz+Q/!3"?GX@Y?ZZd ef  >1'(<=J~~/3b8 ij  >1&';<I}}8"=AABTVWX[]] ^_ !N2!"78Dxx''!$$YDDX$Y!Y\_`des`t\u!u"?nVW@X?Y Z[r  c                    / nSU;   a,  US   nUR                  SS5      S:  a  UR                  S5        SU;   a<  US   nUR                  S0 5      R                  SS5      S	:  a  UR                  S
5        SU;   a,  US   nUR                  SS5      S:  a  UR                  S5        SU;   ai  US   nUR                  S5      (       aN  US    Vs/ s H  owS   S:  d  M  UPM     nn[        U5      [        US   5      S-  :  a  UR                  S5        SU;   a+  US   n	U	R                  S5      S:X  a  UR                  S5        U$ s  snf )z6Generate strategic recommendations from analytics datar  r  r   r  z:Implement user acquisition strategies to increase sign-upsr  r  r  r_  z;Develop long-term retention strategies and loyalty programsro  ri  r{  zCImplement user engagement campaigns and feature adoption strategiesr,  r"  r  rx  r  z@Provide additional support and training for low-performing usersr*  rO  r>  z7Address system health issues to improve user experience)rZ   r   r   )
r(   r6  r3  r  rO  rH  rE  r  low_performershealths
             r*   r:  0MongoHandler._generate_strategic_recommendations  su    n,#O4Fzz+Q/"4&&'cd  >1&';<I}}8"=AABTVWX[]]&&'de  >1'(<=J~~/3b8&&'lm !N2!"78Dxx''-1.-A!_-AGYEZ]^E^!-A!_~&T.-A)BS)HH#**+mn n,#O4Fzz*+{:&&'`a "`s   E!Ec                 L   SnSnSU;   a0  US   n[        UR                  SS5      S-  S5      nX%S-  -  nUS-  nSU;   a0  US   n[        UR                  SS5      S	-  S5      nX'S-  -  nUS-  nS
U;   a@  US
   n[        UR                  S0 5      R                  SS5      S	-  S5      n	X)S-  -  nUS-  nSU;   a*  US   n
U
R                  S5      S:X  a  SOSnX+S-  -  nUS-  nUS:  a  X#-  nOSn[        US	-  S5      nUS:  a  SnOUS:  a  SnOUS:  a  SnOSnUUUS.$ )z9Calculate overall system health score from analytics datar   r  r  r  r  g      ?ro  ri  r  r  r  r  r*  rO  r&  r  rh   r4  	Excellentr{  r  (   r  r  )scorer)  factors_analyzed)r  rZ   rq  )r(   r6  health_scoretotal_factorsr  growth_scorerH  r  rO  retention_scorerS  system_scorefinal_scorehealth_percentagehealth_categorys                  r*   r;  ,MongoHandler._calculate_overall_health_score  s    n,#O4Fvzz*;Q?"DcJL4//LT!M  >1'(<=J":>>2CQ#G##MsSt33LT!M  >1&';<I!)--0KR"P"T"TUgij"knq"qsvwOd22LT!M n,#O4F"(**-=">)"K3QTL4//LT!M 1&6KK "+"3Q7")O"$$O"$$O$O '' -
 	
r  c                     Sn[        U5      n[        X2-  S-  S5      nUS:  a  SnOUS:  a  SnOUS:  a  S	nOS
nUUUUS.$ )z&Calculate data completeness percentage   r  rh   r5  rV  K   r  r{  r  r  )rG  r  available_metricstotal_possible_metrics)r   rq  )r(   r6  rg  rf  completeness_percentagecompleteness_levels         r*   r<  )MongoHandler._calculate_data_completenessQ  ss    !#/"'):)SWZ(Z\]"^"b(!,$*!'$*!'!' 2'!2&<	
 	
r  c                     U R                   R                  SS05      nU(       a  SSS.$ [        [        R                  " 5       5      UR                  5       [        R                  " UR                  S5      [        R                  " 5       5      US[        R                  " 5       SSSSSSSSSSSSSS	.S
.	nU R                   R                  U5      nUR                  (       a_  [        R                  SU 35        U R!                  SS[        UR                  5      SU S3S9  SS[        UR                  5      UUSS.S.$ SSS.$ ! ["         a0  n[        R%                  S[        U5       35        SSS.s SnA$ SnAff = f)zGCreate the initial admin user (should only be called once during setup)r7   rQ   Fz7Admin user already exists. Cannot create another admin.r0   r3   NTr  )	r4   r.   r5   r6   r7   r8   r9   r:   r  z)Initial admin user created successfully: SYSTEM_SETUPinitial_admin_createdzInitial admin user z created during system setup)ro   r  r  r  z'Initial admin user created successfullyr<   )r1   r2   
admin_userrR   z#Error creating initial admin user: )r   r@   r&   rF   rG   rA   rB   rD   rE   rC   r   rH   rI   r   r   r    r  r'   r%   )r(   r.   r5   r6   rS   admin_user_docrT   r)   s           r*   create_initial_admin_user&MongoHandler.create_initial_admin_userh  s   <	P!22;;VW<MNN#(5noo 4::<("MM(//'*BFNNDTU&oo/"!(,(,-1*.-1'+(,'+)-*.-1 N2 **55nEF!!GwOP %%"0 7!&"4"451%8TU	 &   $H!&"4"45!& $ '	#	 	 $)5RSS 	PLL>s1vhGH$1NOO	Ps)   (E DE E 
F%E<6F<Fc                     U R                   R                  SU05      nU(       d  SSS.$ [        U R                  R	                  SU0SSSSSS.5      R                  SS	5      R                  S
5      5      nU H8  nSU;   a  [        US   5      US'   SU;   d  M"  US   R                  5       US'   M:     UR                  SS5      nU R                  U5      n[        U5      n[        U Vs/ s HN  oR                  SS5      R                  [        R                  " 5       R                  S5      5      (       d  ML  UPMP     sn5      n	Sn
U(       a  US   n
[        US   5      US   US   UUR                  S5      (       a  US   R                  5       OSUR                  S5      (       a  US   R                  5       OSS.UU	U
S.UUS   (       a  UR                  S0 5      O0 US.nUS:X  a  U R!                  U5      nXS'   SUS.$ s  snf ! ["         a0  n[$        R'                  S[        U5       35        SSS.s SnA$ SnAff = f)r
  r4   Fr   r0   rc   rh   r  r8   r   r  r7   r>   r  r  Nr   r6   r.   r9   r  r  r1   r  )r  r   r   r  r7   rQ   
admin_dataTr  r  r  )r   r@   rl   r   rm   r   r   r&   rn   rZ   r  r   
startswithr   rH   rW  _get_admin_dashboard_datar'   r   r%   )r(   rc   r>   r  r  r7   r  r  tcthis_month_test_casesr  r  rs  r)   s                 r*   r   r!    sx   <	V((115'2BCD#(5EFF #4??#7#7G$AQqTUV$ d<$UU2Y0O -	I%'*9U+;'<Ie$9,.7.E.O.O.QIl+	 - 88FF+D33G<K  #?3$'o  )SoP\^`IaIlIlmum|m|m~  nH  nH  IP  nQ  JRo  )S  %T! "N!0!3
 d5k* L!'] DHHH\DZDZ$|"4">">"@`dDHHH\DZDZ$|"4">">"@`d )9"7&4
 .EPQZE[{}bAac!N( w!;;GD
/9|,#~FFA )SD  	VLL>s1vhGH$1TUU	VsD   (H A,H AH ,AH	;H	CH 	H 
I%I=IIc                     U R                  U5      nU R                  U5      nU R                  US5      nU R                  U5      nUS   (       a  UR	                  S0 5      O0 US   (       a  UR	                  S0 5      O0 US   (       a  UR	                  S/ 5      O/ US   (       a  UR	                  S0 5      O0 / SQS.nU$ ! [
         a-  n[        R                  S	[        U5       35        0 s S
nA$ S
nAff = f)z!Get admin-specific dashboard datar  r1   r+  r   rU  r6  )zView all userszSystem health checkzUser analyticszBackup datazExport reports)r+  r(  r  r*  quick_actionsz$Error getting admin dashboard data: N)	r-  r   r`  r?  rZ   r'   r   r%   r&   )r(   ro   r+  r,  r  r*  rs  r)   s           r*   ru  &MongoHandler._get_admin_dashboard_data  s    	"66}EO 11-@J #<<]FSO !99-HM RaajQk?#6#67H"#MqsGQR[G\:>>,#CbdRabkRl?#6#67I2#NrtKXYbKc!2!2?B!Gik"J  	LL?AxHII	s   C C 
C:"C5/C:5C:c                 L    SSK J nJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nODUS:X  a	  XT" SS9-
  nO5US:X  a	  XT" S	S9-
  nO&US
:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" S	S9-
  n[        U R                  R                  USU0S.SSSSSS.5      R                  SS5      5      nU R                  R                  SU0SSS.5      n/ n	U(       a0  UR                  S5      (       a  U	R                  SUS   SSSS.5        U Ha  n
U	R                  SU
S   SU
R                  SS5       3SS[        U
S   5      U
R                  SS5      U
R                  S S!5      S".S#.5        Mc     U(       a0  UR                  S$5      (       a  U	R                  S%US$   S&S'SS.5        U	R                  S( S)S*9  U	 H  nUS+   R                  5       US+'   M     0 nU	 H'  nUS+   S,S- nX;  a  / X'   X   R                  U5        M)     [        U	5      n[        U	 Vs/ s H  oS.   S:X  d  M  UPM     sn5      n[        U	 Vs/ s H  oS.   S/;   d  M  UPM     sn5      n[        U	5      S:  a^  [        U	S0 S19n[        U	S2 S19nUR                   " US+   5      nUR                   " US+   5      nUU-
  R"                  nUS:  a  UU-  nOUnOUnUUU[%        US35      U(       a  [        UR'                  5       S4 S19S   OS,U R)                  U	5      S5.nUUR                  5       UR                  5       UU	UUUU:  a  SOS6U R+                  U5      US:  a  S7OS8S9.S:.nS)US;.$ s  snf s  snf ! [,         a0  n[.        R1                  S<[        U5       35        S=S>S?.s S,nA$ S,nAff = f)@z/Get user activity timeline with detailed eventsr   r
   r   rh   rA  r  r  r	  r_  r  r5  r
  r  r   r  )r4   r8   r   rj   r  r8   r   r4   r  user_registrationzUser account createdz	user-plusaccount)
event_typerR  descriptioniconr)  test_case_generatedzGenerated test case from r   unknownzfile-earmark-textr  r  Untitled)test_case_idr   r  )r~  rR  r  r  r)  r  r9   
user_loginzUser logged inzbox-arrow-in-rightc                     U S   $ r  rH  r  s    r*   r  9MongoHandler.get_user_activity_timeline.<locals>.<lambda>R  s    q~r  Tr  rR  Nr  r~  )r|  r  c                     U S   $ r  rH  r  s    r*   r  r  h  s    ;r  rT  c                     U S   $ r  rH  r  s    r*   r  r  i  s    +r  r  c                     [        U S   5      $ rL  )r   r  s    r*   r  r  |  s    SQRSTQUYr  )total_eventstest_case_eventsaccount_eventsevents_per_daymost_active_dayactivity_streakaccount_activityCompletezNo activity)most_common_eventrO  timeline_completeness)r  r   r!  r  timeline_eventsevents_by_daterU  r]  )r1   timeline_dataz&Error getting user activity timeline: Fz$Failed to retrieve activity timeliner0   )r   r   rH   rl   r   rm   r   r   r@   rZ   r   r&   rn   r   r  r  r  rB  rq  r   _calculate_activity_streakra  r'   r   r%   )r(   rc   r  r   r   rT  r   test_case_activitiesr>   r  rz  eventr  date_keyr  r)   r  r  first_event
last_event
first_date	last_datedays_betweenr  rU  r  s                             r*   get_user_activity_timeline'MongoHandler.get_user_activity_timeline  s?   F	Y4//#Ce# 9!#44
& 91#55
' 9"#55
	) 9"#55
& 9##66
 9"#55
 $((<(<#FJ3GH1TUV) d<$$&  ((115'2BE D !O ..&&"5!%l!3#9' )(  1&&"7!),!7%>x||M[d?e>f#g/ +(+HUO(<'/||M9'M!)gz!B (  1 ..&&".!%l!3#30 )(    %=t L )%*;%7%A%A%Ck" )  N( -cr21/1N,(//6	 ) /L"#k!L/UjBjA#kl _!w_,Sv@v!_!wxN ?#a'!/7OP 6NO
%33K4LM
$22:k3JK	 )J 6<<!#%1L%@N%1N!- !-$4"0"'":^l3~';';'=CV#WXY#Zrv#'#B#B?#S   +(224MMO ,#2"0$4BRUcBc)>i{&*&J&J>&Z;G!;KZQ^M  $mDD[ $l!w\  	YLLA#a&JK$1WXX	YsI   HM) M)M/M) ?M$M$D	M) 
M) )
N#3%NN#N#c                    U(       d  g[        US S9nSnSnSnU HW  n[        R                  " US   5      R                  5       nUc  SnO%Xu-
  R                  S:X  a  US-  nO[        XC5      nSnUnMY     [        XC5      nU$ )z Calculate user's activity streakr   c                     U S   $ r  rH  r  s    r*   r  9MongoHandler._calculate_activity_streak.<locals>.<lambda>  s    anr  rT  NrR  rh   )r  r   r  rE  rB  r  )r(   r  sorted_eventscurrent_streak
max_streaklast_event_dater  
event_dates           r*   r  'MongoHandler._calculate_activity_streak  s     4LM
"E!//k0BCHHJJ&!".449!# <
!"(O # 4
r  c                 d    [        U R                  R                  SU0SSSSS.5      R                  SS5      5      nU R                  R                  SU0SSS.5      nU(       d  SSS	.$ / n/ n[        U5      S:  a/  US
   nUR                  SSSSSUS   R                  5       SS.5        [        U5      S:  a/  US   nUR                  SSSSSUS   R                  5       SS.5        [        U5      S:  a/  US   nUR                  SSSSSUS   R                  5       SS.5        [        U5      S:  a/  US   n	UR                  SS S!SSU	S   R                  5       S"S.5        [        S# U 5       5      n
[        U
5      S$:  aC  UR                  S%S&S'[        U
5       S(3S)S*U(       a  US+   S   R                  5       OS,S-S.5        1 S.knU
R                  U5      (       a6  UR                  S/S0S1S2S*U(       a  US+   S   R                  5       OS,S3S.5        UR                  S5      (       a  [        R                  " 5       US   -
  R                  nUS4:  a4  UR                  S5S6S7S8S9US   [        S4S:9-   R                  5       SS.5        US;:  a4  UR                  S<S=S>S8S9US   [        S;S:9-   R                  5       S-S.5        US?:  a4  UR                  S@SASBS8S9US   [        S?S:9-   R                  5       SS.5        U(       Ga  [        5       nU H%  nUR!                  US   R#                  5       5        M'     [%        U5      nS
nS
n['        [        U5      5       H>  nUS
:X  a  SnM  UU   UUS-
     -
  R                  S:X  a  US-  nM0  [)        UU5      nSnM@     [)        UU5      nUSC:  a-  UR                  SDSESFSGSHUS+   S   R                  5       S-S.5        US4:  a-  UR                  SISJSKSGSHUS+   S   R                  5       SS.5        / n[        U5      nUS:  a  UR                  SLUSSSMUS-  S-  SN.5        OIUS:  a  UR                  SLUSSSOUS-  S-  SN.5        O$US:  a  UR                  SLUSS SPUS-  S-  SN.5        [        U
5      SQ:  a0  UR                  SR[        U
5      SQS0SS[        U
5      SQ-  S-  SN.5        [        U5      n0 n0 nU H=  nUST   nUU;  a  S
UU'   UU==   S-  ss'   USU   nUU;  a  S
UU'   UU==   S-  ss'   M?     SVnUU-  S-  nU[+        US5      UUUUUSW.U R-                  U5      U(       a  US
   OS,U(       a  US
   OS,SX.SY.nSZUS[.$ ! [.         a0  n[0        R3                  S\[5        U5       35        SS]S	.s S,nA$ S,nAff = f)^z<Get user achievements and milestones based on their activityrc   rh   r4   r8   r   rj   r8   r4   r  Fr   r0   r   rv  zFirst StepszGenerated your first test casez	star-fill	milestonecommon)r=   r  r  r  r)  unlocked_atrarityr  	   ten_test_caseszGetting StartedzGenerated 10 test casesrk  1   fifty_test_caseszTest Case MasterzGenerated 50 test casesrarer  c   hundred_test_caseszTest Case ExpertzGenerated 100 test casesepicc              3   Z   #    U  H!  oR                  S 5      (       d  M  US    v   M#     g7fr  rZ   rI  rv  s     r*   rK  DMongoHandler.get_user_achievements_and_milestones.<locals>.<genexpr>  s"     _:RP]I^0r-0:   ++r  multiple_sourceszVersatile TesterzUsed z different source typesr   versatilityr   Nuncommon>   urljiratextazureimageall_sourceszSource MasterzUsed all available source typesaward	legendaryr_  monthly_userzMonthly Userz$Been using the platform for 30+ dayszcalendar-checkloyaltyrA  r5  quarterly_userzQuarterly Userz$Been using the platform for 90+ daysr  yearly_userzYearly Userz%Been using the platform for 365+ daysrj  weekly_streakzWeekly Warriorz"Maintained a 7-day activity streakfireconsistencymonthly_streakzMonthly Masterz#Maintained a 30-day activity streakr   zGenerate 10 test cases)r  currenttargetr  r  progresszGenerate 50 test caseszGenerate 100 test casesrx  rM  zUse all 5 source typesr)  r     )by_category	by_raritytotal_possible)r  next_achievementrecent_achievement)total_achievementscompletion_percentageachievementsnext_milestonesr   r]  T)r1   achievements_dataz!Error getting user achievements: zFailed to retrieve achievements)rl   r   rm   r   r   r@   r   r   rn   r  
issupersetrZ   r   rH   rB  r   addrE  r  r  r  rq  _get_achievement_levelr'   r   r%   r&   )r(   rc   r   r>   r  
milestonesrv  tenth_test_casefiftieth_test_casehundredth_test_caserM  all_source_typesdays_since_registrationactivity_datesrv  sorted_datesr  r  r   r  current_countr  achievement_categoriesrarity_countsachievementr)  r  total_possible_achievementsr  r  r)   s                                  r*   $get_user_achievements_and_milestones1MongoHandler.get_user_achievements_and_milestones  s   I	Tdoo22G$1J d<#%J ((115'2BE D
 #(5EFF LJ :!#",Q-##+*#C' +#2<#@#J#J#L&%  :"$",Q-##*.#<' +#2<#@#J#J#L&%  :"$%/^"##,/#<' +#5l#C#M#M#O$%  :#%&0n###./#=' +#6|#D#N#N#P$%  _:__L< A%##,/%*3|+<*==T#U( -OY:b>,#?#I#I#K_c(%   I&&'788##',#D# -OY:b>,#?#I#I#K_c)%  xx%%+3??+<tL?Q+Q*W*W'*b0 '',!/'M 0$-(,\(:YB=O(O'Z'Z'\"*)  +b0 ''.!1'M 0$-(,\(:YB=O(O'Z'Z'\",)  +c1 ''+!.'N 0$-(,\(:YC=P(P'['[']"()  !$$B"&&r,'7'<'<'>? %  &n5
!"s<01AAv)*&q/L1,==CCqH&!+%(^%D
)* 2 !^<
? ''-!1'K &$1'1"~l'C'M'M'O",)  # ''.!1'L &$1'1"~l'C'M'M'O"()  !O  
OMr!&&(, .#;!.!3s :(  #&&(, /#;!.!3s :(  $&&(,!/#<!.!4 ;(  < 1$&&*"<0,#;!$\!2Q!6# =(  "%\!2%'"M+&z2#9978*84&x0A50 %X..,-M&)f%*%  , +-'%7:U%UY\$\! '9)./Da)H ,#2#9!.&A "889NO>M(:SW=I,q/t!"  $:KLL 	TLL<SVHEF$1RSS	Ts%   A(U5 +T	U5 5
V/?%V*$V/*V/c                 J    US:  a  gUS:  a  gUS:  a  gUS:  a  gUS	:  a  g
g)z4Get achievement level based on completion percentager5  	Legendaryre  Masterrk  Expert   Intermediater  BeginnerNovicerH  )r(   r  s     r*   r  #MongoHandler._get_achievement_level  s<     B&"b("b("b(!"b(r  c                     U R                  U5      (       d  SSS.$ SSKJnJn  UR                  " 5       nUS:X  a	  XT" SS9-
  nODUS	:X  a	  XT" S
S9-
  nO5US:X  a	  XT" SS9-
  nO&US:X  a	  XT" SS9-
  nOUS:X  a	  XT" SS9-
  nOXT" SS9-
  n[	        U R
                  R                  SSSU000SSSS0SS0SSSSS/0SS/00SS0SS 0S!S 0S".0S#S$S%00/5      5      n/ n[        U5      n	U GH  n
U R                  R                  S&U
S&   0SSSSS'.5      nU(       d  M3  U
S$   nU
R                  S(S5      nU
R                  S)S5      S*-  n[        U
S+   5      nSnUR                  S5      (       a  X[S   -
  R                  nSnUS:  a  US:  a  [        X-  S*-  S*5      nUR                  [        U
S&   5      US,   US-   UR                  S.S/5      U[        US05      [        US05      UU[        US05      S1.S2.5        GM     U(       Ga$  U Vs/ s H  nUS3   S4   PM     nnU Vs/ s H  nUS3   S(   S:  d  M  US3   S(   PM     nnU Vs/ s H  nUS3   S)   PM     nnU Vs/ s H  nUS3   S5   PM     nn[        [!        U5      [        U5      -  S05      [#        U5      [        U5      S0-     [#        U5      [%        [        U5      S6-  5         [#        U5      [%        [        U5      S7-  5         S8.U(       a!  [        [!        U5      [        U5      -  S05      OSU(       a  [#        U5      [        U5      S0-     OSU(       a  [        U5      OSS9.[        [!        U5      [        U5      -  S05      [#        U5      [        U5      S0-     [#        U5      [%        [        U5      S6-  5         S:.[        [!        U5      [        U5      -  S05      [#        U5      [        U5      S0-     [#        U5      [%        [        U5      S6-  5         S:.S;.nU H  n[        U Vs/ s H  nUS3   S4   US3   S4   :  d  M  UPM     sn5      S-   nU[        U	U-
  S-   U	-  S*-  S5      S<.US='   [        U Vs/ s H  nUS3   S5   US3   S5   :  d  M  UPM     sn5      S-   nUUS=   S>'   [        U	U-
  S-   U	-  S*-  S5      US=   S?'   US=   S@   SA-  US=   S?   SB-  -   US3   S)   SB-  -   n[        US5      US=   SC'   M     UR'                  SD SESF9  [)        U5       H  u  nnUS-   US=   SG'   M     O0 n/ nU(       a  USHSI nUR                  SJSKR+                  U Vs/ s H  nUS,   PM
     sn5       35        [        U5      S:  a:  US   S=   SC   nUS%   S=   SC   n UU -
  n!UR                  SL[        U!S5       SM35        U(       a9  USN   SO   n"UR                  SPU" 35        USN   SQ   n#UR                  SRU# SS35        / n$U(       a  U Vs/ s H  nUS=   SC   ST:  d  M  UPM     n%nU%(       a  U$R                  SU[        U%5       SV35        U Vs/ s H  nUS=   SC   SW:  d  M  UPM     n&nU&(       a  U$R                  SX[        U&5       SY35        U(       a>  US)   SO   n'U'SW:  a  U$R                  SZ5        US>   SO   n(U(ST:  a  U$R                  S[5        UUR-                  5       UR-                  5       U	UUUU$U(       a  US   OSHU(       a"  UR                  SN0 5      R                  SOS5      OS[        U Vs/ s H  nUS=   SC   SW:  d  M  UPM     sn5      [        U Vs/ s H  nS\US=   SC   s=::  a  SW:  d  M  O  M  UPM      sn5      [        U Vs/ s H  nS]US=   SC   s=::  a  S\:  d  M  O  M  UPM      sn5      [        U Vs/ s H  nUS=   SC   S]:  d  M  UPM     sn5      S^.S_.S`.	n)SEU)Sa.$ s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf ! [.         a0  n*[0        R3                  Sb[        U*5       35        SScS.s SHn*A*$ SHn*A*ff = f)dz6Get user comparison and benchmarking data (admin only)Frg   r0   r   r
   r   rh   rA  r  rj  r	  r_  r  r5  r
  r  r  r8   r   r`  ra  rb  r  r  r  r  r  r  rF  rq  rd  rd  rc  )r4   r  r  r  rM  r  rf  rp  r  r   r4   r  r  r  r  rM  r6   r.   r7   r>   r  )re  r  r  source_type_diversityrB  efficiency_score)rc   r6   r.   r7   metricsr  re  r  g      ?g?)r  mediantop_25_percentiletop_10_percentile)r  r  fastest)r  r  r   )r   completion_timer  
efficiency)re  test_case_percentilerankingsr  efficiency_percentiler  r  r  overall_scorec                     U S   S   $ )Nr  r  rH  r  s    r*   r  CMongoHandler.get_user_comparison_and_benchmarking.<locals>.<lambda>\  s    1Z=3Qr  Tr  positionNr  zTop 3 performers: z, z.Performance gap between top and bottom users: z pointsr   r  rM  r   zTop 25% threshold: z test casesrk  zProvide additional support for z low-performing usersr4  zRecognize and reward z high-performing usersz4Implement training programs to improve success ratesz.Provide efficiency training and best practicesr{  rW  )r  r  r  r  )top_performeraverage_performanceperformance_distribution)	r  r   r!  r  user_benchmarks
benchmarksrN  r3  r]  )r1   comparison_dataz0Error getting user comparison and benchmarking: z"Failed to retrieve comparison data)rd   r   r   rH   rl   r   rw  r   r   r@   rZ   rB  r  r   r&   rq  r  r  r  r   r  joinrn   r'   r   r%   )+r(   ro   r  r   r   rT  r   user_performance_datar  r   	user_perfr  re  r  r  r  rB  r  r  test_case_countscompletion_timessuccess_ratesefficiency_scoresr  r>   test_case_rankingefficiency_rankingr  r   rN  r  	top_scorebottom_scoreperformance_gaprH  top_25_thresholdr3  rR  high_performersr  avg_efficiencyr  r)   s+                                              r*   $get_user_comparison_and_benchmarking1MongoHandler.get_user_comparison_and_benchmarking  sr
   [	W==//#(5`aa 5//#Ce# 9!#44
& 9!#44
' 9"#55
	) 9"#55
& 9##66
 9"#55
 %))B)BL6:*>?@%)/,24F+GEI{3K+LaQR*S T% &1.$A'-}&=&,m%<
 
 -r23D * %!" !O34K2	#44==uiPUFV>W"#	Z    <&/0B&CO*3--8Mq*Q'#,==#Cc#IL,/	.0I,J) %&M#''55),L/I)I(O(O ()$&*/BQ/F+.0UY\/\^a+b(#**#&y'7#8 ,V 4!-g!6 , 0 0 @/>389La3P,1,,B5J-:056F0J$, 5 3T M\#]_AiL1B$C_ #]Q`  $MQ`Adefodp  rG  eH  KL  eL$GAiL1F$GQ`   $MGV W!9n!= WO^$_!Qy\2D%E!$_ $)-=)>EUAV)VXY#Z"()9":3?O;PTU;U"V-34D-Ec#N^J_bfJfFg-h-34D-Ec#N^J_beJeFf-g	# _o5-=)>EUAV)VXY#ZtuZj&)9":3?O;PTU;U"Vpq<L3'7#8RS( $)]);c->P)PRS#T"("7M8Ja8O"P-3M-B3s=GY\`G`Ca-b% $)->)?#FWBX)XZ[#\"():";C@Q<RVW<W"X-34E-Fs3O`KadhKhGi-j##
2 ,D(+  -Q11Y<XiKjmqr{m|  ~O  nP  LPQ  -Q  )R  UV  )V%+<05{EV7VYZ7Z^i6ilo6oqr0s(D$ *-  .TAAiLYkLlost}o~  @R  pS  MSa  .T  *U  XY  *Y&5GD$\2@E{UgGgjkGkozFz  ~A  GA  CD  AED$%<= Z()?@3FZ()@ACGHY7#=> "
 9>mQ8OD$_5' ,,  $$)Q[_$`  )9GAt34q5D$Z0  :  
 H!0!!4"4TYYSa?bSaa&	Sa?b5c4d ef '!+ / 2: > OI#22#6z#B?#SL&/,&>OOO&TUZ[jlmUnToov$wx %/%=i%HNOO&CNCS$TU'1,'?@S'T$OO&9:J9K;$WX !O-<!d_*o@^ac@c!_!d!#**-LSQ_M`Laav+wx />"fo:A_ceAe1o"f"#**-B3CWBXXn+op '1.'A)'L$'",'../ef%/%=i%HN%*'../_`  +(224MMO(3#2($#2;J_Q%7PTak:>>,+K+O+OPY[\+]qr%(_)m_*VeHfjlHl!_)m%n #$m12:WfIgCljlClQClQ$m n#&?'p?abAjMZiLjFomoFoFo?'p#q),-pAAjMZiLjmoLoa-p)q	1	O*  $HHA $^ $M W$_: -Q .T6 @c, "e
 #g6 *n$m'p-p  	WLLKCPQF8TU$1UVV	Ws  `6 C:`6 C1`6 _5`6 $_:8_:`6 
_?`6 "`4F,`6  `	
:`	
 1`6 1`
`
C`6 `&B#`6 	``#+`6 `"`(C`6 8`"`"`6 !`'<`' `'`6 `, 0`, 4`, :`6 	`1"`1"#`6 5A`6 6
a0 %a+%a0+a0c                     [        U R                  R                  SU0SSSSS.5      R                  SS5      5      nU(       d  SSS0S.$ [	        S	 U 5       5      n[        U5      n/ nUS:  a  UR                  S
5        US:  a  UR                  S5        US:  a  UR                  S5        US:  a  UR                  S5        US:  a  UR                  S5        [        U Vs/ s H  ofR                  S5      S:X  d  M  UPM     sn5      [        U Vs/ s H  ofR                  S5      S:X  d  M  UPM     sn5      [        U Vs/ s H  ofR                  S5      S:X  d  M  UPM     sn5      [        U Vs/ s H  ofR                  S5      S:X  d  M  UPM     sn5      [        U Vs/ s H  ofR                  S5      S:X  d  M  UPM     sn5      S.nUR                  5        VV	s/ s H  u  pU	S:  d  M  UPM     n
nn	UR                  5        VV	s/ s H  u  pU	S:  d  M  UPM     nnn	U(       a  US   OSUUU
UU(       a5  U Vs/ s H'  nSUR                  SS5      R                  5        S 3PM)     snOS!/S".nSUS.$ s  snf s  snf s  snf s  snf s  snf s  sn	nf s  sn	nf s  snf ! [         a0  n[        R                  S#[        U5       35        S$S%S&.s S'nA$ S'nAff = f)(z*Get user learning and development insightsrc   rh   r  r8   Tr2   z No test cases found for analysis)r1   learning_insightsc              3   Z   #    U  H!  oR                  S 5      (       d  M  US    v   M#     g7fr  r  r  s     r*   rK  :MongoHandler.get_user_learning_insights.<locals>.<genexpr>  s"     #d
"ffUbNc$5B}$5
r  z$Beginner - First test case generatedrx  z%Novice - Basic understanding achievedr  zIntermediate - Consistent usager_  zAdvanced - Proficient userrk  zExpert - Master levelr   r  r  r  r  r  )url_testingimage_testingjira_integrationazure_integrationtext_analysisr  r   zNew Userz	Focus on r  r  z to improve skillsz)Continue exploring different source types)current_stagelearning_progressionskill_development	strengthsimprovement_areasr3  z!Error getting learning insights: Fz$Failed to retrieve learning insightsr0   N)rl   r   rm   r   r  r   r   rZ   r   r   r  r'   r   r%   r&   )r(   rc   r   rA  r  learning_stagesrv  skill_areasarear   r/  r0  r$  r)   s                 r*   get_user_learning_insights'MongoHandler.get_user_learning_insights  s   7	Ydoo22G$1J d<#%J
 #'yJl>mnn !$#d
#d d": !O1$&&'MN1$&&'NO2%&&'HI2%&&'CD2%&&'>?  ##^2vvm?TX]?]B#^_!$:%b:RAVZaAab:%b!c$'j(djFF=DY]cDcj(d$e%(z)fzVVMEZ^eEe"z)f%g!$:%a:RAVZ`A`b:%a!bK 2=1B1B1DS1D+$QR
1DIS9D9J9J9L Z9L+$PUXYPY9L Z 9H!4Z(7%0&%6 ' `q$_pW[iS# 6 < < >??QR_p$-X,Y	!  $:KLL- $_%b(d)f%a T Z$  	YLL<SVHEF$1WXX	Ys   A	J/ BJ/ 'JJ	J/ J

4J

:J/ 	J%J+J/ :JJJ/ +JJJ/ )J9J?J/ J$%J$+J/ 
.J*8J/ *J/ /
K)9%K$K)$K)c                 <    U[         R                  " 5       [        SS9-   [         R                  " 5       S.n[        R                  " SS5      n[
        R                  " X#SS9nU$ ! [         a+  n[        R                  S[        U5       35         S	nAg	S	nAff = f)
zGenerate JWT token for userr_  rA  )rc   expiatJWT_SECRET_KEY$your-secret-key-change-in-productionHS256)	algorithmzError generating JWT token: N)r   rH   r   osgetenvjwtrE   r'   r   r%   r&   )r(   rc   payload
secret_keyrY   r)   s         r*   r]   MongoHandler.generate_jwt_token  s    	"(9"+==(G #35[\JJJwgFEL 	LL7Ax@A	s   A#A& &
B0!BBc                 6    [         R                  " SS5      n[        R                  " XS/S9nUR	                  S5      nU(       a^  U R
                  R                  SU05      nU(       a:  UR	                  SS5      (       a#  SUS   US	   US
   UR	                  SS5      S.S.$ SSS.$ ! [        R                   a    SSS.s $ [        R                   a    SSS.s $ [         a0  n[        R                  S[        U5       35        SSS.s SnA$ SnAff = f)z%Verify JWT token and return user infor9  r:  r;  )
algorithmsrc   r4   r:   Tr.   r6   r7   r>   r<   r   FzInvalid or expired tokenr0   zToken expiredzInvalid tokenzError verifying JWT token: zToken verification failedN)r=  r>  r?  decoderZ   r   r@   ExpiredSignatureErrorInvalidTokenErrorr'   r   r%   r&   )r(   rY   rA  r@  rc   r>   r)   s          r*   verify_jwt_tokenMongoHandler.verify_jwt_token  s   	N#35[\JjjyIGkk),G,,55ug6FGDHH[$77#'"&u+%)']$(L$(HHVV$<	!   %1KLL(( 	B$AA$$ 	B$AA 	NLL6s1vh?@$1LMM	Ns0   B"B* %B* *DD	D(%DDDc                     [        U R                  R                  SU0SSSSSS.5      R                  SS5      R	                  U5      5      nU$ ! [
         a-  n[        R                  S[        U5       35        / s SnA$ SnAff = f)z&Get all test cases for a specific userrc   rh   )r4   	test_datar8   r   item_idr8   r   zError getting user test cases: N)	rl   r   rm   r   r   r'   r   r%   r&   )r(   rc   r   r   r)   s        r*   get_user_test_cases MongoHandler.get_user_test_cases  s    		doo22G$1YZ[ d<$UU5\3J
  	LL:3q6(CDI	s   AA 
B"B<BBc           	      n    [        [        R                  " 5       5      nUU[        R                  " 5       UUU0 US.nU R
                  R                  U5        [        R                  SU SU SU 35        U$ ! [         a1  n[        R                  S[        U5       35        [        S5      eSnAff = f)zJSave test case data and generate unique URL with optional user association)r4   rK  r8   url_keyrL  r   rj   rc   z&Successfully saved test case with ID: z, source_type: z, user_id: zError saving test case: z$Failed to save test case to databaseNr&   rF   rG   r   rH   r   rI   r   r    r'   r%   )r(   rK  rL  r   rc   	unique_iddocumentr)   s           r*   save_test_caseMongoHandler.save_test_case$  s    	DDJJL)I &&oo/$"*"	H OO&&x0KK@?[fZggrszr{|} 	DLL3CF8<=BCC	Ds   A6A9 9
B4,B//B4c                 <    U R                   R                  SU0SSU005      nUR                  S:  a  [        R	                  SU 35        g[        R                  SU 35        g! [         a+  n[        R                  S	[        U5       35         S
nAgS
nAff = f)z5Update the status dictionary for a test case documentrP  rX   rj   r   z%Successfully updated status dict for Tz'No document found to update status for FzError updating status dict: N)	r   r\   rx   r   r    rN  r'   r%   r&   )r(   rP  status_valuesrT   r)   s        r*   update_status_dictMongoHandler.update_status_dict9  s    	__//G$(M23F $$q(CG9MN!H	RS 	LL7Ax@A	s   A
A& A& &
B0!BBc           
          UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      [        R                  " 5       UR                  S5      UR                  S5      S.nU R                  R	                  U5        [
        R                  S	UR                  S5       35        g
! [         a+  n[
        R                  S[        U5       35         SnAgSnAff = f)z"Track user session and page visitsr  r  r  referrerpage_visitedcountrycity)r  r  r  r[  r\  rR  r]  r^  zTracked user session: TzError tracking user session: NF)
rZ   r   rH   r   rI   r   r    r'   r%   r&   )r(   session_datasession_docr)   s       r*   track_user_sessionMongoHandler.track_user_sessionJ  s    	*..|<*..|<*..|<(,,Z8 , 0 0 @%__.'++I6$((0	K ))44[AKK01A1A,1O0PQR 	LL8QAB	s   C	C 
D!C<<Dc                     UR                  S5      UR                  S0 5      UR                  S5      UR                  S5      UR                  S5      [        R                  " 5       UR                  S5      UR                  S/ 5      UR                  SS	5      S
.	nUR                  S5      (       a  UR                  S5      US'   UR                  S5      (       a  UR                  S5      US'   U R                  R	                  U5        [
        R                  SUR                  S5       35        g! [         a+  n[
        R                  S[        U5       35         SnAgSnAff = f)z"Track user events and interactionsr~  
event_datar  r  r  r   test_case_types
item_countr   )	r~  rd  r  r  r  rR  r   re  rf  rc   	user_rolezTracked event: TzError tracking event: NF)
rZ   r   rH   r   rI   r   r    r'   r%   r&   )r(   rd  	event_docr)   s       r*   track_eventMongoHandler.track_event^  s$   	(nn\:(nn\2>(nn\:(nn\:(nn\:%__.)~~m<#->>2CR#H(nn\1=
I ~~i(('1~~i'@	)$~~k**)3)D	+&%%00;KK/*..*F)GHI 	LL1#a&:;	s   D0D3 3
E(=!E##E(c                 @    U(       aF  U(       a?  [         R                  " US5      n[         R                  " US5      [        SS9-   nSXgS.0nO%[         R                  " 5       [        US9-
  n	SSU	00n0 UEn
U(       a  XJS'   U(       a  XZS'   XXS'   U R                  R                  U5      nU R                  R                  U
5      n0 U
ES	S
0EnU R                  R                  U5      n0 U
ES	S0EnU R                  R                  U5      nS0 U
ES	S0E0SSSSSSS/0SSS/0/0SSS.000SSSSSS.00SSSS0S.0SSS00/n[        U R                  R                  U5      5      nS0 U
ESS/ S .S!.E0S"S#0SS#SS0S.0SSS00/n[        U R                  R                  U5      5      nSU
0SS$S%0S&S%0S'S%0S(.SS0S).0SS*S00/n[        U R                  R                  U5      5      nS0 U
ESS+S0S,.E0SSS-S.0S/S.0S0S.0SS0S1.0/n[        U R                  R                  U5      5      nS0 U
ESS+S0S,.E0SSSSSSS/0SSS/0/0SSS.000SSSSSS.00SSS-S.0SS0S2.0SS3S00/n[        U R                  R                  U5      5      nS0 U
ESS+S0SS4S .S5.E0SS6SS7S8S9/0S:SS7S8S;/0S<SS7S8S=/0S>S?S.0S.0S.00S-S.0S-S@0SS0SA.0SSBS00/n[        U R                  R                  U5      5      nU(       a3  S4UUU[        US4:  a  UU-  SC-  OS4SC5      UUUU(       a  US4   OSUUUSD.$ UUUU[        US4:  a  UU-  SC-  OS4SC5      UUUU(       a  US4   OSUUUSD.$ ! [         a+  n[        R                  SE[        U5       35         SnAgSnAff = f)FzZGet analytics summary for the specified date range or number of days with optional filtersrC  rh   rA  rR  r  r   r   rc   r~  generate_button_clickr  r  z
$addFieldseffective_source_typer  z$andr~  rq  Nr  z$event_data.source_type)ifthenelseT)r}  r~  r~  r`  z$effective_source_typerb  rr  rp  r   r   r|  )r~  re  rk  z$test_case_typesz$yearz
$timestampz$monthz$dayOfMonth)r
  r	  r   )r4   eventsr4   r}  )r~  &event_data.generation_duration_secondsr  z'$event_data.generation_duration_secondsrd  rc  )r4   avg_generation_timemin_generation_timemax_generation_timetotal_generations)r4   rs  r   rs  r   )r~  rr  rf  
item_range$ltez$item_countrx  z	1-5 itemsr  z
6-10 itemsrl  z11-20 itemsz	20+ itemsz!$event_data.average_time_per_item)r4   rs  avg_time_per_itemr   z_id.item_ranger  )total_sessionsr  generate_clickssuccessful_generationsr  rm  test_case_type_distributionr5  generation_timingtiming_by_sourcetiming_by_itemsperiod_daysz!Error getting analytics summary: )r   strptimer   rH   r   r   r   rl   rw  r  r'   r   r%   r&   )r(   r   r!  rB  r   rc   start_datetimeend_datetimedate_filtercutoff_datebase_filterrz  r  generate_filterr{  success_filterr|  source_type_pipelinesource_type_statstest_case_type_pipelinetest_case_type_statsdaily_activity_pipeliner5  timing_pipelinetiming_statstiming_by_source_pipeliner  timing_by_items_pipeliner  r)   s                                 r*   get_analytics_summary"MongoHandler.get_analytics_summaryz  s   H	h!)!2!2:z!J'00:FXYIZZ*^,YZ 'oo/)2FF*V[,AB *[/K-8M* )0I&)0I& "::JJ;WN  44DD[QL UTl<STO"77GGXO RQ\;PQN%)%>%>%N%N~%^" OkO<9NOP+#)!&(> ?!&(< =, # %3$="	.   3d[]5^_`#;vqkRS7B-(!$ $ !%T%>%>%H%HI]%^ _   Ak  A9Nos|~c  A  B./#5LM7B-(	'# $((A(A(K(KLc(d#e  ;'!(, 7"*L!9 -|<
  &qk  5!*%'# "$";";"E"EF]"^_N  !"7?H$>O 
 ,24]+^,24]+^,24]+^*0! O   9 9 C CO TUL  !"7?H$>O 
 +#)!&(> ?!&(< =, # %3$="	.   3d[]5^_`3,24]+^$a[ 
 0"561)%4  $D$=$=$G$GHa$bc  !"7?H$>O.21"=	  $#'-q/A&B(3$+/5r7J.K0<,37=r?R6S8E8C6.1*
.&)"&'* -34]+^*02U)V$a[1 4 +Q/0C"($F #4#<#<#F#FG_#`aO  '($0'6.D$'\kno\o)?/)QTW)Wuvx{$|0A3G&4<Had(8'6#' " '5$0'6.D$'\kno\o)?/)QTW)Wuvx{$|0A3G&4<Had(8'6#'   	LL<SVHEF	s   L2M( 52M( (
N2!NNc                 2    0 nU(       a  UR                  S5      (       a
  SUS   0US'   UR                  S5      (       a  SU;   a  US   US   S'   O
SUS   0US'   UR                  S5      (       a  US   US'   UR                  S5      (       a  US   US'   [        U R                  R                  USS	05      R	                  SS
5      R                  S5      5      nU$ ! [         a+  n[        R                  S[        U5       35         SnAgSnAff = f)z,Get detailed analytics with optional filtersr   r   rR  r!  rx  r~  r   r4   r   r   i  z"Error getting detailed analytics: N)
rZ   rl   r   rm   r   r   r'   r   r%   r&   )r(   filtersmatch_criteriarq  r)   s        r*   get_detailed_analytics#MongoHandler.get_detailed_analyticsF  s   	N;;|,,397<;P2QN;/;;z**"n4>Ej>Q{3F;7=wz?R6S{3;;|,,3:<3HN<0;;}--4;M4JN=1 $3388
 d;#EE$K1F
 M 	LL=c!fXFG	s   CC! !
D+!DDc           	          U R                   R                  SU05      nU(       d  [        R                  SU 35        g[        R	                  SU SU 35        [        R	                  S[        UR                  5       5       35        SU;   a  [        R	                  S[        US   5       35        [        US   [        5      (       a3  [        R	                  S	[        US   R                  5       5       35        O<[        US   [
        5      (       a$  [        R	                  S
[        US   5       35        SnU(       ah  SU;  ab  SU;  a\  [        R                  " 5       nU R                   R                  SU0SSU 3USU 3U005        Sn[        R	                  SU SU 35        SnSU;   a2  [        US   [
        5      (       a  Sn[        R	                  SU 35        SnSU;   aV  [        US   [        5      (       a>  SUS   ;   a5  [        US   S   [
        5      (       a  Sn[        R	                  SU 35        U(       a  [        R	                  SU SU 35        [        R                  " 5       nU R                   R                  SU0SSU 3USU 3U005      n	U	R                  S:  a  [        R	                  SU 35        g[        R                  SU 35        gU(       a  US   n
Sn[!        U
5       H  u  pUR#                  SS5      nX:X  d  M  [        R	                  SU 35        U R                   R                  SU0SSU S3U005      n	U(       d?  [        R                  " 5       nU R                   R                  SU0SSU 3USU 3U005        Sn  O   U(       d  [        R                  SU S U 35        ggSU;   GaJ  S!US   ;   Ga@  US   S!   n
S nS"U;   aK  UR%                  S"5      n[        U5      S#:  a+  US    S"US$    S"US%    3n[        R	                  S&U 35        [!        U
5       GH  u  pUR#                  SUR#                  S'S5      5      nUR#                  S(UR#                  S)S5      5      nU(       d  U(       a  UR%                  S*5      nU HW  nUR'                  5       R)                  S+5      (       d  M)  UR'                  5       R+                  S+S5      R'                  5       n  O   U(       dy  UR%                  S*5      nU Hb  nUR'                  5       nU(       d  M  UR)                  S,5      (       d.  UR)                  S-5      (       d  UR)                  S.5      (       d  M`  Un  O   U(       a  X.;   a  [        R	                  S/U 35        U R                   R                  SU0SS0U S13U005      n	U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  a  [        R	                  S2U 35          gU(       a  S3U;   a  UR%                  S35      S   R'                  5       nUU:X  a  [        R	                  S4U 35        U R                   R                  SU0SS0U S13U005      n	U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  a  [        R	                  S5U 35          gU(       a  UU;   a  [        R	                  S6U 35        U R                   R                  SU0SS0U S13U005      n	U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  a  [        R	                  S7U 35          gU(       a  U(       a  UR)                  US"-   5      (       d  UR)                  US8-   5      (       d  X:X  a  [        R	                  S9U S:U 35        U R                   R                  SU0SS0U S13U005      n	U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  a  [        R	                  S;U 35          gU(       d  GM6  UU;   d  GM?  [        R	                  S<5        U R                   R                  SU0SS0U S13U005      n	U(       a,  U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  d  GM  [        R	                  S7U 35          g   [!        U
5       H  u  pUR#                  S=5      U:X  d  UR#                  S>5      U:X  d  M1  [        R	                  S?U 35        UR#                  SUR#                  S'S5      5      nU R                   R                  SU0SS0U S13U005      n	U(       a,  U(       d%  U R                   R                  SU0SSU 3U005        U	R                  S:  s  $    [        R                  S@U SU 35        g[        R                  SAU SB35        g! [,         a+  n[        R                  SC[/        U5       35         S nAgS nAff = f)DNrP  z No document found with url_key: Fz/Updating status for test case with identifier 'z' in document zDocument structure: rK  ztest_data type: ztest_data keys: ztest_data list length: .r*  rX   zstatus.zstatus_timestamps.Tz-Updated central status dictionary for title: z with timestamp: z Shared view update detected for z"URL structure update detected for z#Updating status for URL structure: z = r   z/Successfully updated status for URL structure: z+Failed to update status for URL structure: Titler  z"Found shared view match by title: z
test_data.z.StatuszNo test case found with title 'z' in shared view document r   r  r  rh   r  zExtracted UI identifier: r  Contentcontent
zTitle:TC_TC_FUNC_TC_UI_zFound match in title: ztest_data.test_cases.z.statusz/Successfully updated status by title match for (zFound match by base title: z4Successfully updated status by base title match for z)Found match in content for test case ID: z1Successfully updated status by content match for r  zFound match for UI identifier z in title: z7Successfully updated status by UI identifier match for zFound match in contentr  zTest Case IDzFound direct ID match at index zNo test case found matching 'z	Document z has no test casesz!Error updating test case status: )r   r@   r   r%   r    rl   r   r  r   r  r   r   rH   r\   rx   rN  r  rZ   splitstriprt  r   r'   r&   )r(   rP  r  rj   doctitle_foundcurrent_timeis_shared_viewis_url_structurerT   r   foundidxrv  r  ui_identifierpartsr  linesline
base_titler)   s                         r*   update_test_case_status$MongoHandler.update_test_case_statusb  s
   \	//**Iw+?@C?yIJ KKI,Wefmenop KK.tCHHJ/?.@ABc!.tC4D/E.FGHc+.55KK"24K8H8M8M8O3P2Q RSK 0$77KK"9#c+>N:O9P QR  K < 7C|<S  (0**(%l^4f0?! #KL>Yjkwjxyz #Nc!j[1A4&H&H!%>wiHI  %c!j[1A4&H&H[\_`k\lMlq{|  AL  }M  NY  }Z  \`  ra  ra#' @	JK A,sSYRZ[\  (033(%l^4f0?! ((1,KK"QR^Q_ `aNN%PQ]P^#_`  -
 (4GCFF7B/E ,&H$PQ!%!;!;&0#
3%w&?%HI"  ++3??+<L OO66!*G 4$**1%(96*<UG(Dl-&!" !%3  56 NN%D\NRlmtlu#vw #K8H(H -l;
 !%,&(..s3E5zQ+08*AeAhZqq
(K&?$OP  )4GCFF7BFF7B,?@E ffYy"0EFG !W 'd 3$)D#zz|66x@@(,

(<(<Xr(J(P(P(R % %*  %$+MM$$7E(-'+zz|#'4T__U-C-CtWaGbGbfjfufuv~ff,0E$)	 ). !6&<UG$DE!%!;!;&0#(=cU'&JF%ST"  + OO66!*G 4!'GE7*;V)D E
 "0014"KK*YZfYg(hi#'
 !4%1%7%7%<Q%?%E%E%G
 J."KK*Ej\(RS%)__%?%?!*G 4!',A#g*NPV)W X&F $/ $ : :%.$8%+~.F-O$P!"
  &44q8 &.bcobp,q r'+ <7#:&OP\~$^_!%!;!;&0#(=cU'&JF%ST"  + OO66!*G 4!'GL>*BF)K L
 "0014"KK*[\h[i(jk#' % ",,]S-@AA!,,]S-@AA!2"KK*HWbchbi(jk%)__%?%?!*G 4!',A#g*NPV)W X&F $/ $ : :%.$8%+~.F-O$P!"
  &44q8 &.efset,u v'+ w<7#:&<>!%!;!;&0#(=cU'&JF%ST" ! OO66!*G 4!'GE7*;V)D E
 "0014"KK*[\h[i(jk#'{  5@  )4GCvvn-=AW[gAg&EcU$KL "ww0C D!%!;!;&0#(=cU'&JF%ST" ! OO66!*G 4!'GE7*;V)D E
  &44q88#  5( !>|nN[bZcde7)3EFG 	LL<SVHEF	s   <h6 Jh6 h6 &3h6 B,h6 Dh6 A$h6 >A h6 B%h6 (Ch6 1B h6 Ch6 .h6 8h6 A<h6 h6 :h6 B#h6 >h6 h6 6
i+ !i&&i+c                 x    U R                   R                  SU05      nU(       dV  U R                   R                  SU05      nU(       a  [        R                  SU 35        U$ [        R	                  SU 35        U$ ! [
         a1  n[        R                  S[        U5       35        [        S5      eSnAff = f)z"Retrieve test case data by URL keyrP  r4   Found document by _id: 'No test case found for URL key or _id: zError retrieving test case: z*Failed to retrieve test case from databaseN)r   r@   r   r    rN  r'   r%   r&   )r(   rP  rT   r)   s       r*   get_test_caseMongoHandler.get_test_case  s    	J__--y'.BCF115'2BCKK"9' CD M NN%LWI#VWM 	JLL7Ax@AHII	Js   A!A> $A> >
B9,B44B9c                     U R                   R                  SU05      nU(       dV  U R                   R                  SU05      nU(       a  [        R                  SU 35        O[        R	                  SU 35        gSU;   a  [        R                  SUS    35        O[        R                  S5        S	U;   a  [        US	   [        5      (       a  [        US	   5       H  u  pE[        U[        5      (       aN  UR                  S
S5      nUR                  SS5      nU(       a!  [        R                  SU SU SU S35        Mf  Mh  [        R	                  SU S[        U5       35        M     GO	S	U;   Ga  [        US	   [        5      (       Ga  SUS	   ;   Ga  [        US	   S   5       GHz  u  pE[        U[        5      (       an  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       a!  [        R                  SU SU SU S35        M  M  [        U[        5      (       a   SSKJn  U" U5      n	U	(       a  [        U	5       Ht  u  pUR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       d  MR  [        R                  SU SU
 SU SU S3	5        Mv     GM:  [        R	                  SU S35        GMV  [        R	                  SU S[        U5       35        GM}     ONS	U;   aH  [        US	   [        5      (       a0  [        R	                  S[!        US	   5       SUS	   SS  S35        0 $ SU;   a4  US   (       a*  [        R                  S[!        US   5       S 35        US   $ 0 nS	U;   a  [        US	   [        5      (       as  [        R                  S!5        US	    HS  n[        U[        5      (       d  M  S
U;   d  M"  UR                  S
S5      nUR                  SS5      nU(       d  MO  XU'   MU     GOS	U;   GaT  [        US	   [        5      (       Ga;  SUS	   ;   Ga1  [        R                  S"5        US	   S    GH  n[        U[        5      (       aS  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       a  XU'   Mj  Ml  [        U[        5      (       d  M  SSKJn   U" U5      nU(       at  U Hk  n[        U[        5      (       d  M  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       d  Mg  XU'   Mm     GM  GM     GOxS	U;   a  [        US	   [        5      (       a  S	US	   ;   a  [        R                  S$5        [        US	   S	   [        5      (       a  US	   S	    H  n[        U[        5      (       d  M  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       d  Mg  XU'   [        R#                  S%U S&U S'35        M     GOS	U;   a/  [        US	   [        5      (       a  [        R                  S(5        0 $ S	U;   a  [        US	   [        5      (       a  SUS	   ;   a  [        US	   S   [        5      (       a  [        R                  S)5        SSKJn   U" US	   S   5      nU(       a  U H  n[        U[        5      (       d  M  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       d  Mg  XU'   [        R#                  S%U S&U S*35        M     GOUGOSS	U;   GaL  [        US	   [        5      (       Ga3  SUS	   ;   Ga)  [        US	   S   [        5      (       Ga  [        R                  S,5        SSKJn   US	   S    H  n[        U[        5      (       d  M  S-U;   d  M"  US-   nU(       d  M0  [        U[        5      (       d  MG  U" U5      nU(       d  MX  U H  n[        U[        5      (       d  M  UR                  S
UR                  SS5      5      nUR                  SUR                  SS5      5      nU(       d  Mg  XU'   [        R#                  S%U S&U S.35        M     M     U(       aF  [        R                  S0[!        U5       S1U 35        U R                   R%                  SU0S2SU005        [        R                  S3[!        U5       S4U 35        U$ ! [         a'  n[        R                  SU SU 35         SnAGM  SnAff = f! [         a$  n[        R                  S#U 35         SnAGM\  SnAff = f! [         a#  n[        R                  S+U 35         SnAGN SnAff = f! [         a#  n[        R                  S/U 35         SnAGN0SnAff = f! [         a+  n[        R                  S5[        U5       35         SnAgSnAff = f)6zRetrieve all status values for test cases in a document

Args:
    url_key: The unique URL key for the document
    force_refresh: If True, forces a direct database query to get fresh data
rP  r4   r  r  Nrj   zSTATUS DICT in MongoDB: z"NO STATUS DICT in MongoDB documentrK  r  r  StatuszSHARED VIEW TC[z
]: Title='z', Status=''z] is not a dict: r   r  zMAIN VIEW TC[r   )parse_traditional_formatz	] parsed[z%] is a string but could not be parsedzError parsing MAIN VIEW TC[z] string entry: z'test_data is stored as string (length: z):    z...zFound z# status values in status dictionaryz.Building status values from shared view formatz,Building status values from main view formatz3Error parsing string test case entry in main view: z3Building status values from nested test_data formatzFound status 'z' for 'z' in nested test_datazEtest_data is stored as string - no individual status values availablez-Building status values from test_cases stringz' in parsed test_casesz!Error parsing test_cases string: z+Building status values from test_cases listr  z' from list itemzError parsing test_cases list: z%UPDATING status dict in MongoDB with z	 values: rX   z
Returning z status values for z*Error retrieving test case status values: )r   r@   r   r    rN  r   rl   r  r  rZ   r  r&   utils.file_handlerr  r'   r%   r   debugr\   )r(   rP  force_refreshrT   r   rv  r  rj   r  parsedpidxptcptitlepstatusr)   rW  parsed_test_casestest_case_objr  s                      r*   get_test_case_status_values(MongoHandler.get_test_case_status_values  s	   t	
 __--y'.BCF115'2BCKK"9' CDNN%LWI#VW 6!6vh7G6HIJ@A f$F;4G)N)N&vk':;EA!"d++ "w 3!#"!5 "KK/!Jug[Y_X``a(bc ! ;LTRTXJ'WX < &:f[6I4+P+PUaeklwexUx&vk':<'HIEA!"d++ "ww0C D!#"&&22F!G "KK-s*UG;W]V^^_(`a !#B,,_S%=b%AF%1:61BID-0WWWcgggr>R-SF.1gghRT@U.VG'-v(.mA3iPTvU_`f_ggrszr{{|4}(~	 2C !'qcAf/g h qc9J4PR8*'UV- J2 &:f[6I3+O+O!HVT_M`IaHbbeflmxfyz~{~f  fA  AD   E  F	 6!fX&6fS)9%:$;;^_`h'' M f$F;4G)N)NLM -B!"d++2 "w 3!#"!5 539%0 . &:f[6I4+P+PUaeklwexUxJK -l;B!"d++ "ww0C D!#"&&22F!G 39%0 ! $B,,O
d0H0L-0+<C'1#t'<'<14#'''SUBV1W25''(CGGHVXDY2Z+16DK&,A ,=  1 <. &:f[6I4+P+PU`djkvdwUwQRf[1+>EE$[1+>%b$//$&FF7BFF7B4G$HE%'VVHbffXr6J%KF$u7=e 4 &~fXWUGSh-i j ? &:f[6I3+O+Ocd	 &:f[6I4+P+PUaeklwexUxf[1,?EEKK OPKN,DVKEXYeEf,g),&7#-b$#7#7,.FF7BFF7B<O,PE-/VVHbffXr>R-SF',u?Ee(<(.~fXWUZT[[q5r(s '8 F" &:f[6I4+P+PUaeklwexUxf[1,?FFKK MNKL-3K-@-NM)->>9P]C]*7	*B#*7z'3/G/G8PQX8Y$5'8'82CB/9"d/C/C8:wwXZH[8\9;"&&QY[]J^9_385KQ%4H4:LL>RXQYY`af`ggwAx4y 3D .O" CCDVCWW`an`opq**(h67
 KK*S%7$88KG9UV  w  ) _"LL+FqcIYZ[Y\)]^^_j  ) d"LL+^_`^a)bccdH % N'H%LMMN, % L'Fqc%JKKL  	LLEc!fXNO	s^  A9i <Gi A.f=&f#i &f?A:i :9i 4Ai i )i =Ci i 'gA	ggA?i A	i (Ai Ai !-g2 A	g2 $g2 A%i )h" h" 
h" !h" 8h" 	h" %A	h" 2(h" A2i 
f>f92i 9f>>i 
g/g*#i *g//i 2
h<hi hi "
i,i
i 
ii 
j!jjc                 `    [        [        R                  " 5       5      SS nUU[        R                  " 5       SS.nU R
                  R                  U5        [        R                  SU 35        U$ ! [         a1  n[        R                  S[        U5       35        [        S5      eSnAff = f)z,Save URL parameters and generate a short keyN   shortened_url)r4   
url_paramsr8   r  z,Successfully saved URL data with short key: zError saving URL data: z#Failed to save URL data to databaserQ  )r(   r  	short_keyrS  r)   s        r*   save_url_dataMongoHandler.save_url_dataN  s    	CDJJL)"1-I (&oo/'	H OO&&x0KKFykRS 	CLL23q6(;<ABB	Cs   A/A2 2
B-<,B((B-c                     U R                   R                  SU05      nU(       a0  SU;   a  UR                  S5      $ SU;   a  UR                  S5      $ U$ g! [         a"  n[        R                  SU 35         SnAgSnAff = f)z&
Retrieve URL parameters by short key
r4   rK  r  NzError retrieving URL data: )r   r@   rZ   r'   r   r%   )r(   r  rS  r)   s       r*   get_url_dataMongoHandler.get_url_data_  s    	//	0BCH(*#<<44!X-#<<55 $O 	LL6qc:;	s"   :A A A 
B!A>>B)r   r   r   r   r   r   )r>   )rl  )Nrk  )r   )rh   r  )r  r  )NNr  )NN)Nr  )Nr	  )r	  )r
  )rk  )NNN)NNr_  NN)F)]__name__
__module____qualname____firstlineno__r+   rN   rU   r^   rd   rp   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r-  r9  r\  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r&  r?  r`  rs  r  r  r  r<  rg  r`  ra  rb  r  r  r  r  r  r  r=  r8  r9  r:  r;  r<  rp  ru  r  r  r  r  r!  r4  r]   rH  rM  rT  rX  ra  ri  r  r  r  r  r  r  r  __static_attributes__rH  r  r*   r   r      sX   d'JRP((JT	 MDO6Q0J&J0#WJL0%MNN>M6"QHQ2-M^!KFUB/Rb,O\KVZ4Wl<M|EUN^V@/Jb7Qr'SR SD UD9TvFJPOLbYKv1XfN0S@O8$ULQ<"UHI[VX\t|X|mZ^}X~\U|WZrzYxu]n&		NY`Z]xL\\p
d#&
@~_@2h>$L7
r
.>P@>V@!FHYT<KTZ]W~9Yv N<D*"(8JX8]~J {zC"r  r   )utils.error_loggerr   r   r   r   r!   r   r  r	   r   r   r   r   stringrandomloggingconfig.settingsr   r   rF   rB   r?  r=  	getLoggerr  r   r   rH  r  r*   <module>r     sV    W W     (     3   
 	 (			8	$\] \]r  