
    Ƃj                    ,   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlZddlZddlZddlZddlm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+ ddlm,Z, ddl-m.Z/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE ddlFmGZG ddlHmIZImJZJmKZKmLZL ddlMmNZN  eeO          jP        ZQ e eQdz              eGjR        dejS        d         ejS        d         ejS        d          eTejS        d                   ejS        d         ddi           ZU eBeUd!d"d#d$d%&          ZV eLeVd%d%'          ZWejS        d(         ZX ejY        d)d*          ZZ eT ejY        d+d,                    Z[ eT ejY        d-d.                    Z\ eT ejY        d/d0                    Z]ejS        d1         Z^ eTejS        d2                   Z_ejS        d3         Z`ejS        d4         ZaejS        b                    d5e`          Zc e2jd                    Ze e+d%6          Zfd>d9Zgd?d;Zhd@d>ZidAdAZjdBdCZkdDZldEZmdFZndGZodCdKZpdDdNZqdEdPZrdFdRZsddltZtd>dSZudGdVZvdHdYZwdId]Zx G d^ d_eI          Zy G d` daey          Zz G db dcey          Z{ G dd deey          Z| G df dgey          Z} G dh diey          Z~ G dj dkey          Z G dl dmey          Z G dn doey          Z G dp dqe4          Z G dr dse          Z G dt due          Z G dv dwe4          Z G dx dye          Z G dz d{e4          Z G d| d}e          Z G d~ de4          Z G d de4          Z G d de4          Z G d de4          Z G d de4          Z G d de4          Z G d de4          Z G d de          Z G d de          Z eddddddd          Z edddddddddd
  
         eddddddddd	  	         eddddddddd	  	         eddddddddd	  	         eddddddddddĬ
  
        gZ eddddddg dʢ˦           edddddddg˦           eddddddg ˦           eddddddg ˦          gZg dݢZg dޢZg dߢZdJdZdJdZe
dKd            Z e$e          Z e#ef          fdLdZ e"ddg          Z G d de4          Z G d de4          Z G d de4          Ze                    dd          dMd            Ze                    de          dNd            Z e"d e#e          g          ZdOdZdPdZeb                    d          d             Zeb                    de          d             Zeb                    dee                   dd e&dd           e&d	dd
          fdQd            Ze                    de          dRd            Zeb                    de          dSd            Ze                    d          dSd            Ze                    de          dTd            Zeb                    dee                   dUdVd            Ze                    de          dWd            Zeb                    de          dXd!            Ze                    d"e          dYd$            Ze                    d"e          dYd%            Zeb                    d&ee                    e&dd           e&d'dd(          fdZd)            Ze                    d*e          d[d+            Ze                    d,e          d\d-            Zeb                    d.ee                    e&d/          fd]d1            Zeb                    d2ee                   d3             Ze                    d4          d^d6            Ze                    d7          d8             Ze                    e           e                    e           e                    eNd!d9gd9gd9g:            ej        ej        d;<            ej        d=          ZdS (_  uQ   
Qaans FastAPI backend — MySQL (via SQLAlchemy + PyMySQL) + JWT/email-OTP auth
    )annotationsN)	b64decode)asynccontextmanager)datedatetime	timedeltatimezone)EmailMessage)Path)Optional)Requesturlopen)uuid4)load_dotenv)	APIRouterDependsFastAPIHTTPExceptionQueryResponsestatus)HTTPAuthorizationCredentials
HTTPBearer)InvalidTokenError)ImageImageFilter)PasswordHash)	BaseModel
ConfigDictEmailStrField)ColumnDateDateTime
ForeignKeyIndexIntegerStringTextUniqueConstraintcreate_enginefuncselectupdate)URL)DeclarativeBaseSessionrelationshipsessionmaker)CORSMiddlewarez.envzmysql+pymysql
MYSQL_USERMYSQL_PASSWORD
MYSQL_HOST
MYSQL_PORTMYSQL_DBcharsetutf8mb4)
drivernameusernamepasswordhostportdatabasequeryTi     
   F)pool_pre_pingpool_recycle	pool_sizemax_overflowecho)bind
autocommit	autoflush
JWT_SECRETJWT_ALGORITHMHS256JWT_EXPIRE_MINUTES1440OTP_TTL_MINUTES5
OTP_LENGTH6	SMTP_HOST	SMTP_PORT	SMTP_USERSMTP_PASSWORD	SMTP_FROM)
auto_errorreturnstrc                 (    t                      j        S N)r   hex     (/var/www/app.qaans.com/backend/server.pynew_idrd   [   s    77;rb   r   c                 f    t          j        t          j                                      d           S )N)tzinfo)r   nowr	   utcreplacera   rb   rc   now_utcrj   _   s%    <%%--T-:::rb   urlOptional[np.ndarray]c                   	 t          | ddi          }t          |d          5 }|                                }d d d            n# 1 swxY w Y   t          j        t          j        |                                        d          }t          j	        |          S # t          $ r!}t          j        d| |           Y d }~d S d }~ww xY w)Nz
User-Agentz
dihadi/1.0)headers   )timeoutRGBzphoto fetch failed %s: %s)r   r   readPILImageopenioBytesIOconvertnparray	Exceptionloggingwarning)rk   reqrdataimges         rc   _load_image_from_urlr   d   s   cL,#?@@@S!$$$ 	6688D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	mBJt,,--55e<<x}}   3S!<<<ttttts:   $B AB AB AAB 
C
)CC
r   
np.ndarrayc                    	 t          j        | d          }|sd S t          j        | |d d                   }|r|d         nd S # t          $ r }t	          j        d|           Y d }~d S d }~ww xY w)Nhogmodel   known_face_locationsr   zface encoding failed: %s)face_recognitionface_locationsface_encodingsrz   r{   r|   r   	locationsencsr   s       rc   _encode_facer   p   s    $3CuEEE	 	4.sSUTUSUWWW(tAwwD(   2A666ttttts   A )A 
A0A++A02list[tuple[tuple[int, int, int, int], np.ndarray]]c                    	 t          j        | d          }|sg S t          j        | |          }t          t	          ||                    S # t
          $ r!}t          j        d|           g cY d}~S d}~ww xY w)zqDetect and encode every face in the frame. Returns list of
    (location, 128-d encoding). Empty list on failure.r   r   r   zmulti face encoding failed: %sN)r   r   r   listziprz   r{   r|   r   s       rc   _encode_all_facesr   |   s    
$3CuEEE	 	I.sSSSC	4(()))   8!<<<						s"   A 2A 
A:A5/A:5A:g      >@g     F@g      l@g333333?pil_imgPILImage.Imagedict[str, float]c                p   |                      d          }|                    t          j                  }t	          j        |t          j                  }t	          j        |t          j                  }t          |                                          t          |	                                          dS )zCheap, dependency-free sharpness + brightness score.
    - sharpness = variance of the FIND_EDGES-filtered grayscale image
    - brightness = mean of grayscale pixels
    Ldtype)	sharpness
brightness)
rw   filterr   
FIND_EDGESrx   asarrayfloat32floatvarmean)r   grayedges	arr_edgesarr_grays        rc   _image_qualityr      s    
 ??3DKK.//E
5
333Iz$bj111H9==??++HMMOO,,  rb   img_np*tuple[Optional[np.ndarray], Optional[str]]c                   t          |          }|d         t          k     rdd|d         ddfS |d         t          k    rdd|d         ddfS |d         t          k     rdd	|d         dd
fS t	          |           }|sdS t          |          dk    rddt          |           dfS |d         \  \  }}}}}| j        d         }	||z
  }
|	dk    r|
|	z  t          k     rdS |dfS )zRun every quality gate for face enrolment.
    Returns (encoding, error_message). On success encoding is set and error is None.r   Nz"The image is too dark (brightness z.0fz&). Move to better light and try again.z&The image is over-exposed (brightness z1). Reduce direct light on the face and try again.r   z#The image is too blurry (sharpness z'). Hold the phone steady and try again.)NzMNo face detected. Please look at the camera with the whole face in the frame.r   z	Detected z@ faces. Only one person should be in the frame during enrolment.r   )NzLFace is too far away or too small. Move closer so your face fills the frame.)r   QUALITY_MIN_BRIGHTNESSQUALITY_MAX_BRIGHTNESSQUALITY_MIN_SHARPNESSr   lenshapeQUALITY_MIN_FACE_HEIGHT_FRAC)r   r   qfacestoprightbottomleftenchface_hs              rc   _assess_enrolmentr      sy   
 	wA///2<I 2 2 2
 	
 	///=Q|_M = = =
 	
 	~---3!K.I 3 3 3
 	
 f%%E 

 
 5zzA~~&E

 & & &
 	
 ',Ah#S%QAc\F1uu&1* <<<
 
 9rb   payloadc                P    t          |           }|t          j        |          nd S r_   )_decode_b64_pilrx   ry   )r   pils     rc   _decode_b64_imager      s%    
'
"
"CO28C===5rb   Optional[PILImage.Image]c                L   	 |                      d          r|                     dd          d         } t          j        t	          j        t          |                                                   d          S # t          $ r }t          j
        d|           Y d }~d S d }~ww xY w)Ndata:,r   rq   zb64 decode failed: %s)
startswithsplitrs   rt   ru   rv   r   rw   rz   r{   r|   )r   r   s     rc   r   r      s    g&& 	/mmC++A.G}RZ	'(:(:;;<<DDUKKK   /333ttttts   A6A9 9
B#BB#c                 P    t          j        dt          z            dt           dS )NrD   0d)secrets	randbelowrT   ra   rb   rc   generate_otpr      s)    j 011BJBBBBBrb   emailsup_idc                    t          j        t          j                  }|                                 |||t          t                    z   dd}t          j        |t          t                    S )Nminutesaccess)subsupervisor_idiatexptype)	algorithm)r   rg   r	   rh   lowerr   rP   jwtencoderM   rN   )r   r   rg   r   s       rc   create_access_tokenr      s`    
,x|
$
$C{{}}Y'9:::: G :gz]CCCCrb   tokendictc                    	 t          j        | t          t          gdg di          S # t          $ r t          t          j        dddi          w xY w)Nrequire)r   r   r   r   )
algorithmsoptionszInvalid or expired tokenWWW-AuthenticateBearerstatus_codedetailrn   )r   decoderM   rN   r   r   r   HTTP_401_UNAUTHORIZED)r   s    rc   decode_access_tokenr      s    
z% = = =>	
 
 
 	
  
 
 
4-'2
 
 
 	

s	   &) )Ato_emailotpNonec           	        K   t                      }t          |d<   | |d<   d|d<   |                    d| dt           d           t	          j        |t          t          t          t          dd	
           d {V  d S )NFromToz$Your Qaans ERP supervisor login codeSubjectzYour Qaans ERP login code is z.

It expires in zQ minutes and can only be used once. If you did not request it, ignore this email.T   )hostnamer@   r=   r>   	start_tlsrp   )
r
   rZ   set_contentrR   
aiosmtplibsendrV   rW   rX   rY   )r   r   messages      rc   send_otp_emailr     s      nnGGFOGDM?GI	8 	8 	8(	8 	8 	8  
 /           rb   c                      e Zd ZdS )BaseN)__name__
__module____qualname__ra   rb   rc   r   r     s        Drb   r   c                  j   e Zd ZdZ e ed          de          Z e ed          d          Z e ed          dd	          Z	 e ed
                    Z
 e ed                    Z e ed                    Z ee          Z e ed                    Z eee          ZdS )
Supervisorsupervisors@   Tprimary_keydefaultx   Fnullable(   uniquer     r  N)r   r   r  __tablename__r"   r(   rd   idnamecoder   phonedesignationr)   photojoining_dater$   rj   
created_atra   rb   rc   r  r    s        !M	r

f	=	=	=B6&&++...D6&&**TE:::DF66#;;EF66"::E&%%KF4LLE6&&**%%L'222JJJrb   r  c                  6   e Zd ZdZ e ed          de          Z e ed          d          Z e ed                    Z	 e ed                    Z
 e ed	          d
d          Z ee          Z eee          Z eddd          ZdS )Projectprojectsr  Tr  r  Fr
  r  r   Active)r  r  r  
Allocationprojectall, delete-orphanback_populatescascadeN)r   r   r  r  r"   r(   rd   r  r  location
start_dater   r)   coverr$   rj   r  r2   allocationsra   rb   rc   r  r  (  s        M	r

f	=	=	=B6&&++...DvffSkk""Hr

##JVFF2JJ5AAAFF4LLE'222J,Y8L  KKKrb   r  c                     e Zd ZdZ e ed          de          Z e ed          d          Z e ed                    Z	 e ed          dd	          Z
 e ed                    Z e ed                    Z e ed
                    Z e ed
                    Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z ee          Z ee          Z e ed                    Z e ed                    Z e ed                    Z e ed                    Z e ed          d          Z ee          Z ee          Z  ee!e"          Z# e$ddd          Z%dS )Employee	employeesr  Tr  r	  Fr
  r  r  r   r     r  r  r  employeer   r!  N)&r   r   r  r  r"   r(   rd   r  r  name_hir  r  skillgendermarital_statusdobfather_namenomineeprimary_mobile
alt_mobiler   date_of_joiningdate_of_exitr)   current_addresspermanent_addressaadhaarpanuanesir   r  face_encodingr$   rj   r  r2   r'  ra   rb   rc   r)  r)  7  su       M	r

f	=	=	=B6&&++...DfVVC[[!!G6&&**TE:::D&%%KF66#;;EVFF2JJFVFF2JJ''N
&

C&%%KfVVC[[!!GVFF2JJ''Nr

##JF66#;;EfVVBZZ((O6&&**%%LfTllOtfVVBZZ  G
&

C
&

C
&

CVFF2JJ111FF4LLEF4LLM'222J,Z9M  KKKrb   r)  c                  ,   e Zd ZdZ e ed          de          Z e ed           ed          d          Z	 e ed           ed          d          Z
 eee	          Z ed
dd          fZ edd          Z edd          ZdS )r  r'  r  Tr  zprojects.idFr
  employees.idr  
project_idemployee_iduq_alloc)r  r  )r"  r)  N)r   r   r  r  r"   r(   rd   r  r%   rA  rB  r$   rj   allocated_atr*   __table_args__r2   r  r,  ra   rb   rc   r  r  Y  s        !M	r

f	=	=	=Br

JJ}$=$=NNNJ&ZZ%?%?%PPPK6(G444L&&|]TTTVNl9]CCCG|J}EEEHHHrb   r  c                  2   e Zd ZdZ e ed          de          Z e ed           ed          d          Z	 e ed          d          Z
 e ed	                    Z e ed                    Z eee
          Z eed 
          ZdS )AttendanceRecord
attendancer  Tr  r@  Fr
  r   r  r  c                 (    t          j                    S r_   )r   todayra   rb   rc   <lambda>zAttendanceRecord.<lambda>m  s    tz|| rb   N)r   r   r  r  r"   r(   rd   r  r%   rB  r   timer   r$   rj   	marked_atr#   dayra   rb   rc   rG  rG  e  s         M	r

f	=	=	=B&ZZ%?%?%PPPK6&&**u---D6&&**DVFF2JJFx111I
&33
4
4
4CCCrb   rG  c                  &   e Zd ZdZ e ed          de          Z e ed           ed          d          Z	 e ed          d          Z
 eed	
          Z eed	
          Z eed	
          Z e ed          d
          ZdS )SalaryRecordsalary_recordsr  Tr  r@  Fr
  r   r   r  PendingN)r   r   r  r  r"   r(   rd   r  r%   rB  monthr'   days_worked
daily_rate
deductionsr   ra   rb   rc   rP  rP  p  s        $M	r

f	=	=	=B&ZZ%?%?%PPPKF66"::...E&!,,,K+++J+++JVFF2JJ	222FFFrb   rP  c                     e Zd ZdZ e ed          de          Z e ed          d          Z ee	          Z
 e ed                    Z eed	
          Z e ed                    Z eee
          ZdS )Notificationnotificationsr  Tr  r  Fr
  <   r   r  r+  N)r   r   r  r  r"   r(   rd   r  titler)   description
time_labelr'   rr   r   r$   rj   r  ra   rb   rc   rX  rX  {  s        #M	r

f	=	=	=BF66#;;///E&,,Kr

##J6'1%%%D6&&**D'222JJJrb   rX  c                      e Zd ZdZ eedd          Z e ed          dd          Z ee	d          Z
 eede          Z eedd          Z eedd	          Z eed          Z ed
dd          fZdS )OtpCode	otp_codesT)r  autoincrementi@  F)r  indexr
  )r  r  r   ix_otp_email_createdr   r  N)r   r   r  r  r"   r'   r  r(   r   r)   	code_hashr$   rj   r  
expires_atattemptsused_atr&   rE  ra   rb   rc   r_  r_    s        M	T	>	>	>BF66#;;d;;;Ete,,,I5'BBBJ5===Jvgq999HfX---Ge2G\JJLNNNrb   r_  c                  &    e Zd Z ed          ZdS )PydBaseT)from_attributesN)r   r   r  r   model_configra   rb   rc   ri  ri    s         :d333LLLrb   ri  c                  t    e Zd ZU ded<   ded<   ded<   dZded<   dZded	<   dZded
<   dZded<   dZded<   dS )SupervisorOutr]   r  r  r  NzOptional[EmailStr]r   Optional[str]r  r  r  r  )	r   r   r  __annotations__r   r  r  r  r  ra   rb   rc   rm  rm    s         GGGIIIIII $E$$$$E!%K%%%%E"&L&&&&&&rb   rm  c                  f    e Zd ZU ded<   ded<   dZded<   dZded<   ded<   dZded	<   g Zd
ed<   dS )
ProjectOutr]   r  r  Nrn  r$  r%  r   r&  z	list[str]allocated_employee_ids)r   r   r  ro  r$  r%  r&  rr  ra   rb   rc   rq  rq    sr         GGGIII"H"""" $J$$$$KKKE(*******rb   rq  c                  R    e Zd ZU ded<   dZded<   dZded<   dZded<   dZded	<   dS )
	ProjectInr]   r  Nrn  r$  r%  r  r   r&  )r   r   r  ro  r$  r%  r   r&  ra   rb   rc   rt  rt    s_         III"H"""" $J$$$$FErb   rt  c                      e Zd ZU ded<   ded<   dZded<   ded<   dZded<   dZded	<   ded
<   dZded<   dZded<   dZ	ded<   dZ
ded<   dZded<   dS )EmployeeOutr]   r  r  Nrn  r-  r  r  r.  r   r  r4  r   rA  project_name)r   r   r  ro  r-  r  r.  r  r4  r   rA  rw  ra   rb   rc   rv  rv    s         GGGIII!G!!!!III!%K%%%%EKKKE$(N((((E $J$$$$"&L&&&&&&rb   rv  c                  X   e Zd ZU ded<   dZded<   ded<   dZded<   dZded<   dZded	<   dZded
<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dS )
EmployeeInr]   r  Nrn  r-  r  r  r.  r/  r0  r1  r2  r3  r4  r5  r   r6  r7  r8  r9  r:  r;  r<  r=  r  r   r  rA  )r   r   r  ro  r-  r  r.  r/  r0  r1  r2  r3  r4  r5  r   r6  r7  r8  r9  r:  r;  r<  r=  r   r  rA  ra   rb   rc   ry  ry    s        III!G!!!!III!%K%%%%E F    $(N((((C!%K%%%%!G!!!!$(N(((( $J$$$$E%)O))))"&L&&&&%)O))))'+++++!G!!!!CCCFE $J$$$$$$rb   ry  c                  l    e Zd ZU ded<   ded<   ded<   ded<   dZded<   ded	<   dZded
<   dZded<   dS )AttendanceOutr]   r  rB  employee_nameemployee_codeNrn  r  r   rL  r   )r   r   r  ro  r  rL  r   ra   rb   rc   r{  r{    s{         GGGEIIID F      rb   r{  c                  X    e Zd ZU ded<    ed          Zded<   dZded<   d	Zded
<   dS )AttendanceInr]   rB  ^(Check-in|Check-out)$patternr   Nrn  rL  On Timer   )r   r   r  ro  r!   r   rL  r   ra   rb   rc   r  r    s_         6777D7777D%F%%%%%%rb   r  c                  d    e Zd ZU ded<    edd          Zded<    eddd	
          Zded<   dS )FaceMatchInr]   	image_b64Check-inr  )r  r  r   g333333?g333333?g?)r  geler   	thresholdN)r   r   r  ro  r!   r   r  ra   rb   rc   r  r    s^         NNNj2JKKKDKKKKuTdt<<<I<<<<<<rb   r  c                  (    e Zd ZU ded<   dZded<   dS )FaceEnrollInr]   r  Tboolupdate_photoN)r   r   r  ro  r  ra   rb   rc   r  r    s,         NNNLrb   r  c                  2    e Zd ZU ded<   ded<   dZded<   dS )FaceEnrollOutr  okr]   r   NOptional[EmployeeOut]r,  )r   r   r  ro  r,  ra   rb   rc   r  r    s5         HHHLLL&*H******rb   r  c                  <    e Zd ZU dZded<   ded<   ded<   ded<   dS )FaceBoxzHNormalized bounding box (0..1) of a detected face in the analyzed frame.r   r   r   r   r   N)r   r   r  __doc__ro  ra   rb   rc   r  r    s:         RRJJJLLLMMMKKKKKrb   r  c                  R    e Zd ZU ded<   dZded<   dZded<   dZded	<   dZd
ed<   dS )FaceMatchItemr  matchedNOptional[float]distancer  r,  Optional[AttendanceOut]rH  zOptional[FaceBox]box)r   r   r  ro  r  r,  rH  r  ra   rb   rc   r  r  
  s_         MMM $H$$$$&*H*****.J....!C!!!!!!rb   r  c                  t    e Zd ZU ded<   dZded<   dZded<   dZded	<    ee
          Z	ded<   dZ
ded<   dS )FaceMatchOutr  r  Nr  r  r  r,  r  rH  )default_factoryzlist[FaceMatchItem]matchesr   intfaces_detected)r   r   r  ro  r  r,  rH  r!   r   r  r  ra   rb   rc   r  r    s}         MMM $H$$$$&*H*****.J....#(5#>#>#>G>>>>Nrb   r  c                      e Zd ZU ded<   ded<   ded<   ded<   dZded<   ded	<   d
ed<   d
ed<   d
ed<   ded<   d
ed<   dS )	SalaryOutr]   r  rB  r|  r}  Nrn  r  rS  r  rT  rU  rV  r   net)r   r   r  ro  r  ra   rb   rc   r  r    s         GGGEJJJOOOOOOKKKHHHHHrb   r  c                  T    e Zd ZU ded<   ded<   dZded<   dZded<   ded	<   ded
<   dS )NotificationOutr]   r  r[  Nrn  r\  r]  r  rr   r   )r   r   r  ro  r\  r]  ra   rb   rc   r  r  *  sV         GGGJJJ!%K%%%% $J$$$$JJJIIIIIrb   r  zRajesh VermazSUP-0007zrajesh.verma@dihadi.inz+91 99999 88888zSenior Supervisorz12 Jan 2022zhttps://images.unsplash.com/photo-1679679811837-c28b2586f533?crop=entropy&cs=srgb&fm=jpg&ixid=M3w4NjA1NTJ8MHwxfHNlYXJjaHwyfHx3b3JrZXIlMjBwb3J0cmFpdHxlbnwwfHx8fDE3ODI1NTEzODB8MA&ixlib=rb-4.1.0&q=85)r  r  r   r  r  r  r  e1zRamesh Kumaru   रमेश कुमारzDHD-1042zSite SupervisorSupervisionr  z+91 98231 45678zramesh.k@dihadi.inzhttps://images.unsplash.com/photo-1646227655685-a530813759b3?crop=entropy&cs=srgb&fm=jpg&ixid=M3w4NjA1NTJ8MHwxfHNlYXJjaHwzfHx3b3JrZXIlMjBwb3J0cmFpdHxlbnwwfHx8fDE3ODI1NTEzODB8MA&ixlib=rb-4.1.0&q=85)
r  r  r-  r  r  r.  r   r4  r   r  e2zSunita Deviu   सुनीता देवीzDHD-1043HelperzGeneral Labourz+91 98112 33445zphttps://images.pexels.com/photos/12576220/pexels-photo-12576220.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940)	r  r  r-  r  r  r.  r   r4  r  e3zMohan Singhu   मोहन सिंहzDHD-1044MasonBricklayingzNo Allocationz+91 97650 12000znhttps://images.pexels.com/photos/9227535/pexels-photo-9227535.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940e4z
Anil Yadavu   अनिल यादवzDHD-1045ElectricianWiringInactivez+91 96007 23498e5zPriya Sharmau"   प्रिया शर्माzDHD-1046zOffice Assistantz+91 95002 78122zpriya.s@dihadi.inzphttps://images.pexels.com/photos/37556467/pexels-photo-37556467.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940p1zSkyline Tower AzSector 62, Noidaz12 Jan 2026zYhttps://images.unsplash.com/photo-1503387762-592deb58ef4e?auto=format&fit=crop&w=900&q=60)r  r  r  )r  r  r$  r%  r   r&  r'  p2zGreenfield Mall RenovationzMG Road, Gurgaonz03 Nov 2025z\https://images.unsplash.com/photo-1541888946425-d81bb19240f5?auto=format&fit=crop&w=900&q=60p3zRiverside Villas Phase 2zYamuna Expresswayz20 Aug 2025zOn Holdz\https://images.unsplash.com/photo-1572120360610-d971b9d7767c?auto=format&fit=crop&w=900&q=60p4zMetro Line ExtensionzDwarka, Delhiz05 Feb 2025	Completedz\https://images.unsplash.com/photo-1487958449943-2429e8be8625?auto=format&fit=crop&w=900&q=60))r  r  z08:42 AMr  )r  r  z09:05 AMLate)r  r  z08:55 AMr  ))r  Feb 26   i     Paid)r  r     i&  d   r  )r  r     i  r   rR  )r  r     i   i,  
Processing)r  r  r  iX     r  ))Attendance markedz#Ramesh Kumar checked in at 08:42 AMz10 mins agoFrH  )zNew employee addedz3Priya Sharma (DHD-1046) has been added to your teamz
1 hour agoFr,  )zSalary processedz0December salary cycle completed for 48 employees	YesterdayTsalary)r  z)Sunita Devi checked in at 09:05 AM (Late)r  TrH  )zEmployee records updatedz)Mohan Singh's allocation has been updatedz
2 days agoTr,  c                    t                      5 } |                     t                                                    dk    r$|                     t          d	i t
                     |                     t                                                    dk    r)t          D ]!}|                     t          d	i |           "|                     t                                                    dk    rg }t          D ]X}|
                    d          }|                     t          d	i |           |D ]}|                    |d         |f            Y|                                  |D ])\  }}|                     t          ||                     *|                     t                                                    dk    r5t          D ]-\  }}}}	|                     t          ||||	                     .|                     t                                                     dk    r9t"          D ]1\  }}
}}}}	|                     t!          ||
||||	                     2|                     t$                                                    dk    r;t&          D ]3\  }}}}}|                     t%          ||||rdnd|                     4|                                  d d d            d S # 1 swxY w Y   d S )
Nr   r'  r  rA  rB  rB  r   rL  r   )rB  rS  rT  rU  rV  r   r   )r[  r\  r]  rr   r   ra   )SessionLocalrB   r  countaddSEED_SUPERVISORr)  SEED_EMPLOYEESr  SEED_PROJECTSpopappendflushr  rG  SEED_ATTENDANCErP  SEED_SALARYrX  SEED_NOTIFICATIONScommit)dbr   allocspempseidpidttmstmdwratededr[  desctlr~   tps                      rc   seed_if_emptyr    sR   	 288J%%''1,,FF:000011188H##%%**# & &x}}!}}%%%%88G""$$)),.F" 2 2uu]++w||||$$$ 2 2CMM1T7C.11112HHJJJ" D DSzScBBBCCCC88$%%++--22"1 V VQB'CabQSTTTUUUU88L!!''))Q..-8 Q Q)QD#r|1"/3BP P P Q Q Q Q88L!!''))Q..*< B B&tRB|%Tb./QRA A A B B B B
		7                 s   KK))K-0K-c                    t                      5 } |                     t                                        t          j                            d          t          j                            d                                                    }|D ]}|j        r|j        	                    d          s$t          |j                  }|;t          |          }|Mt          j        |                                          |_        |                                  t!          j        d|j                   	 ddd           dS # 1 swxY w Y   dS )zCompute + cache face_encoding for enrolled employees whose photo is a URL.
    Runs at startup so the first match request doesn't stall fetching photos.Nhttpzcached encoding for %s)r  rB   r)  r   r>  is_r  isnotallr   r   r   jsondumpstolistr  r{   infor  )r  r  empr   r   s        rc   warm_face_encodingsr    sg    
 =2xx!!(("&&t,,hn.B.B4.H.H
 

#%% 	  	= 	=C9 CI$8$8$@$@ &sy11C{s##C{ $
3::<< 8 8CIIKKKL138<<<<	=	= = = = = = = = = = = = = = = = = =s   D$EEE_r   c                  K   t           j                            t                     t	                       	 t                       n,# t          $ r}t          j        d|           Y d }~nd }~ww xY wd W V  d S )N)rJ   zwarm_face_encodings failed: %s)	r   metadata
create_allenginer  r  rz   r{   r|   )r  r   s     rc   lifespanr    s      M&)))OOO= = = =8!<<<<<<<<=	EEEEEEs   A 
A/A**A/)r  credentials&Optional[HTTPAuthorizationCredentials]c                   | r| j                                         dk    rt          ddddi          t          | j                  }t                      5 }|                    t          |                    dd                    }|r5|j                                        |d	                                         k    rt          dd
          |cd d d            S # 1 swxY w Y   d S )Nbeareri  zNot authenticatedr   r   r   r    r   zSupervisor no longer valid)	schemer   r   r   r  r  getr  r   )r  claimsr  sups       rc   require_supervisorr    s+     
+,2244@@&'2
 
 
 	

 !!899F	 2ffZOR!@!@AA 	Ccioo''6%=+>+>+@+@@@%ABBB	                 s   A8CC"Cz	/api/authauth)prefixtagsc                      e Zd ZU ded<   dS )OtpRequestBodyr    r   N)r   r   r  ro  ra   rb   rc   r  r    s         OOOOOrb   r  c                  <    e Zd ZU ded<    ed          Zded<   dS )OtpVerifyBodyr    r   z	^\d{4,6}$r  r]   r   N)r   r   r  ro  r!   r   ra   rb   rc   r	  r	    s9         OOOu\***C******rb   r	  c                  2    e Zd ZU ded<   dZded<   ded<   dS )TokenResponser]   access_tokenr  
token_typer  
expires_inN)r   r   r  ro  r  ra   rb   rc   r  r    s6         JOOOOOrb   r  z/request-otp   )r   bodyc           
       K   t          | j                                                                                  }t	                      }|t          d          z
  }t                      5 }|                    t          t          j
        t          j                                                t          j        |k    t          j        |k                        pd}|dk    rt          dd          |                    t          t                                         t           j        |k                        }|dd	icd d d            S t#                      }|                    t'          t                                        t          j        |k    t          j                            d           t          j        |k                                  |
                     t          |t0                              |          ||t          t4                    z   d          }|                    |           |                                 d d d            n# 1 swxY w Y   	 t;          ||           d {V  n# t<          $ r}	t?          j         d|	           t                      5 }|                    t'          t                                        t          j        |k    t          j                            d                                         t	                      
                     |                                 d d d            n# 1 swxY w Y   t          dd          d }	~	ww xY wdd	iS )N   r   r   rC   i  z&Too many OTP requests; try again laterr   r   z2If this address is eligible, an OTP has been sent.)rg  )r   rd  r  re  rf  zOTP send failed: %si  z+Unable to deliver OTP right now. Try again.)!r]   r   stripr   rj   r   r  scalarr-   r,   r  r_  r  wherer  r   r  r   executer.   rg  r  re  valuespassword_hashhashrR   r  r  r   rz   r{   r|   )
r  r   rg   window_startr  r  r  r   rowr   s
             rc   request_otpr    s     
OO!!##))++E
))C2....L	 "2		4:gj))**00&(:l(J 
 
  	 	
 A::,TUUUUiiz**001AU1JKKLL;ST" " " " " " " " nn 	

7OOU&##D))"S( 
 VCV  	
 	
 	
 #((--Y????
 
 
 	s
		E" " " " " " " " " " " " " " "HWUC(((((((((( 	W 	W 	W-q111^^ 	rJJww}-w/B/B4/H/HII		**  
 IIKKK	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 C(UVVVV	W KLLsW   *CIDII!I&I= =
M2#M-*BMM-M	M-M	M--M2z/verify-otp)response_modelc           	        t          | j                                                                                  }t	                      }t          dd          }t                      5 }|                    t          t                    
                    t          j        |k    t          j                            d           t          j        |k                                  t          j                                                            }|||j        dk    r||_        |                                 |t&                              | j        |j                  s8|xj        dz  c_        |j        dk    r||_        |                                 ||                    t          t.                    
                    t.          j        |k                        }|||_        |                                 |||_        |                                 t1          |j        |j                  }t5          |t6          dz            cd d d            S # 1 swxY w Y   d S )N  zInvalid or expired OTPr  rC   r   rZ  )r  r  )r]   r   r  r   rj   r   r  r  r-   r_  r  rg  r  re  order_byr  r  rf  r  r  verifyr   rd  r  r   r  r  rP   )r  r   rg   invalidr  r  r  r   s           rc   
verify_otpr$  !  s4   
OO!!##))++E
))CC(@AAAG	 !
2ii7OOU&##D))"S( 
 Xg(--//00
 
 ;M<1CKIIKKKM##DHcm<< 	LLALL|q  !IIKKKMiiz**001AU1JKKLL;CKIIKKKM
		#CIsv66+=+B
 
 
?!
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
 !
s   &G"IIIz/api)r  dependenciesr  r  r1   c                   |                     t          t                                        t          j        | j        k                                                                                        }d }d }|r2|j        }|	                    t          |j                  }|r|j        nd }t          | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        ||          S )N)r  r  r-  r  r  r.  r   r  r4  r   rA  rw  )r  r-   r  r  rB  r  scalarsfirstrA  r  r  r  rv  r-  r  r  r.  r   r  r4  r   )r  r  allocrA  rw  projs         rc   employee_to_outr+  P  s    


6*%%++J,Bcf,LMMNN		 

 !%J"&L 3%
vvgu/00$(2tyyd6#+CHO39SZi(:#)L	   rb   r  c           
         t          | j        | j        | j        | j        | j        | j        d | j        D                       S )Nc                    g | ]	}|j         
S ra   )rB  ).0as     rc   
<listcomp>z"project_to_out.<locals>.<listcomp>h  s    EEE!EEErb   )r  r  r$  r%  r   r&  rr  )rq  r  r  r$  r%  r   r&  r'  )r  s    rc   project_to_outr1  d  sF    4afqzalxqwEEq}EEE   rb   /c                 J    ddt                                                      dS )Ndihadir  )servicer   rL  )rj   	isoformatra   rb   rc   rootr7  m  s"    49L9L9N9NOOOrb   z/supervisor/mec                    t                      5 } |                     t                                                    }|st	          dd          t
                              |          cd d d            S # 1 swxY w Y   d S )N  zNo supervisor)r  rB   r  r(  r   rm  model_validate)r  r  s     rc   get_supervisorr;  r  s    	 12hhz""((** 	6_555++C00	1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s   AA44A8;A8z
/employeesr   )r  2   r  )r  r  responser   r   rn  r   pager  	page_sizec                >  	 t                      5 		                    t                    }|r)|dk    r#|                    t          j        |k              }|rXd| d}|                    t          j                            |          t          j                            |          z            }|                                }|	                    t          j
                                                                      |dz
  |z                                |                                          }t          |          | j        d<   t          |          | j        d<   t          |          | j        d<   	fd|D             cd d d            S # 1 swxY w Y   d S )NAll%r   X-Total-CountX-PageX-Page-Sizec                0    g | ]}t          |          S ra   )r+  )r.  r   r  s     rc   r0  z"list_employees.<locals>.<listcomp>  s#    55512&&555rb   )r  rB   r)  r   r   r  iliker  r  r!  r  r  offsetlimitr  r]   rn   )
r=  r   r   r>  r?  rB   liketotalr  r  s
            @rc   list_employeesrL  |  s    
 62"" 	<fooLLF!:;;E 	\q888DLL(-"5"5d";";@S@STX@Y@Y!Z[[ENN8.335566VTAX*++U9SUU	 	 -0JJ)%(YY"*-i..'5555555#6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6s   E5FFFc                   t                      5 }|                     dh          }t          di |}|                    |           |                                 | j        r.|                    t          | j        |j                             |                                 |	                    |           t          ||          cd d d            S # 1 swxY w Y   d S )NrA  )excluder  ra   )r  
model_dumpr)  r  r  rA  r  r  r  refreshr+  )r   r  r   r  s       rc   create_employeerQ    s   	 	(2!!<.!99
s



 	RFF:);PPPQQQ
		


3sB''	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(s   B:CCCz/employees/{emp_id}emp_idc                    t                      5 }|                    t          |           }|st          dd          t	          ||          cd d d            S # 1 swxY w Y   d S )Nr9  Employee not found)r  r  r)  r   r+  rR  r  r  s      rc   get_employeerV    s    	 (2ffXv&& 	;%9:::sB''	( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   =AA Ac                   t                      5 }|                    t          |           }|st          dd          |                    |           |                                 ddicd d d            S # 1 swxY w Y   d S )Nr9  rT  r  T)r  r  r)  r   deleter  rU  s      rc   delete_employeerY    s    	 2ffXv&& 	;%9:::
		#
		d|                 s   AA66A:=A:z/employees/{emp_id}/enroll-facec           	        t          |j                  }|t          dd          t          j        |          }t          ||          \  }}||t          d|pd          t                      5 }|                    t          |           }|st          dd          t          j
        |                                          |_        |j        r(|j        }|                    d          sd	| }||_        |                                 |                    |           t%          j        d
|j        |j                   t-          dd|j         t/          ||                    cddd           S # 1 swxY w Y   dS )a  Enroll (or re-enroll) the face for an employee using a base64 image
    captured from the camera. Overwrites the cached 128-d encoding.
    Optionally stores the image itself as the employee's photo (data URL).

    Quality gates (all must pass):
    - decodes successfully
    - not too dark / not over-exposed
    - not blurry
    - exactly one face detected, occupying at least ~15% of image height
    Nr   Could not decode imagei  zEnrolment quality check failedr9  rT  r   zdata:image/jpeg;base64,zenrolled face for %s (%s)TzFace enrolled for )r  r   r,  )r   r  r   rx   ry   r   r  r  r)  r  r  r  r>  r  r   r  r  rP  r{   r  r  r  r  r+  )	rR  r   r   framer   errr  r  b64s	            rc   enroll_employee_facer_    s    '+
,
,C
{C!9:::HSMME ,,HC
#+C!H(HIII	 
2ffXv&& 	;%9::: Jszz||44 	#C>>'** 6555CI
		


30#(CHEEE333$S"--
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   2C8E77E;>E;z	/projectsc                .   t                      5 }|                    t                    }| r)| dk    r#|                    t          j        | k              }|rXd| d}|                    t          j                            |          t          j                            |          z            }|                    t          j	        
                                                                          }d |D             cd d d            S # 1 swxY w Y   d S )NrA  rB  c                ,    g | ]}t          |          S ra   )r1  )r.  r  s     rc   r0  z!list_projects.<locals>.<listcomp>  s     111aq!!111rb   )r  rB   r  r   r   r  rG  r$  r!  r  r  r  )r   r   r  rB   rJ  projss         rc   list_projectsrc    s1   	 22!! 	;fooLL6!9::E 	^q888DLL',"4"4T":":w?O?U?UVZ?[?[!\]]Ew1668899==??1151112 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s   C.D

DDc                (   t                      5 }t          di |                                 }|                    |           |                                 |                    |           t          |          cd d d            S # 1 swxY w Y   d S )Nra   )r  r  rO  r  r  rP  r1  )r   r  r  s      rc   create_projectre    s    	 !2++g((**++
q			
		


1a  ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   A+BBBz/projects/{project_id}rA  c                    t                      5 }|                    t          |           }|st          dd          t	          |          cd d d            S # 1 swxY w Y   d S Nr9  Project not found)r  r  r  r   r1  )rA  r  r  s      rc   get_projectri    s    	 !2FF7J'' 	:%8999a  	! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   <AAAz-/projects/{project_id}/allocate/{employee_id}rB  c                   t                      5 }|                    t          |           st          dd          |                    t          |          st          dd          |                    t          t                                        t          j	        | k    t          j
        |k    z                                                                                      }|s8|                    t          | |                     |                                 |                    t          |           }t          |          cd d d            S # 1 swxY w Y   d S )Nr9  rh  rT  r  )r  r  r  r   r)  r  r-   r  r  rA  rB  r'  r(  r  r  r1  )rA  rB  r  existsr  s        rc   allocate_employeerl    so   	 !2vvgz** 	:%8999vvh,, 	;%9:::JJz""((*j8!-<>   WYYUWW 	  	FF:MMMNNNIIKKKFF7J''a  '! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   D7EEEc                   t                      5 }|                    t          t                                        t          j        | k    t          j        |k    z                                                                                      }|r)|	                    |           |
                                 |                    t          |           }|st          dd          t          |          cd d d            S # 1 swxY w Y   d S rg  )r  r  r-   r  r  rA  rB  r'  r(  rX  r  r  r  r   r1  )rA  rB  r  r)  r  s        rc   unallocate_employeern    s-   	 !2JJz""((*j8!-<>   WYYUWW 	  	IIeIIKKKFF7J'' 	:%8999a  #! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   C$D  DDz/attendance/todayr  i  c                v   t                      5 }|                    t                                        t          j        t          j                    k              }|                                }|                    t          j	        
                                                              |dz
  |z                                |                                          }t          |          | j        d<   t          |          | j        d<   t          |          | j        d<   g }|D ]w}|                    t"          |j                  }	|	s%|                    t)          |j        |	j        |	j        |	j        |	j        |j        |j        |j                             x|cd d d            S # 1 swxY w Y   d S )Nr   rC  rD  rE  r  rB  r|  r}  r  r   rL  r   )r  rB   rG  r   rN  r   rJ  r  r!  rM  r  rH  rI  r  r]   rn   r  r)  rB  r  r{  r  r  r  r  r   rL  r   )
r=  r>  r?  r  baserK  recsoutr~   r  s
             rc   today_attendancert  2  s    
 2xx())001A1E1UVV

MM*499;;<<VTAX*++U9SUU	 	 -0JJ)%(YY"*-i..'#% 
	 
	A&&1=11C JJtsx"%(#)afQX      1                 s   FF..F25F2z/attendance/markc                J   t                      5 }|                    t          | j                  }|st	          dd          t          |j        | j        | j        p%t          j
                                        d          | j                  }|                    |           |                                 |                    |           t!          |j        |j        |j        |j        |j        |j        |j        |j                  cd d d            S # 1 swxY w Y   d S )Nr9  rT  %I:%M %pr  rp  )r  r  r)  rB  r   rG  r  r   rL  r   rg   strftimer   r  r  rP  r{  r  r  r  )r   r  r  recs       rc   mark_attendancery  S  s?   	 
2ffXw233 	;%9:::D!8!8!D!D>	
 
 
 	s
		


3v36(#)
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   C<DDDz/attendance/matchc                	   t          | j                  }|t          dd          t          |          }t	          j        dt          |                     |st          ddg d          S t                      5 }|	                    t                                        t          j        dk                                              }g }|D ]}d}|j        rK	 t          j        t#          j        |j                  t          j        	          }n# t(          $ r d}Y nw xY w|o|j        rht-          |j                  }|Rt/          |          }	|	A|	}t#          j        |	                                          |_        |                                 ||                    ||f           t9          d
          }
g }t;                      }|j        dd         \  }}|D ]\  }}|\  }}}}t?          |r||z  nd|r||z  nd|r||z  nd|r||z  nd          }d}d}|D ]J\  }}|j         |v rtC          t          j"        #                    ||z
                      }|||k     r|}|}K|||| j$        k    r&|                    tK          d||                     |&                    |j                    tO          |j         | j(        tS          j*                    +                    d          d          }|&                    |           |                                 |,                    |           |                    tK          d|t[          ||          t]          |j         |j         |j/        |j0        |j        |j(        |j1        |j                  |                     te          d |D             d          }|td |D             }|rtg          |          nd}t	          j        dt          |          || j$                   t          d||t          |                    cddd           S t          d|j4        |j5        |j6        |t          |                    cddd           S # 1 swxY w Y   dS )a
  Server-side multi-face match. Client sends a base64 JPEG/PNG captured
    from the camera; we detect ALL faces in the frame, compute 128-d encodings
    for each, compare each with every enrolled employee, and mark attendance
    for every face whose best-match distance is under the threshold.

    Response keeps `matched/employee/attendance` for backward compatibility
    (first successful match) and adds `matches: list[FaceMatchItem]` containing
    one entry per detected face and `faces_detected` = raw count.
    Nr   r[  zmatch: faces detected=%dFr   )r  r  r  r  r  r   -   )seconds   )r   r   r   r   )r  r  r  rv  r  r  Trp  )r  r  r,  rH  r  c              3  (   K   | ]}|j         	|V  d S r_   )r  r.  r  s     rc   	<genexpr>zmatch_face.<locals>.<genexpr>  s)      >>AI>!>>>>>>rb   c                *    g | ]}|j         	|j         S r_   )r  r  s     rc   r0  zmatch_face.<locals>.<listcomp>  s!    SSSAJ<R<R<R<Rrb   z4match: no match (faces=%d best_dist=%s threshold=%s))r  r  r,  rH  r  r  )7r   r  r   r   r{   r  r   r  r  rB   r)  r   r   r  r>  rx   ry   r  loadsfloat64rz   r  r   r   r  r  r  r  r   setr   r  r  r   linalgnormr  r  r  rG  r   r   rg   rw  rP  r+  r{  r  r  rL  nextminr  r,  rH  )r   r\  probesr  r  emp_encsr  enc_arrr   r   cooldown_windowmatches_outalready_matched_idsh_imgw_imglocprobetop_pxright_px	bottom_pxleft_pxr  best_emp	best_distdistrx  	first_hit	distancess                               rc   
match_facer  i  sc    g/00E}C!9:::u%%FL+S[[999 XED"UVWWWW	 l
2xx!!((J)FGGKKMM 79 	0 	0C,0G  ## htz#2C'D'DBJWWWGG  # # #"GGG#39*3955?&s++C"%,0Jszz||,D,D)		"g///
 $B///+-(+{2A2u  2	 2	JC360FHi&+2FUNN*/6h&&Q,18y5((q(-4Wu__1	  C ,0H)-I ( # #W6000RY^^GeO<<==$y(8(8 $I"H9#4	GDU8U8U""=X[#\#\#\]]]##HK000"$K\\^^,,Z88 	  C FF3KKKIIKKKJJsOOO &,Xr::,6$,K&.m&.m&n X X"z	  	  	       & >>[>>>EE	SS[SSSI*3=IILFFY(9    "#"6{{	  }l
 l
 l
 l
 l
 l
 l
 l
J '' +v;;
 
 
Kl
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
 l
s>   ;AQ>7DQ>D Q>D  LQ>0Q>>RRz/salaryr  rS  c                <   t                      5 }|                    t                    }| r#|                    t          j        | k              }|                                }g }|D ]}|                    t          |j                  }|s%|j	        |j
        z  |j        z
  }|                    t          |j        |j        |j        |j        |j        |j        |j	        |j
        |j        |j        |                     |cd d d            S # 1 swxY w Y   d S )N)r  rB  r|  r}  r  rS  rT  rU  rV  r   r  )r  rB   rP  r   rS  r  r  r)  rB  rT  rU  rV  r  r  r  r  r  r  r   )rS  r  rB   rowsrs  r~   r  r  s           rc   rQ  rQ    sU   	 2&& 	>LL!3u!<==Eyy{{! 	 	A&&1=11C -!,.=CJJtsx"%(#)17 !!, |AH#	      '                 s   C5DDDz/notificationsc                     t                      5 } |                     t                                        t          j                                                                                  }d |D             cd d d            S # 1 swxY w Y   d S )Nc                    g | ]B}t          |j        |j        |j        |j        t          |j                  |j                   CS ))r  r[  r\  r]  rr   r   )r  r  r[  r\  r]  r  rr   r   )r.  ns     rc   r0  z&list_notifications.<locals>.<listcomp>	  sY     
 
 

 	 4qwAM<d16ll  
 
 
rb   )r  rB   rX  r!  r  r  r  )r  r  s     rc   list_notificationsr    s    	 
2xx%%..|/F/K/K/M/MNNRRTT
 

 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   A'BB
Bz/notifications/{nid}/readnidc                    t                      5 }|                    t          |           }|st          dd          d|_        |                                 ddicd d d            S # 1 swxY w Y   d S )Nr9  zNotification not foundr   r  T)r  r  rX  r   rr   r  )r  r  r  s      rc   mark_notification_readr    s    	 2FF<%% 	?%=>>>
		d|                 s   AA((A,/A,z/notifications/read-allc                     t                      5 } |                     t                                        t          j        di           |                                  ddicd d d            S # 1 swxY w Y   d S )Nr   r  T)r  rB   rX  r.   rr   r  )r  s    rc   mark_all_readr    s    	 2
%%|'8!&<===
		d|                 s   AA--A14A1*)allow_credentialsallow_originsallow_methodsallow_headersz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)levelformatr4  )r\   r]   )r\   r   )rk   r]   r\   rl   )r   r   r\   rl   )r   r   r\   r   )r   r   r\   r   )r   r   r   r   r\   r   )r   r]   r\   rl   )r   r]   r\   r   )r   r]   r   r]   r\   r]   )r   r]   r\   r   )r   r]   r   r]   r\   r   )r\   r   )r  r   )r  r  r\   r  )r  r  )r  r	  )r  r)  r  r1   r\   rv  )r  r  r\   rq  )
r=  r   r   rn  r   rn  r>  r  r?  r  )r   ry  )rR  r]   )rR  r]   r   r  )NN)r   rn  r   rn  )r   rt  )rA  r]   )rA  r]   rB  r]   )r=  r   r>  r  r?  r  )r   r  )r   r  )rS  rn  )r  r]   )r  
__future__r   ru   r{   osr   base64r   
contextlibr   r   r   r   r	   email.messager
   pathlibr   typingr   urllib.requestr   r   uuidr   r   r   r   numpyrx   dotenvr   fastapir   r   r   r   r   r   r   fastapi.securityr   r   r   PILr   rs   r   pwdlibr   pydanticr   r   r    r!   
sqlalchemyr"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   sqlalchemy.enginer/   sqlalchemy.ormr0   r1   r2   r3   starlette.middleware.corsr4   __file__parentROOT_DIRcreateenvironr  	MYSQL_URLr  r  rM   getenvrN   rP   rR   rT   rV   rW   rX   rY   r  rZ   recommendedr  bearer_schemerd   rj   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r  r  r)  r  rG  rP  rX  r_  ri  rm  rq  rt  rv  ry  r{  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  appr  auth_routerr  r	  r  postr  r$  apir+  r1  r7  r;  r   rL  rQ  rV  rX  rY  r_  rc  re  ri  rl  rn  rt  ry  r  rQ  r  patchr  r  include_routeradd_middlewarebasicConfigINFO	getLoggerloggerra   rb   rc   <module>r     s    # " " " " " 				  				        * * * * * * 8 8 8 8 8 8 8 8 8 8 8 8 & & & & & &             + + + + + + + +               



           W W W W W W W W W W W W W W W W W W E E E E E E E E ! ! ! ! ! ! . . . . . . . .       ; ; ; ; ; ; ; ; ; ; ; ;                              " ! ! ! ! ! O O O O O O O O O O O O 4 4 4 4 4 4 4>>  Hv   CJZ%Z()	L	!	RZ%	&	&Z
#i
   	 
	
 
 
 |EUKKK Z%
	/733S#7@@AA #ibi 137788S<--..
J{#	C
;'((	J{#	
?+JNN;	22	((**
e,,,   ; ; ; ;
	 	 	 		 	 	 	   &    #    ( ( ( (V6 6 6 6
    C C C C	D 	D 	D 	D
 
 
 
    ,	 	 	 	 	? 	 	 	
3 
3 
3 
3 
3 
3 
3 
3    d       t   D	F 	F 	F 	F 	F 	F 	F 	F5 5 5 5 5t 5 5 53 3 3 3 34 3 3 33 3 3 3 34 3 3 3
M 
M 
M 
M 
Md 
M 
M 
M4 4 4 4 4i 4 4 4' ' ' ' 'G ' ' '+ + + + + + + +         	      ' ' ' ' '' ' ' '% % % % % % % %6! ! ! ! !G ! ! !& & & & &9 & & &= = = = =) = = =    9   
+ + + + +I + + +    i   " " " " "I " " "    9              g    $		
"
# Q   	DD~/MT^&mH)1E VW W W 	DD}.OV`%5h) BC C C 	DD}.IPZM/)A A A 	DD|-Hz"(:) VW W W 	DD~/SZd'}X)1D BC C C#0 	DD(3E!(j''') ) ) 	DD3>P!(mV   	DD1<O!)m   	DD-!+m  &          @= = = =* 
 
 
 
 gx   
 ;B'-:P:P    $ i{&:::    Y   + + + + +I + + +
    I    .c226M 6M 6M 326Mr ->>&
 &
 &
 ?>&
T ivWW5G-H-H,IJJJ   (    P P P 	-881 1 981 d;&788 !aAU2!,,,6 6 6 6 9866 ,{33
( 
( 
( 43
( 	{;;( ( ( <;( !""   #" 
+MJJ$
 $
 $
 KJ$
P T*%566	2 	2 	2 	2 76	2 +j11! ! ! 21! 	!*==! ! ! >=! 
9*UU! ! ! VU!. ;JWW! ! ! XW!, 	T--@AA aAU31---    BA@ 
];;
 
 
 <;
* 
l;;~
 ~
 ~
 <;~
D 4	?33*/%*=*=*=     430 	$*?@@	
 	
 A@	
 &''   (' 
#$$  %$   ;      3      %%%      
,A    
	8	$	$rb   