+
    kej"                     
   R t ^ RIHtHt ^ RIHtHtHtHtH	t	 ^ RI
Ht ^ RIHt ^ RIHt ^ RIHt ^ RIHt ]! RR	.R
7      t^tR R lt]P/                  R4      ]P0                  ! R4      ]! RR7      3R R ll4       4       tR# )u
  Dossiê consolidado de uma entidade, por NIF (v1 public API).

Alimenta a tab "Intel" da ficha de cliente do Sabichão. A ideia é que o Intel
Grid continue a ser a plataforma de monitorização, mas que a informação apareça
onde o cliente é gerido — quem atende um cliente não vai a outro portal.

É composição de dados que já existem (empresa, processos, insolvências,
publicações, contratos), não lógica nova: uma única chamada em vez de cinco,
porque a tab carrega em lazy-load e não pode ser lenta.
)	AnnotatedAny)	APIRouterDependsHTTPExceptionQueryRequest)text)AsyncSession)require_api_key)get_session)limiterz/dossierz
public-api)prefixtagsc                L    V ^8  d   QhR\         R,          R\         R,          /# )   rawNreturn)str)formats   "app/api/v1/dossier.py__annotate__r      s"     0 03: 0#* 0    c                 n    V '       g   R # RP                  R V  4       4      p\        V4      ^	8X  d   V# R # )N c              3   T   "   T F  qP                  4       '       g   K  Vx  K   	  R # 5i)N)isdigit).0chs   & r   	<genexpr>_norm_nif.<locals>.<genexpr>   s     6#BRR#s   (
()joinlen)r   digitss   & r   	_norm_nifr$      s2    WW6#66F[A%6/4/r   r   z
120/minuteu'   NIF/NIPC; aceita espaços e pontuação)descriptionc                    V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \
        \        \        3,          \        \        4      3,          R\        R\
        \        \        3,          /# )r   requestsession_keynifr   )	r   r   r
   r   r   dictr   r   r   )r   s   "r   r   r   #   so     f ff|W[%99:f DcNGO$<<
=f 
	f
 
#s(^fr   c                   "   \        V4      pV'       g   \        R RR7      hVP                  \        R4      RV/4      G Rj  xL
 P	                  4       P                  4       pVP                  \        R4      RVR\        /4      G Rj  xL
 P	                  4       P                  4       pVP                  \        R4      RVR\        /4      G Rj  xL
 P	                  4       P                  4       p. p. p	. p
/ p/ pV'       Ed   VR	,          pVP                  \        R
4      RVR\        /4      G Rj  xL
 P	                  4       P                  4        Uu. uF  p\        V4      NK  	  ppVP                  \        R4      RVR\        /4      G Rj  xL
 P	                  4       P                  4        Uu. uF  p\        V4      NK  	  p	pVP                  \        R4      RVR\        /4      G Rj  xL
 P	                  4       P                  4        Uu. uF  p\        V4      NK  	  p
pVP                  \        R4      RV/4      G Rj  xL
 P	                  4       P                  4       pV'       d   \        V4      M/ pVP                  \        R4      RV/4      G Rj  xL
 P	                  4       P                  4       pV'       d   \        V4      M/ pRTRVRJRV'       d   \        V4      MRRV Uu. uF  p\        V4      NK  	  upRV Uu. uF  p\        V4      NK  	  upRVRVRV	RV
RV/
#  EL EL ELi EL	u upi  ELu upi  EL[u upi  EL
 Lu upi u upi 5i)i  u   NIF inválido)status_codedetaila  
                SELECT c.id::text, c.nif, c.legal_name, c.cae, c.address,
                       c.natureza_juridica, c.distrito, c.concelho, c.freguesia,
                       c.codigo_postal, c.localidade, c.objeto_social,
                       c.capital_social, c.registry_complete, c.risk_score,
                       c.monitoring_type, c.active,
                       (SELECT ac.alvara_number FROM alvara_companies ac
                         WHERE ac.nipc = c.nif AND ac.alvara_type = 'A'
                           AND ac.removed_at IS NULL LIMIT 1) AS alvara
                FROM companies c WHERE c.nif = :nif
                r*   Naa  
                SELECT h.claim_deadline, (h.claim_deadline - CURRENT_DATE) AS days_left,
                       h.matched_role, h.acknowledged_at,
                       a.process_number, a.tribunal, a.ato, a.pub_date,
                       a.claim_days, a.claim_deadline_estimated,
                       a.admin_name, a.admin_email
                FROM insolvency_hits h
                JOIN cire_announcements a ON a.id = h.announcement_id
                WHERE h.matched_nif = :nif AND a.opens_claim_window
                ORDER BY h.claim_deadline NULLS LAST
                LIMIT :lim
                limau  
                SELECT DISTINCT a.id::text, a.pub_date, a.ato, a.process_number,
                       a.tribunal, p.role
                FROM cire_announcement_parties p
                JOIN cire_announcements a ON a.id = p.announcement_id
                WHERE p.nif = :nif
                ORDER BY a.pub_date DESC NULLS LAST
                LIMIT :lim
                ida   
                        SELECT process_number, tribunal, juizo, species, source,
                               role_in_process, date_filed
                        FROM processes WHERE company_id = :cid
                        ORDER BY date_filed DESC LIMIT :lim
                        cidz
                        SELECT title, date, type, source
                        FROM dre_publications WHERE company_id = :cid
                        ORDER BY date DESC NULLS LAST LIMIT :lim
                        aM  
                        SELECT DISTINCT ON (person_nif, cargo)
                               person_name, person_nif, cargo, act_date
                        FROM publication_people WHERE company_id = :cid
                        ORDER BY person_nif, cargo, act_date DESC
                        LIMIT :lim
                        z
                    SELECT count(*) AS total, COALESCE(sum(value),0) AS valor
                    FROM public_contracts WHERE company_id = :cid
                    a!  
                    SELECT count(*) FILTER (WHERE source='cire') AS cire,
                           count(*) FILTER (WHERE source='distribuicao') AS distribuicao,
                           count(*) AS total
                    FROM processes WHERE company_id = :cid
                    monitorizadaempresaprazos_reclamacaoanuncios_insolvencia	processosprocessos_contagempublicacoespessoascontratos_publicos)	r$   r   executer	   mappingsfirst	MAX_ITEMSallr+   )r'   r(   r)   r*   nif_normcompany	deadlinesannouncements	processespublicationspeople	contractscountsr1   rrows   &&&&            r   dossierrK   !   s     ~HODD oo
 H
 	
  hj# , oo HeY/
 	
" hj% * oo
 HeY/
 	
 hj " ')I)+L#%F "IFwdm oo C	2
 
 hj
 G 	 
& oo C	2	 	 hj
 G 	 
$ oo C	2  hj
 G 	 
$ //   (*UUW 	 "%DI"	// 
 
 (*UUW 	 "cr 	x
 	t+G4=y9y!d1gy9- @-Qa- @Yf|6i Y	
*	
(	
6

&	
$
$
, : @s   AM$L4AM$
L7AM$L:2M$/M$4L=5"M$M +(M$M"M$6M
(M$2M3"M$M)"M$M'M$4-M$!M"'M$
M$&M$7MM$M&M$7M$:M$=M$ M$M$M$M$
M$N)__doc__typingr   r   fastapir   r   r   r   r   
sqlalchemyr	   sqlalchemy.ext.asyncior
   app.auth.api_key_authr   app.dbr   app.rate_limitr   routerr>   r$   getlimitrK    r   r   <module>rX      sv   	 " E E  / 1  "	*L>	:	0 B|
 !JK	f  fr   