+
    N\ej                        ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	t	^ RI
Ht ^ RIHt ^ RIHtHtHtHt ^ RIHt ]P*                  ! ]4      tRtRtR	 R
 ltR R ltR R ltR R ltR R ltR R ltR R lt R R lt!R# )    N)Any)text)AsyncSession)AsyncRetrying
RetryErrorstop_after_attemptwait_exponential)settingsz4[Segunor Intel Grid] Novo processo: {process_number}u   Novo processo detectado para {company}.

Processo: {process_number}
Tribunal: {court}
Data: {date}
Espécie: {type}
Fonte: {source}
NIF: {nif}

Detetado em: {created_at}
c          	      t    V ^8  d   QhR\         R\        R\        \        \        \        3,          ,          /# )   session
company_idreturn)r   strlistdictr   )formats   "app/services/alerts.py__annotate__r   !   s1      '*	$sCx.    c                   "   V P                  \        R4      RV/4      G Rj  xL
 P                  4       pV Uu. uF2  pRV^ ,          RV^,          RV^,          RV^,          RV^,          /NK4  	  up#  LQu upi 5i)	zKLoad enabled alert configs that apply to this company (specific or global).z
                SELECT id::text, company_id::text, type, target, enabled
                FROM alerts_config
                WHERE enabled = TRUE
                  AND (company_id IS NULL OR company_id = :cid)
                cidNidr   typetargetenabled)executer   all)r   r   rowsrs   &&  r   _load_configsr!   !   s     
 oo J

 
	
 
ce 	 A 
qt\1Q41x1yRSTURVW 
	
s    !A<A5A<8A72A<7A<c                f    V ^8  d   QhR\         R\        R\        R\        R\        R,          RR/# )r   r   
process_idalert_config_idstatusresponseNr   )r   r   )r   s   "r   r   r   8   sJ        	
  Dj 
r   c                   "   T P                  \        R 4      RTRTRTRT;'       g    RR,          ;'       g    R/4      G Rj  xL
  R#  L5i)z
            INSERT INTO alerts_log (process_id, alert_config_id, status, response)
            VALUES (:pid, :cid, :st, :resp)
            pidr   stresp :Ni  NN)r   r   )r   r#   r$   r%   r&   s   &$$$$r   _log_dispatchr,   8   sV      //	
 

E?D&&8>>WY[`JaJiJieij  s   6AAAAc                t    V ^8  d   QhR\         \        \        3,          R\         \        \        3,          /# )r   process_rowr   )r   r   r   )r   s   "r   r   r   K   s*      S#X 4S> r   c                    R V P                  R4      ;'       g    RRV P                  R4      RV P                  R4      ;'       g    RRV P                  R4      ;'       g    RRV P                  R	4      '       d    V P                  R	4      P                  4       MRR
V P                  R4      RV P                  R4      ;'       g    RRV P                  R4      '       d!   V P                  R4      P                  4       /# R/# )companycompany_namer+   nifcompany_nifprocess_numbercourttribunaldate
date_filedr   speciessource
created_atfirst_seen_at)get	isoformat)r.   s   &r   _build_payloadr?   K   s    ;??>288b{}-+//*:;AAr,22OOL11 .88:79	*+//(+11r%///:: #7AAC  AC r   c                H    V ^8  d   QhR\         R\         R\         R\         /# )r   to_addrsubjectbodyr   )r   )r   s   "r   r   r   Z   s(     # # #c # # #r   c                   \         P                  '       g   \        R4      h\        P                  P                  4       p\         P                  ;'       g    \         P                  ;'       g    RVR&   WR&   WR&   VP                  V4       \        P                  ! 4       p\         P                  '       d   \        P                  ! \         P                  \         P                  ^VR7      ;_uu_ 4       p\         P                  '       d/   VP                  \         P                  \         P                   4       VP#                  V4       RRR4       RV  2# \        P$                  ! \         P                  \         P                  ^R	7      ;_uu_ 4       p\         P&                  '       d   VP)                  VR
7       \         P                  '       d/   VP                  \         P                  \         P                   4       VP#                  V4       RRR4       RV  2#   + '       g   i     L; i  + '       g   i     L(; i)u  Blocking SMTP send. Returns a short status string on success or raises.

Suporta os dois modos: STARTTLS (tipicamente 587) e TLS implícito (465),
que é o do mail.segunor.pt. Com SMTP_SSL_IMPLICIT ligado a ligação nasce
já cifrada e não se chama starttls().
zSMTP not configuredznoreply@localhostFromToSubject)timeoutcontextNzsmtp ok (ssl) to rH   )rI   zsmtp ok to )r
   	SMTP_HOSTRuntimeErroremailmessageEmailMessage	SMTP_FROM	SMTP_USERset_contentsslcreate_default_contextSMTP_SSL_IMPLICITsmtplibSMTP_SSL	SMTP_PORTloginSMTP_PASSWORDsend_messageSMTPSMTP_STARTTLSstarttls)rA   rB   rC   msgctxss   &&&   r   
_send_smtprb   Z   s    011
--
$
$
&C$$QQ(:(:QQ>QCKI	NOOD

$
$
&C!!! 2 2B
 
!!!**H,B,BCNN3
 #7),,	h(((*<*<b	I	IQ!!!JJsJ#GGH&&(>(>?	s 
J 	""
 
 
J	Is   7AH">H5?H5"H2	5I	c          
      j    V ^8  d   QhR\         R\         R\         R\        \        \         3,          /# )r   r   rB   rC   r   )r   tuplebool)r   s   "r   r   r   z   s1     1 1 1s 1# 1%c	BR 1r   c                $  "   \         P                  '       g   R#  \        P                  ! \        WV4      G Rj  xL
 pRV3#  L  \
         d=   p\        P                  RY4       R\        T4      P                   RT 23u Rp?# Rp?ii ; i5i)u   Envio com assunto e corpo já montados.

O `send_email_alert` formata a partir do template de processos; os avisos de
insolvência têm corpo próprio (prazo, administrador, base do cálculo) e
precisam de passar ao lado desse template.
FNTzemail para %s falhou: %s: Fz'SMTP_HOST not configured; email skipped)
r
   rK   asyncio	to_threadrb   	Exceptionloggerwarningr   __name__)r   rB   rC   r*   es   &&&  r   send_email_rawrp   z   s      ??1&&z6DIITz J 116=a))*"QC0001sD   BA AA BA B1BBBBBc                    V ^8  d   QhR\         R\        \         \        3,          R\        \        \         3,          /# r   r   payloadr   r   r   r   rd   re   )r   s   "r   r   r      s3     
1 
13 
1c3h 
1E$PS)DT 
1r   c           	        "   \         P                  '       g   R# \        P                  ! R/ VB p\        P                  ! R/ / VCRVP                  R4      ;'       g    R/CB p \        P                  ! \        WV4      G Rj  xL
 pRV3#  L  \         d=   p\        P                  RY4       R \        T4      P                   RT 23u Rp?# Rp?ii ; i5i)	Fr2   u   —NTzemail alert to %s failed: %srg   rh    )r
   rK   EMAIL_SUBJECTr   
EMAIL_BODYr=   ri   rj   rb   rk   rl   rm   r   rn   )r   rs   rB   rC   r*   ro   s   &&    r   send_email_alertry      s     ??""-W-GON'N5'++e2D2M2MNOD1&&z6DIITz J 15vAa))*"QC0001sN   ACC'B BB CB C1CCCCCc                    V ^8  d   QhR\         R\        \         \        3,          R\        \        \         3,          /# rr   rt   )r   s   "r   r   r      s3      S 4S> eDRUIFV r   c                 F  "   \         P                  ! V\        R 7      p \        \	        \
        P                  4      \        ^^^R7      RR7        Rj  xL
  pT;_uu_ 4        \        P                  ! \
        P                  R7      ;_uu_4       GRj  xL
 pVP                  V VRR/R7      G Rj  xL
 pVP                  4        RVP                   R	VP                  R
,           23uuRRR4      GRj  xL
  uuRRR4       u #  L Lv LZ L  + GRj  xL 
 '       g   i     M; i RRR4       K    + '       g   i     K  ; iD R#   \         d   pRRT 23u Rp?# Rp?i\          d'   pR\#        T4      P$                   RT 23u Rp?# Rp?ii ; i5i))default)
multiplierminmaxT)stopwaitreraiseNrJ   zContent-Typezapplication/json)contentheaders :N   NFzretry exhausted: rg   )Funknown)jsondumpsr   r   r   r
   WEBHOOK_RETRIESr	   httpxAsyncClientWEBHOOK_TIMEOUT_Spostraise_for_statusstatus_coder   r   rk   r   rn   )r   rs   rC   attemptcr    ro   s   &&     r   send_webhook_alertr      sc    ::gs+D1*#H$<$<=!QA1=
 	C 	C'
  ,,X5O5OPPPTUff $!/1C D %  A
 &&(AMM?!AFF4L>!BB QPP 	C Q QPPPP 
$ 	  .)!--- 1a))*"QC0001s   F!1E EDEE %2D;DD;D5D67D-D;:D;D;?E F!ED;DD;D-D
D-&D-(D;1
E ;E
E F!FE*$F%F!*F7F8FFF!FF!c                b    V ^8  d   QhR\         R\        R\        \        \        3,          RR/# )r   r   r#   r.   r   N)r   r   r   r   )r   s   "r   r   r      s8     &> &>&>&> c3h&> 
	&>r   c           	       "   \        VP                  R4      4      pV'       g   R#  \        W4      G Rj  xL
 pT'       g   R# \        T4      p\        P                  RTP                  R4      \        T4      4       T F  pTR,          R8X  d   \        TR,          T4      G Rj  xL
 w  rM9TR,          R	8X  d   \        TR,          T4      G Rj  xL
 w  rMR
RTR,           2r \        T TTR,          T'       d   RMRT	R7      G Rj  xL
  K  	  R#  L  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i L Lw L?  \         d"   p\        P                  RT4        Rp?K  Rp?ii ; i5i)zrDispatch alerts for a newly discovered process. Failures are logged but
never raise into the caller's transaction.r   Nzload alerts_config failed: %sz%trigger_alerts: process=%s configs=%dr4   r   rM   r   webhookFzunknown type r   sentfailed)r#   r$   r%   r&   zalerts_log insert failed: %s)r   r=   r!   rk   rl   rm   r?   infolenry   r   r,   )
r   r#   r.   r   configsro   rs   cfgokr*   s
   &&&       r   trigger_alertsr      sR     [__\23J%g:: [)G
KK/AQ1RTWX_T` v;'!-c(mWEEHB[I%/HwGGHBc&k];		>% #D	!#v    ; 6: FG  	>NN91==	>s   %E?D DD E?A%E?(E
)+E?EE?*$EEEE?D E&E<E?EE?E?EE<E71E?7E<<E?)"ri   email.messagerM   r   loggingrV   rS   typingr   r   
sqlalchemyr   sqlalchemy.ext.asyncior   tenacityr   r   r   r	   
app.configr
   	getLoggerrn   rl   rw   rx   r!   r,   r?   rb   rp   ry   r   r   rv   r   r   <module>r      st         
    / T T 			8	$ G

.&#@1"
10&>r   