+
    3oj&!                        R t ^ RIH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HtHt ^ RIHt ^ RIHt ^ R	IHt ]! R
R.R7      t]P7                  R4      ]
! R^R7      ]
! R^R7      ]
! R^R7      RRR]
! ^^R7      ]
! ^2^^R7      3R R ll4       t]P7                  R4      R R l4       t]P7                  R4      R R l4       t]P?                  R4      RR R ll4       t R# )uy  Arquivo nacional da Distribuição: consulta e recruzamento.

Ao contrário da `/processes`, que é a vista das empresas monitorizadas, isto é o
arquivo cru — tudo o que os 197 tribunais distribuíram, dê ou não match. É o que
permite responder "e no mês passado?" sobre uma empresa que só hoje passou a
interessar, sem depender dos ~180 dias que o CITIUS ainda serve.
)date)	AnnotatedAny)	APIRouterDependsHTTPExceptionQuerystatus)text)AsyncSession)CurrentUsercurrent_userrequire_admin)get_sessionrematch_all)normalize_namez/court-filingszcourt-filings)prefixtags N)default
max_lengthF)r   ge)r   r   lec                l   V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R,          R\        R,          R\        R,          R\        R,          R\        R,          R	\        R
\        R\        R\        \        \        3,          /# )   session_userqNtribunalespeciedesdeateso_com_acertopage	page_sizereturn)r   r   r   r   r   r   strr   boolintdictr   )formats   "app/api/court_filings.py__annotate__r-      s     OW OW|W[%99:OW[',"778OW TzOW Dj	OW
 4ZOW $;OW 
OW OW OW OW 
#s(^OW    c
                  "   . p
/ pV'       d7   V
P                  R4       RVP                  4        R2VR&   \        V4      VR&   V'       d   V
P                  R4       W;R&   V'       d   V
P                  R4       WKR&   V'       d   V
P                  R	4       W[R
&   V'       d   V
P                  R4       WkR&   V'       d   V
P                  R4       V
'       d   RRP                  V
4       2MRpV P	                  \        RV 24      V4      G Rj  xL
 P                  4       pWR&   V^,
          V	,          VR&   V P	                  \        RV R24      V4      G Rj  xL
 P                  4       P                  4       p. pV FW  p\        V4      pVR,          e   \        VR,          4      MRVR&   VR,          ;'       g    . VR&   VP                  V4       KY  	  RVR\        V4      RVRV	/#  L L5i)uJ   Pesquisa no arquivo. `q` procura por nome de parte ou número de processo.z(f.process_number ILIKE :qlike OR EXISTS ( SELECT 1 FROM court_filing_parties p  WHERE p.filing_id = f.id AND p.name_norm % :qnorm))%qlikeqnormzf.tribunal = :tribunalr   zf.especie = :especier    zf.data_distribuicao >= :desder!   zf.data_distribuicao <= :ater"   zCEXISTS (SELECT 1 FROM court_filing_hits h WHERE h.filing_id = f.id)zWHERE z AND r   z%SELECT count(*) FROM court_filings f NlimoffaC  
                SELECT f.id::text, f.process_number, f.tribunal, f.unorganica,
                       f.especie, f.valor, f.data_distribuicao, f.data_entrada,
                       f.observacoes,
                       (SELECT count(*) FROM court_filing_parties p
                         WHERE p.filing_id = f.id) AS n_partes,
                       (SELECT count(*) FROM court_filing_hits h
                         WHERE h.filing_id = f.id) AS n_acertos,
                       (SELECT json_agg(json_build_object(
                                  'name', p.name, 'role', p.role, 'nif', p.nif)
                                ORDER BY p.role NULLS LAST, p.name)
                          FROM court_filing_parties p
                         WHERE p.filing_id = f.id) AS partes
                FROM court_filings f
                z
                ORDER BY f.data_distribuicao DESC NULLS LAST, f.first_seen_at DESC
                LIMIT :lim OFFSET :off
                valorpartesitemstotalr$   r%   )appendstripr   joinexecuter
   
scalar_onemappingsallr*   floatr)   )r   r   r   r   r    r!   r"   r#   r$   r%   whereparamsclauser8   rowsr7   ritems   &&&&&&&&&&        r,   search_filingsrG      s     EF 	D	

 aggi[*w(+w-.%z+,#y45w
23uZ[/4vgll5)*+"F oo8ABF
 	
 jl	 

 5MAX*F5Moo  ( +
 	
. hj1 	2 EAw04W0Id7m,tWh--2XT	 
 UGSZ{IVVK	
	
sP   A
G4G4*G4G4$G4G47G4G0AG4G2A#G4/G42G4z/facetsc                    V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        \        \        3,          /# )r   r   r   r&   )	r   r   r   r   r   r   r*   r'   r   )r+   s   "r,   r-   r-   k   sL     & &|W[%99:&[',"778& 
#s(^&r.   c                   "   V P                  \        R4      4      G Rj  xL
 P                  4       pV P                  \        R4      4      G Rj  xL
 P                  4       pV P                  \        R4      4      G Rj  xL
 P                  4       P	                  4       pRV UUu. uF  w  rVRVRV/NK  	  uppRV UUu. uF  w  rvRVRV/NK  	  uppR	\        T;'       g    / 4      /#  L L Lou uppi u uppi 5i)
uC   Os valores que a fonte usa, para os filtros não serem adivinhados.zVSELECT tribunal, count(*) AS n FROM court_filings GROUP BY 1 ORDER BY 2 DESC LIMIT 250NzoSELECT especie, count(*) AS n FROM court_filings WHERE especie IS NOT NULL GROUP BY 1 ORDER BY 2 DESC LIMIT 120a(  
                SELECT count(*) AS total,
                       min(data_distribuicao) AS mais_antigo,
                       max(data_distribuicao) AS mais_recente,
                       (SELECT count(*) FROM court_filing_hits) AS acertos
                  FROM court_filings
                	tribunaisr5   nespeciesresumo)r<   r
   r?   r>   firstr*   )r   r   rJ   rL   rM   trK   es   &&      r,   filing_facetsrQ   j   s     oo8
 	
 
ce  ooR
 	
 
ce  oo

 
	
 hj  	yAytqw3*yAh?hdagq#q)h?$v||$ 9	
	

	
 B?sW   C>C,/C>C./C> C0&C>'C28	C>C8C>$	C>.C>0C>2C>z/{filing_id}c          
          V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \
        \        \        4      3,          R\        \         \        3,          /# )r   	filing_idr   r   r&   )	r'   r   r   r   r   r   r   r*   r   )r+   s   "r,   r-   r-      sV     ; ;;|W[%99:; [',"778; 
#s(^	;r.   c                  "   VP                  \        R4      RV /4      G Rj  xL
 P                  4       P                  4       pV'       g   \	        \
        P                  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 /4      G Rj  xL
 P                  4       P                  4       p\        V4      pVR,          e   \        VR,          4      MRVR&   V Uu. uF  p\        V4      NK  	  upVR	&   V Uu. uF  p\        V4      NK  	  upVR
&   V#  EL1 L Lu upi u upi 5i)u4  Um processo do arquivo, com todas as partes e o que o cruzamento decidiu.

Os acertos vêm com o `match_kind`: quem foi identificado pelo NIF resolvido
contra o registo comercial e quem foi só pelo nome. É a diferença entre uma
certeza e uma semelhança, e quem lê a página tem direito a saber qual é.
a-  
                SELECT id::text, process_number, tribunal, unorganica, especie,
                       valor, valor_raw, data_distribuicao, data_entrada,
                       observacoes, first_seen_at, last_seen_at
                  FROM court_filings WHERE id = CAST(:id AS UUID)
                idNu   não encontrado)status_codedetailzSELECT id::text, name, role, nif, nif_source FROM court_filing_parties WHERE filing_id = CAST(:id AS UUID) ORDER BY role NULLS LAST, namea  
                SELECT h.id::text, h.match_kind, h.matched_role, h.matched_nif,
                       c.id::text AS company_id, c.legal_name, c.monitoring_type, c.nif,
                       p.name AS party_name
                  FROM court_filing_hits h
                  LEFT JOIN companies c ON c.id = h.company_id
                  LEFT JOIN court_filing_parties p ON p.id = h.party_id
                 WHERE h.filing_id = CAST(:id AS UUID)
                r5   r6   acertos)
r<   r
   r>   rN   r   r	   HTTP_404_NOT_FOUNDr?   r*   r@   )	rS   r   r   linhar6   rX   rF   pas	   &&&      r,   filing_detailr]      sU     oo 9

 
	
 hj 
 (A(AJ[\\ oo2
 9
 	
 hj  oo
 9
 	
 hj " ;D,0M,EE$w-(4DM'-.v!d1gv.DN(/01tAw0DOK_
	
 	
	
$ /0sY   !E%E'E%;E%EA E%E	AE%E.
E%8E 	E%E%E%
E%z/rematchc          
          V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R,          R\        \        \        3,          /# )r   r   _adminr!   Nr&   )
r   r   r   r   r   r   r   r*   r'   r)   )r+   s   "r,   r-   r-      sZ     3 3|W[%99:3k7=#99:3 $;3 
#s(^	3r.   c                6   "   \        WR7      G Rj  xL
 #  L5i)u  Reaplica o cruzamento ao arquivo.

É o que se corre quando entra uma empresa nova ou quando a regra de
correspondência muda: sem isto, uma falha de correspondência era silenciosa e
definitiva, porque a linha tinha sido deitada fora no momento da recolha.
)sinceNr   )r   r_   r!   s   &&&r,   rematchrb      s      W2222s   )N)!__doc__datetimer   typingr   r   fastapir   r   r   r   r	   
sqlalchemyr
   sqlalchemy.ext.asyncior   app.auth.depsr   r   r   app.dbr   app.services.court_filingsr    app.services.registry_act_parserr   routergetrG   rQ   r]   postrb    r.   r,   <module>rq      s     ! D D  / B B  2 ;	*/1B	C B $37 #>=aA&2!4OW OWd I& &R N; ;| Z3 3r.   