+
    =qj\                        ^ RI t ^ RIt^ RIt^ RIHtHtHtHt ^ RIH	t	H
t
 ^ RIHtHt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Ht ^ R	IHt ^ R
IHtH t H!t! ^ RI"H#t#H$t$ ^ RI%H&t& ^ RI'H(t( ^ RI)H*t* ^ RI+H,t, ]! RR.R7      t- ! R R]4      t.]-P_                  R4      ]! RRR7      R]! RR7      3R R ll4       t0]-Pc                  R4      R R l4       t2]-Pc                  R]3]&,          R 7      RCR! R" ll4       t4]-P_                  R#]$R 7      ]! R4      3R$ R% ll4       t5]-Pc                  R&4      RDR' R( ll4       t6R) R* lt7]-Pc                  R+4      R, R- l4       t8]-Pc                  R.4      R/ R0 l4       t9]-Pc                  R14      RER2 R3 ll4       t:]-P_                  R44      R5 R6 l4       t;R7 R8 lt<]-Pc                  R94      RER: R; ll4       t= ! R< R=]4      t> ! R> R?]4      t?]-P_                  R@4      RERA RB ll4       t@R# )F    N)datedatetime	timedeltatimezone)	AnnotatedAny)	APIRouterBodyDependsHeaderHTTPExceptionPathstatus)	BaseModel)text)AsyncSession)CurrentUserrequire_admin)get_session)list_scheduled_jobsschedule_backfill_for_companytrigger_manual_scrape)RaciusImportItemRaciusImportResult)ScrapingLogOut)parse_mj_html)extract_people)is_valid_nifz/adminadmin)prefixtagsc                   H   a  ] tR t^t o RtRtRtRtRtRt	Rt
V 3R ltRtV tR# )ScrapeOptionsNc                   < V ^8  d   Qh/ S[ R,          ;R&   S[ R,          ;R&   S[R,          ;R&   S[S[,          R,          ;R&   S[R,          ;R&   S[R,          ;R&   S[R,          ;R&   # )	   N	date_fromdate_todaystypesmax_days	max_itemsmax_seconds)r   strlistintfloat)format__classdict__s   "app/api/admin.py__annotate__ScrapeOptions.__annotate__   s}     d{! D[  *  9t"	  Dj  Tz   $      )__name__
__module____qualname____firstlineno__r&   r'   r(   r)   r*   r+   r,   __annotate_func____static_attributes____classdictcell__r2   s   @r3   r#   r#      s/     !IGD"EH I $K  r6   r#   z/scrape/{source}.z^(distribuicao|distribuicao_backfill|cire|ptdata|dre|contracts|registry_sweep|registry_expand|registry_content|registry_nacional)$)patterndefaultc          
          V ^8  d   QhR\         R\        \        \        \        4      3,          R\
        R,          R\        \         \         3,          /# )r%   source_adminoptionsNreturn)r-   r   r   r   r   r#   dict)r1   s   "r3   r4   r4   (   sL     2 22k7=#99:2 T!2 
#s(^	2r6   c                 x   "   V'       d   VP                  R R7      M/ p\        W4      G Rj  xL
 pRV RV/#  L
5i)T)exclude_noneNrD   task_id)
model_dumpr   )rD   rE   rF   optsrK   s   &&&  r3   
scrape_nowrN   '   s?      5<740D)&77Gfi11 8s   +:8:z/scheduled-jobsc                    V ^8  d   QhR\         \        \        \        4      3,          R\        \
        \        \        3,          ,          /# )r%   rE   rG   )r   r   r   r   r.   rH   r-   object)r1   s   "r3   r4   r4   3   s9     ! !k7=#99:!	$sF{
!r6   c                   "   \        4       # 5i)z4List all APScheduler jobs with their next run times.)r   rE   s   &r3   scheduled_jobsrS   2   s     
   s   z/scraping-logs)response_modelc          	          V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R\        \        ,          /# r%   sessionrE   limitrG   )	r   r   r   r   r   r   r/   r.   r   )r1   s   "r3   r4   r4   ;   sS      |W[%99:k7=#99:  
.	r6   c                   "   V P                  \        R 4      RV/4      G Rj  xL
 P                  4       pV Uu. uF  p\        V^ ,          V^,          V^,          V^,          V^,          V^,          ;'       g    ^ V^,          ;'       g    ^ V^,          V^,          V^	,          ;'       g    ^ V^
,          ;'       g    ^ R7      NK  	  up#  Lu upi 5i)a  
                SELECT id::text, source, started_at, finished_at, status,
                       rows_seen, rows_new, error, params,
                       progress_current, progress_total
                FROM scraping_logs ORDER BY started_at DESC LIMIT :lim
                limN)idrD   
started_atfinished_atr   	rows_seenrows_newerrorparamsprogress_currentprogress_total)executer   allr   rW   rE   rX   rowsrs   &&&  r3   scraping_logsri   :   s      oo EN

 
	
 
ce 	&  A 	tAaDQqTqtAaDdiia!A$))!1Q4!qTYYQquzz	

  
	
s9   !CCCAC<C!C0CCCCz/racius-importc                    V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        \        ,          R\        /# )r%   rW   rE   itemsrG   )	r   r   r   r   r   r   r.   r   r   )r1   s   "r3   r4   r4   X   sT     2 2|W[%99:2k7=#99:2  !2 	2r6   c                <  "   . p. p. pV EFo  p\        VP                  4      '       g"   VP                  RVP                  RR/4       K@  V P                  \	        R4      RVP                  /4      G Rj  xL
 P                  4       pV'       d"   VP                  RVP                  RR/4       K  V P                  \	        R4      RVP                  R	VP                  R
VP                  RVP                  /4      G Rj  xL
 P                  4       pV P                  4       G Rj  xL
  VP                  VP                  4       \        V^ ,          VP                  4       VP                  V^ ,          4       EKr  	  \        W4\        V4      R7      #  EL  L Lt5i)uX  Bulk-import closed/insolvent competitors from Racius. Each row lands as
monitored=TRUE, active=FALSE (one-shot historical scrape only). After insert,
the per-company backfill is scheduled — 180d distribuicao + all CIRE — so
we capture the credor/executado footprint without enrolling the company in
the daily cron (active=FALSE gates that).nifreasonzinvalid NIF checksum-SELECT id::text FROM companies WHERE nif = :nnNzalready existsa  
                    INSERT INTO companies (nif, legal_name, status, monitored, active,
                                           monitoring_type)
                    VALUES (:nif, :legal, :status, TRUE, FALSE, :mt)
                    RETURNING id::text
                    legalr   mt)insertedskippedtotal_scheduled_backfills)r   rm   appendrd   r   first
legal_namer   monitoring_typecommitr   r   len)	rW   rE   rk   rs   rt   backfill_idsitemexistingrows	   &&&      r3   racius_importr   W   sj     H$&G LDHH%%NNE488X7MNO//DEdhh  %' 	 NNE488X7GHI// 488T__dkk$..	   %'# 	$ nn!%c!fdhh7CF#E F c,FW =" 	s>   A3F5F6FA/F?F %F%F&A0FFFz/false-positive-reportsc                    V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R\        \        \        \        3,          ,          /# rV   )r   r   r   r   r   r   r/   r.   rH   r-   rP   )r1   s   "r3   r4   r4      s\      |W[%99:k7=#99:  
$sF{
	r6   c                 V  "   V P                  \        R 4      RV/4      G Rj  xL
 P                  4       pV Uu. uF_  pRV^ ,          RV^,          RV^,          RV^,          RV^,          RV^,          R	V^,          R
V^,          RV^,          RV^	,          /
NKa  	  up#  L~u upi 5i)a?  
                SELECT id::text, company_id::text, company_legal_name, process_number,
                       tribunal, source, parties_snapshot, flagged_by_email,
                       flagged_at, reason
                FROM false_positive_reports
                ORDER BY flagged_at DESC LIMIT :lim
                rZ   Nr[   
company_idcompany_legal_nameprocess_numbertribunalrD   parties_snapshotflagged_by_email
flagged_atrn   )rd   r   re   rf   s   &&&  r3   false_positive_reportsr      s      oo EN
 	
 
ce 	*  A !A$ad,@!A$adJ!h!!&8!A$!A$!A$		
  	
s!   !B)B"B)A%B$B)$B)c                0    V ^8  d   QhR\         R\         /# )r%   	root_pathzip_namer-   )r1   s   "r3   r4   r4      s      S C r6   c                 >   ^ RI p^ RIp^ RIHp ^ RIHp V! V 4      pVP                  4       '       g   \        \        P                  RV  R24      hVP                  4       pVP                  VRVP                  4      ;_uu_ 4       pVP                  R4       FF  p	V	P                  4       '       g   K  VP                  V	\!        V	P#                  V4      4      R7       KH  	  RRR4       VP%                  ^ 4       V! VR	R
RV R2/R7      #   + '       g   i     L2; i)r   N)r   )StreamingResponsez/Extension source not found on server (expected z).w*)arcnamezapplication/zipzContent-Dispositionzattachment; filename="")
media_typeheaders)iozipfilepathlibr   fastapi.responsesr   existsr   r   HTTP_404_NOT_FOUNDBytesIOZipFileZIP_DEFLATEDrglobis_filewriter-   relative_toseek)
r   r   r   r   r   r   rootbufzpaths
   &&        r3   _stream_extension_zipr      s    3	?D;;==%%=i[K
 	
 **,C	c7#7#7	8	8AJJsOD||~~c$*:*:4*@&AB $ 
9 HHQK)&*@
!(LM  
9	8s   (D3/DD	z/mj-extension.zipc                X    V ^8  d   QhR\         \        \        \        4      3,          /# r%   rE   r   r   r   r   )r1   s   "r3   r4   r4      s&     Q Qk7=#99:Qr6   c                "   "   \        RR4      # 5i)zzStable per-NIF capturer ZIP. Served from the host-mounted
/app/extension so file edits roll out without a backend rebuild.z/app/extensionzintel-grid-mj-capturer.zipr   rR   s   &r3   mj_extension_zipr      s      !!13OPP   z/mj-extension-bulk.zipc                X    V ^8  d   QhR\         \        \        \        4      3,          /# r   r   )r1   s   "r3   r4   r4      s&     R Rk7=#99:Rr6   c                "   "   \        RR4      # 5i)u   Bulk (beta) extension ZIP — iterates every monitored NIF through
one captcha-backed session. Separate from the stable extension so we
can experiment without affecting the per-NIF flow.z/app/extension-bulkzintel-grid-mj-bulk.zipr   rR   s   &r3   mj_extension_bulk_zipr      s      !!68PQQr   z/mj-monitoredc          	          V ^8  d   QhR\         \        \        \        4      3,          R\         \        R,          \        RR7      3,          R\        \        \        \        3,          ,          /# )r%   rW   x_intel_tokenNX-Intel-TokenaliasrG   )	r   r   r   r   r-   r   r.   rH   r   )r1   s   "r3   r4   r4      sU     " "|W[%99:"S4Zo)FFG" 
$sCx."r6   c                ^  "   \        W4      G Rj  xL
  V P                  \        R4      4      G Rj  xL
 P                  4       pV Uu. uFQ  pRV^ ,          RV^,          RV^,          RV^,          RV^,          '       d   V^,          P	                  4       MR/NKS  	  up#  L Lru upi 5i)zReturn every active internal+competitor NIF the Intel Grid wants
captured, sorted by oldest-last-capture first so successive runs
preferentially refresh the stalest entries.Na  
                SELECT c.id::text, c.nif, c.legal_name, c.monitoring_type,
                       MAX(d.created_at) AS last_captured_at
                FROM companies c
                LEFT JOIN dre_publications d
                       ON d.company_id = c.id AND d.source = 'mj'
                WHERE c.active = true
                  AND c.monitoring_type IN ('internal', 'competitor')
                GROUP BY c.id, c.nif, c.legal_name, c.monitoring_type
                ORDER BY MAX(d.created_at) ASC NULLS FIRST, c.nif
                r[   rm   rx   ry   last_captured_at)_check_mj_tokenrd   r   re   	isoformat)rW   r   rg   rh   s   &&  r3   mj_monitoredr      s      '
111oo

 	
 
ce! 	2 	 A !A$1Q4!A$qtAaDD! 0d	
 	 	% 2	
 	s7   B-B$!B-B&B-
8B(B(!B-&B-(B-z	/mj-tokenc                    V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        \        \        3,          /# )r%   rW   r   rG   )r   r   r   r   r   r   rH   r-   )r1   s   "r3   r4   r4     sL      |W[%99:['-"889 
#s(^r6   c           	     v  "   R\         P                  ! ^ 4      ,           p\        P                  ! \        P
                  R7      \        ^R7      ,           pV P                  \        R4      RVRVP                  RV/4      G Rj  xL
  V P                  4       G Rj  xL
  R	VR
VP                  4       /#  L0 L5i)u   Issue a 24h token the admin embeds in their bookmarklet. Each call
generates a new token and supersedes any previous one for the same user
— simpler than tracking devices. Old tokens still work until they expire
naturally.mj_)tz)hourszy
            INSERT INTO mj_import_tokens (token, user_id, expires_at)
            VALUES (:tok, :uid, :exp)
            tokuidexpNtoken
expires_at)secretstoken_urlsafer   nowr   utcr   rd   r   r[   rz   r   )rW   r   r   expiress   &&  r3   mj_generate_tokenr     s      G))"--Ellhll+ib.AAG
//	
 
uehhw7   ..
g'')  s$   BB9B5B9B7B97B9c                J    V ^8  d   QhR\         R\        R,          R\        /# )r%   rW   r   NrG   )r   r-   )r1   s   "r3   r4   r4   !  s(      *-*r6   c                   "   V'       g   \        \        P                  R 4      hV P                  \	        R4      RV/4      G Rj  xL
 P                  4       pV'       g   \        \        P                  R4      hV^ ,          #  L=5i)missing X-Intel-Tokenz
                SELECT user_id::text FROM mj_import_tokens
                WHERE token = :t AND expires_at > now()
                tNinvalid/expired token)r   r   HTTP_401_UNAUTHORIZEDrd   r   rw   )rW   r   r   s   && r3   r   r   !  s{      F88:QRRoo - 
 	
 eg  F88:QRRq6M	
s   ABBB $Bz/mj-existingc                    V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \         R,          \        RR7      3,          R\        \         \        3,          /# )r%   rm   rW   r   Nr   r   rG   )r-   r   r   r   r   r   rH   r   )r1   s   "r3   r4   r4   7  sZ     ' '	'|W[%99:' S4Zo)FFG' 
#s(^	'r6   c                  "   \        W4      G Rj  xL
  VP                  \        R4      RV /4      G Rj  xL
 P                  4       pV'       g   RRR. /# VP                  \        R4      RV^ ,          /4      G Rj  xL
 P	                  4       pRV^ ,          RV Uu. uF2  pRVP
                  R	VP                  R
\        VP                  4      /NK4  	  up/#  L L L`u upi 5i)u'  Return every MJ publication already captured for this NIF so the
extension can skip re-fetching the detail of rows we already have.
`has_detail` is True when raw_json.detail_body is non-empty — those
rows should be skipped entirely on the next capture run to avoid
hammering publicacoes.mj.pt.Nro   rp   r   rg   a  
                SELECT to_char(date, 'YYYY-MM-DD') AS d,
                       title,
                       COALESCE(length(raw_json->>'detail_body'), 0) > 0 AS has_detail
                FROM dre_publications
                WHERE company_id = :c AND source = 'mj'
                cr   title
has_detail)	r   rd   r   rw   re   dr   boolr   )rm   rW   r   corg   rh   s   &&&   r3   mj_existingr   6  s      '
111oo@A#J
 	
 eg  dFB//oo "Q%L
 	
 
ce 	 	be
 QSS'177L$q||:LM
 / 2	
	

sI   C&C$C&CC&-C&>C? C&8C!
C&C&C&!C&c                   D   a  ] tR tRt o RtRtRtRtRtRt	V 3R lt
RtV tR# )MjImportRowia  Nc                   < V ^8  d   Qh/ S[ R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   # )r%   Nr   rm   entityconcelhoactodetail_htmlr   )r1   r2   s   "r3   r4   MjImportRow.__annotate__a  sg     
* 	t  $J  Dj	 
 *  t" r6   r7   )r8   r9   r:   r;   r   rm   r   r   r   r   r<   r=   r>   r?   s   @r3   r   r   a  s*     DCFHD"K  r6   r   c                   @   a  ] tR tRt o RtRtRtRtRtV 3R lt	Rt
V tR# )MjImportPayloadij  Nc                   < V ^8  d   Qh/ S[ R,          ;R&   S[S[,          R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   S[ R,          ;R&   # )r%   Nhtmlrg   rm   nif_hintr   )r-   r.   r   )r1   r2   s   "r3   r4   MjImportPayload.__annotate__j  s`      * 
 {
d
")  
t  Dj  d
! r6   r7   )r8   r9   r:   r;   r   rg   rm   r   r   r<   r=   r>   r?   s   @r3   r   r   j  s'      D%)DCH!J  r6   r   z
/mj-importc                   V ^8  d   QhR\         \        \        4       3,          R\         \        \	        \
        4      3,          R\         \        R,          \        RR7      3,          R\        \        \        3,          /# )r%   payloadrW   r   Nr   r   rG   )
r   r   r
   r   r   r   r-   r   rH   r   )r1   s   "r3   r4   r4   w  sl     e e./e|W[%99:e S4Zo)FFGe 
#s(^	er6   c           "       "   V'       g   \        \        P                  R4      hVP                  \	        R4      RV/4      G Rj  xL
 P                  4       pV'       g   \        \        P                  R4      hVP                  \	        R4      RV/4      G Rj  xL
  VP                  4       G Rj  xL
  ^ RIHp V P                  ;'       g    V P                  p. pV P                  '       Ed   V P                   EFn  pVP                  pRp	V'       d0   ^ RIHp
 RJ F#  p V
P                  W4      P                  4       p	 M	  VP                   '       d   V! VP                   4      M/ pVP"                  VP$                  VP&                  3 Uu. uF  q'       g   K  VNK  	  ppTP)                  R	VP&                  ;'       g    R
R,          RRP+                  V4      R,          RV	RVP&                  RRRRRVP                  RRVP                  RVP                  RVP"                  RVP$                  RVP&                  RVP-                  R4      RVP-                  R4      //4       EKq  	  M)V P.                  '       d   \1        V P.                  VR7      pV'       g   R^ R ^ R!^ R"R#/# V P2                  pV'       g   TpV'       g,   V F%  pVP-                  R4      '       g   K  VR,          p M	  V'       dE   VP                  \	        R$4      R%V/4      G Rj  xL
 P                  4       pV'       d
   V^ ,          pV'       g   R^ R \5        V4      R!\5        V4      R"R&/# ^ R'IHp ^ p^ pV EFq  pVP-                  R4      pT R(VP-                  R	4      ;'       g    R
P;                  4       P=                  4        R)T;'       g    R
 2p\>        P@                  ! VPC                  R*4      4      PE                  4       pV! VP-                  R	4      VP-                  R4      4      p\G        VP-                  R4      ;'       g    / P-                  R4      4      pTP                  \	        R+4      R,TRVP-                  R	4      ;'       g    R
R-VP-                  R4      R.TR/VP-                  R4      R0VP-                  R4      R1\H        PJ                  ! VP-                  R4      ;'       g    / \L        R27      R3VR4VPN                  R5VPP                  R6V/4      G Rj  xL
 pVP                  4       pRpV'       d+   V^ ,          '       d   V^,          pMV'       d
   V^,          pV'       g   EK   VP                  \	        R74      R3V/4      G Rj  xL
 P                  4       pV'       g   EK>  V^ ,          pVP-                  R4      ;'       g    / P-                  R4      ;'       g    R
p\S        V4       F  pTP                  \	        R84      R9TR,TRVR,          R:VP-                  R;4      R<VP-                  R=4      R>VP-                  R?4      ;'       g    R@RAV/4      G Rj  xL
  VR,          PU                  RB4      '       g   K  VP-                  R;4      '       g   K  VP                  \	        RC4      RVR,          R:VR;,          RD,          /4      G Rj  xL
  K  	  EKt  	  VP                  4       G Rj  xL
  RVREVR \5        V4      V,
          V,
          R!\5        V4      RFVR"RGV RHV RI2/#  EL EL EL  \         d     EK-  i ; iu upi  EL8 EL; EL L L Lg5i)Ka=  Receive HTML scraped by the admin's browser bookmarklet, parse
publication rows, insert into dre_publications with source='mj'.

Auth via X-Intel-Token (short-lived, issued by /admin/mj-token). No
session cookie because the POST comes from publicacoes.mj.pt origin
(cross-origin, no cookies sent per our CORS config).r   z~
                SELECT user_id FROM mj_import_tokens
                WHERE token = :t AND expires_at > now()
                r   Nr   z
            UPDATE mj_import_tokens
            SET last_used_at = now(), uses = uses + 1
            WHERE token = :t
            )parse_detail_html)r   r    :Ni  Nsummaryu    · :Ni  Nr   type
source_urlrD   mjnipcrawrm   r   r   r   detail_fieldsfieldsdetail_bodybody)	nipc_hintrs   rt   parsedmessagezNo publication rows found.ro   rp   z<Could not resolve target company. Pass ?nif= or ?company_id.)classifyz|mj||zutf-8a  
                INSERT INTO dre_publications
                    (company_id, title, summary, date, type, source_url,
                     raw_json, dedup_hash, relevance, change_kind, source)
                VALUES
                    (:cid, :t, :s, :d, :ty, :u, CAST(:r AS JSONB), :h,
                     :rel, :ck, 'mj')
                ON CONFLICT (dedup_hash) DO UPDATE SET
                    summary    = CASE WHEN :has_detail THEN EXCLUDED.summary    ELSE dre_publications.summary    END,
                    raw_json   = CASE WHEN :has_detail THEN EXCLUDED.raw_json   ELSE dre_publications.raw_json   END,
                    relevance  = CASE WHEN :has_detail THEN EXCLUDED.relevance  ELSE dre_publications.relevance  END,
                    change_kind= CASE WHEN :has_detail THEN EXCLUDED.change_kind ELSE dre_publications.change_kind END
                RETURNING (xmax = 0) AS is_insert
                cidsr   tyurh   rA   hrelckr   z;SELECT id::text FROM dre_publications WHERE dedup_hash = :ha  
                            INSERT INTO publication_people
                                (publication_id, company_id, person_nif,
                                 person_name, cargo, event, act_date)
                            VALUES (:pid, :cid, :nif, :nm, :cg, :ev, :dt)
                            ON CONFLICT (publication_id, person_nif) DO UPDATE
                              SET person_name = EXCLUDED.person_name,
                                  cargo       = EXCLUDED.cargo,
                                  event       = EXCLUDED.event,
                                  act_date    = EXCLUDED.act_date
                            pidnmnamecgcargoeveventotherdt5a  
                                INSERT INTO companies
                                    (nif, legal_name, monitoring_type,
                                     monitored, active, status)
                                VALUES (:nif, :nm, 'related', false,
                                        true, 'active')
                                ON CONFLICT (nif) DO NOTHING
                                :N   Nenrichedr   z	Imported z new, enriched z with detail.)z%Y-%m-%dz%d-%m-%Yz%d/%m/%Y)+r   r   r   rd   r   rw   rz   app.services.mj_parserr   rm   r   rg   r   r   strptime
ValueErrorr   r   r   r   rv   joingetr   r   r   r{   app.services.dre_classifierr   striplowerhashlibsha256encode	hexdigestr   _jsondumpsr-   	relevancechange_kindr   
startswith)r   rW   r   tok_rowr   r   rk   rh   r   parsed_date_dtfmtdetailpsummary_parts
target_cid
target_nifitr   r   rs   r  keyr  clsr   respub_idpub_rowr   s   &&&                           r3   	mj_importr2  v  s     F88:QRRoo - 
 	
 eg  F88:QRR
//	
 
m	 	 	 ..
 9//w//I"$E|||AAK4?C!&)ll1&:&?&?&A @ :;&q}}5BF *+1::qvv(FL(F1!QQ(FMLLL!&&,,B-6;;}5e<d$AFF155ahh

AFF#VZZ%9!6::f#5 ! D 
glli@Ay!Xq)Eabb %//J
66&>>!#FJ  ooHI*%  eg   V
Ay#e*hE
Y[ 	[ 5HHFF6ND"&&/"7"7R!>!>!@!F!F!H I177PR)TNN3::g./99;rvvgy(9:266%=..B33MBC
OO" zRVVG_**RVVI&QbffVnRVVL)U[[!4!4"cBQs}}cooj#
 
> iik1vvAA :ooVW!H  eg  w !vve}2277FLL"'4A!//
  "6!:!1U8 !%%- !%%. !%%.";";G !  : x**3//AEE&MM%oo !$	 #AeHdAfIdOD  ? 5w N ..
HH3u:(83#e*jYxjzO a	
	 $ & ! ! MJ4
Z< s  A]%\5]% :]%\8]%2\;3]%!]%21]%$\>]%9]%	] ]& ]%B<]%]%#]%	]%]%)]%> ]%]]%9]%
A]%"(]%A;]%A]%A]%-1]%]]%=]%]%]%2 ]%]]%0 ]%]%*A-]%]%%]&]%
]%#7]%]! ]%;]#<:]%8]%;]%>]	]%]	]%]%]%]%!]%#]%)d   )r  )N)Ar  jsonr  r   r   r   r   r   typingr   r   fastapir	   r
   r   r   r   r   r   pydanticr   
sqlalchemyr   sqlalchemy.ext.asyncior   app.auth.depsr   r   app.dbr   app.jobs.schedulerr   r   r   app.schemas.companyr   r   app.schemas.processr   r  r   app.services.mj_people_parserr   app.services.nifr   routerr#   postrN   r  rS   r.   ri   r   r   r   r   r   r   r   r   r   r   r   r2  r7   r6   r3   <module>rC     s      8 8 ! Q Q Q   / 4  
 E . 0 8 )	('	3%I %  s  %i  j=A$($62 !2 ! ! T.-AB C8 .@A %)I2 B2j %& 'L2  Q !Q $%R &R O" "J [ 4* N' 'T#) #	"i 	" \e er6   