+
    j                       a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RI	t^ RI
t^ RIHt R^ RRRR/tR]R	&   ^<tR
 R ltR R lt ! R R]4      tRR R lltR R lt0 RmtRR R lltR R ltR# )u  
catalogo_module.py — Reader read-only do catálogo CE (espelho em six_catalogo no Supabase).

Stack stdlib-only (urllib, json) — sem dependências externas.

Variáveis de ambiente (lê na primeira chamada, cacheia 60s):
  UNI_DATA_SUPABASE_URL ou SUPABASE_URL         → base URL Supabase
  UNI_DATA_SUPABASE_SERVICE_ROLE ou SUPABASE_*  → service role key

Endpoint exposto:
  GET /api/catalogo?tipo=<t>&busca=<q>&apenas_ativos=<bool>&limit=<n>
  tipo ∈ {procedimento, consulta, experiencia, profissional, pacote, produto, todos}

Mapping CE → público (alinhado ao refactor cortesia→experiência):
  category_name = "Cortesias"           → tipo_publico = "experiencia"
  category_name in (Consulta/Avaliação) → tipo_publico = "consulta"
  depends_on_others = true              → tipo_publico = "protocolo"
  default                               → tipo_publico = "procedimento"
)annotationsN)Any	loaded_aturl keydict[str, Any]
_CFG_CACHEc                   V ^8  d   QhRR/# )   returndict[str, str] )formats   "'/opt/apps/studio-api/catalogo_module.py__annotate__r   %   s           c                    \         P                   ! 4       p V \        R,          ,
          \        8  d   \        R,          '       d   \        # \        P                  P                  R4      ;'       g*    \        P                  P                  R4      ;'       g    RP                  R4      p\        P                  P                  R4      ;'       gx    \        P                  P                  R4      ;'       gQ    \        P                  P                  R	4      ;'       g*    \        P                  P                  R
4      ;'       g    Rp\        P                  RV RVRV/4       \        # )u    Lê env vars uma vez por minuto.r   r   UNI_DATA_SUPABASE_URLSUPABASE_URLr   /UNI_DATA_SUPABASE_SERVICE_ROLEUNI_DATA_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLESUPABASE_ANON_KEYr   )timer	   _CFG_TTL_SECosenvirongetrstripupdate)nowr   r   s      r   _configr#   %   s   
))+C
Z$$|3
58I8I


./ 	 	::>>.)	 	fSk	  	

78 	 	::>>67	 	::>>12	 	 ::>>-.	 	   {CUC@Ar   c                   V ^8  d   QhRR/# )r   r   boolr   )r   s   "r   r   r   :   s     + +D +r   c                 \    \        4       p \        V R ,          ;'       d
    V R,          4      # )r   r   )r#   r%   )cfgs    r   
is_enabledr(   :   s$    
)CE
))s5z**r   c                      ] tR t^AtRtR# )CatalogoErrorr   N)__name__
__module____qualname____firstlineno____static_attributes__r   r   r   r*   r*   A   s    r   r*   c               (    V ^8  d   QhRRRRRRRR/# )	r   tablestrquery_paramsr   timeoutintr   zlist[dict[str, Any]]r   )r   s   "r   r   r   E   s/     !G !G !G> !GC !GI] !Gr   c                   \        4       pVR ,          '       d   VR,          '       g   \        R4      h\        P                  P	                  VRR7      pVR ,           RV  RV 2p\        P
                  P                  VRVR,          RR	VR,           2R
RRR/RR7      p \        P
                  P                  WbR7      ;_uu_ 4       pVP                  4       P                  R4      pV'       d   \        P                  ! V4      M. uuRRR4       #   + '       g   i     R# ; i  \        P                  P                   db   p	Rp
 T	P                  4       P                  RRR7      R,          p
M  \         d     Mi ; i\        RT	P                   RT  RT
 24      T	hRp	?	i\        P                  P                    d"   p	\        RT  RT	P"                   24      T	hRp	?	ii ; i)r   r   zQCredenciais Supabase ausentes (UNI_DATA_SUPABASE_URL/SERVICE_ROLE ou SUPABASE_*).,)safez	/rest/v1/?apikeyAuthorizationzBearer Acceptzapplication/jsonzAccept-Profilesix_catalogoGET)headersmethod)r4   zutf-8Nr   ignore)errors:Ni,  NzHTTP z em z: zURLError em )r#   r*   urllibparse	urlencoderequestRequesturlopenreaddecodejsonloadserror	HTTPError	ExceptioncodeURLErrorreason)r1   r3   r4   r'   qsr   reqrespbodyeerrs   &&&        r   _getrY   E   s   
)Cu::SZZ_
 	
 
		3		7BZL	%"
.C
..
 
 c%jws5zl3(n	
  ! 	CG^^##C#99T99;%%g.D'+4::d# :999 <<!! G	&&(//'(/;DAC 		eAFF84wb>?QF<<   Gl5'AHH:>?QFGsl   "(D( 
?D	
D( D%	D( %D( (G&F#
(E32F#3F>F# F"F## G&G&G!!G&c               $    V ^8  d   QhRRRRRR/# )r   category_namez
str | Nonedepends_on_othersr%   r   r2   r   )r   s   "r   r   r   k   s!      
 t  r   c                    T ;'       g    R P                  4       P                  4       pVR9   d   R# VR9   d   R# V'       d   R# R# )r   consultaexperiencia	protocoloprocedimento)r^   u   avaliação	avaliacao)	cortesiascortesia)striplower)r[   r\   cats   && r   _classificarrh   k   sB    B
%
%
'
-
-
/C
66
''r   c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r   tipor2   buscaapenas_ativosr%   limitr5   r   r   r   )r   s   "r   r   r      sH     KT KT
KTKT KT 	KT
 KTr   c           
        T ;'       g    RP                  4       P                  4       pV\        9  d/   \        RV RRP	                  \        \        4      4       R24      h\        ^\        \        T;'       g    ^24      R4      4      pT;'       g    RP                  4       pVR8X  dN   R	R
R\        V4      /pV'       d   RVR&   V'       d   RV RV R2VR&   \        RV4      pRVR\        V4      RV/# VR8X  dy   R	RR\        V4      /pV'       d   RVR&   V'       d
   RV R2VR&   \        RV4      pV F(  pVP                  R4      ;'       g    ^ ^d,          VR&   K*  	  RVR\        V4      RV/# VR8X  dy   R	RR\        V4      /pV'       d   RVR&   V'       d
   RV R2VR&   \        R V4      pV F(  pVP                  R4      ;'       g    ^ ^d,          VR&   K*  	  RVR\        V4      RV/# R	R!R\        VR8w  d
   V^,          MT4      /pV'       d   RVR&   V'       d
   RV R2VR&   \        R"V4      p. p	V Fp  p\        VP                  R#4      \        VP                  R$4      4      4      p
WR%&   VP                  R4      ;'       g    ^ ^d,          VR&   V	P                  V4       Kr  	  VR8w  d)   V	 Uu. uF  qP                  R%4      V8X  g   K  VNK  	  p	pV	R&V p	RVR\        V	4      RV	/# u upi )'z
Retorna {tipo, total, items: [...]} pronto pra serializar JSON.

Levanta CatalogoError em caso de problema (capture no handler).
todosu   Tipo inválido: 'z'. Use: z, .i  r   profissionalselectz8ce_id,name,short_name,specialty,registro,category,activerm   zeq.trueativo_cez(name.ilike.*z*,short_name.ilike.*z*)orprofissionaisrj   totalitemspacotezce_id,description,cents,activezilike.**descriptionpacotescentspreco_reaisprodutoz"ce_id,description,sku,cents,activeprodutoszdce_id,description,category_name,depends_on_others,cents,duration_min,active,enabled_professional_idsprocedimentosr[   r\   tipo_publicoN)re   rf   _TIPOS_VALIDOSr*   joinsortedmaxminr5   r2   rY   lenr   rh   r%   append)rj   rk   rl   rm   	tipo_norm
busca_normparamsrowsrclassificadosclsis   &&&&        r   listarr      s$    '')//1I&/	{(499VTbMcCdBeefghh3s5;;B'-.E++2$$&J N"VX_adejakl!*F:*:,6J:,VXYF4LOV,	7CIwEE H<gs5zR!*F:&-j\$;F=!Iv&A !g 3 3!s:Am 	7CIwEE I@'3u:V!*F:&-j\$;F=!J'A !g 3 3!s:Am 	7CIwEE
 	x)w"6UQYEBF &z")*Q 7}(D*,M15514>Q8R3ST.EE'N//a36-Q	  G$1XMqUU>5Ji5WMX!&5)MIwM(:G]SS Ys   K=K=c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r      s     5 5^ 5r   c            	          \        RRRRRRR/4      p V '       g   RR	R
R/# RRRV ^ ,          /#   \         d   pRR	R\        T4      /u Rp?# Rp?ii ; i)uH   Retorna info do último sync_runs (pra debug/UI mostrar 'última sync').	sync_runsrr   ry   orderzstarted_at.descrm   1	availableFmessageu%   Sync nunca rodou — renove token CE.TlastrM   N)rY   r*   r2   )r   rW   s     r   sync_statusr      sp    	5sG%6E
 	3Z[[T64733 5UGSV445s   / / AAAA)   >   ro   rx   r~   r^   r`   r_   ra   rq   )ro   r   T2   )__conditional_annotations____doc__
__future__r   rK   r   r   urllib.errorrC   urllib.parseurllib.requesttypingr   r	   __annotations__r   r#   r(   rO   r*   rY   rh   r   r   r   )r   s   @r   <module>r      sy   ( #  	      *1eRC
N C*+	I 	!GL	KT\5r   