
    j                       U d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZmZ dZ ej"                  e      Z eh d      Z ej,                  d	      Zd
d
d
d
dZded<    ej,                  d      Z G d de      Z G d de      Zd"dZd#dZd$dZded	 	 	 	 	 	 	 	 	 d%dZ  G d de      Z! G d de      Z"	 	 	 	 	 	 d&dZ#d'dZ$ G d de      Z% G d  d!e      Z&y)(z;Thin Telegram transport contracts for nutrition onboarding.    )annotationsN)StrEnum)Self)	BaseModel
ConfigDictFieldmodel_validatorz2.0>   routeingressreceipt	authority
validationpersistencepublicationz^[a-z][a-z0-9_]{0,63}$ )activity_rationalecooking_accessbudget_bandschedule_constraintszdict[str, object]OPTIONAL_QUESTION_DEFAULTSz^[a-z][a-z0-9_-]{0,11}$c                       e Zd Z edd      Zy)TransportModelforbidT)extrafrozenN)__name__
__module____qualname__r   model_config     n/home/cube/projects/richard/.worktrees/nutricoach-v140-impl/gateway/platforms/telegram_nutrition_onboarding.pyr   r   (   s    HT:Lr!   r   c                  P    e Zd ZU ded<    ed      Zded<    ed      Zded	<   y
)CallbackTokenstractionr   geint
generationz^[A-Za-z0-9_-]{43}$patternsession_hashN)r   r   r   __annotations__r   r*   r-   r    r!   r"   r$   r$   ,   s%    KqkJ!&<=L#=r!   r$   c                    t        j                  |j                  d            j                         }t	        | ||      S )Nutf-8)r&   r*   sid_hash)hashlibsha256encode	hexdigestencode_callback_hash)r&   r*   
session_iddigests       r"   encode_callbackr9   2   s:    ^^J--g67AACF r!   c                   t         j                  |       st        d      |dk  rt        d      t        j                  d|      st        d      t        j                  |      }t        j                  |      j                  d      j                  d      }d|  d	| d	| }t        |j                  d
            dkD  rt        d      |S )Nz"invalid onboarding callback actionr   &invalid onboarding callback generationz[0-9a-f]{64}z(invalid onboarding callback session hashascii=znon2::r0   @   z*onboarding callback exceeds Telegram limit)_ACTION	fullmatch
ValueErrorrebytesfromhexbase64urlsafe_b64encodedecoderstriplenr4   )r&   r*   r1   r8   r-   callbacks         r"   r6   r6   ;   s    V$=>>A~ABB<<2CDD]]8$F++F3::7CJJ3OLvha
|1\N;H
8??7#$r)EFFOr!   c                X   | j                  d      }t        |      dk(  r|d   dk(  rt        d      t        |      dk7  s |d   dk7  st        j	                  |d         st        d      	 t        |d	         }t        |d   ||d         S # t        $ r}t        d
      |d }~ww xY w)Nr>      r   non1z)historical onboarding callback is expirednon2   zinvalid onboarding callback   r;      )r&   r*   r-   )splitrJ   rB   r@   rA   r)   r$   )valuepartsr*   excs       r"   decode_callbackrW   J   s    KKE
5zQ58v-DEE
5zQ%(f,G4E4EeAh4O677Lq]
 Qx1X   LABKLs   -B 	B)B$$B))reason_codeloggerc                  | t         vrt        d      t        |      t        u r|dk\  rt	        |      nd}||j                  d| |       yt        j                  |      st        d      |j                  d| ||       y)zBEmit the bounded, content-free audit record for nutrition ingress.zinvalid nutrition ingress stager   unknownNz'nutrition_ingress stage=%s update_id=%sz%invalid nutrition ingress reason codez6nutrition_ingress stage=%s update_id=%s reason_code=%s)_INGRESS_STAGESrB   typer)   r%   info_REASON_CODErA   )stage	update_idrX   rY   safe_update_ids        r"   log_ingress_stagerc   [   s     O#:;; 	?c!i1n 	I 
 5	

 	!!+.@AA
KK@	r!   c                  f    e Zd ZU ded<   ded<   ded<   ded<    ed      Zded<   d	ed
<   ded<   y)IngressEvidencer)   actor_user_idchat_idtopic_id
message_idr   r'   r*   r%   r&   boolmember_presentN)r   r   r   r.   r   r*   r    r!   r"   re   re   {   s0    LMOqkJ!Kr!   re   c                  0    e Zd ZU ded<   ded<   dZded<   y)IngressDecisionrj   consumedmutateFfallthroughN)r   r   r   r.   rp   r    r!   r"   rm   rm      s    NLKr!   rm   c                D    | |k(  xr |j                   }t        d|d      S NTF)rn   ro   rp   )rk   rm   )expectedactualexacts      r"   authorize_ingressrv      s(    
 86#8#8EDEJJr!   c                    t        ddd      S rr   )rm   )_s    r"   consume_unknown_callbackry      s    DEJJr!   c                      e Zd ZdZdZdZy)PublicationStatePREPARED	COMMITTED	UNCERTAINN)r   r   r   r|   r}   r~   r    r!   r"   r{   r{      s    HIIr!   r{   c                      e Zd ZU  ed      Zded<    ed      Zded<    ed      Zded	<   d
ed<   dZded<   e		 	 	 	 	 	 	 	 dd       Z
 ed      dd       Zedd       ZddZddZddddZy)PublicationAttemptr   r'   r)   r*   z^[0-9a-f]{64}$r+   r%   body_digestbutton_digestr{   stateNz
int | Noneri   c               6     | |||t         j                        S )N)r*   r   r   r   )r{   r|   )clsr*   r   r   s       r"   preparezPublicationAttempt.prepare   s#     !#'"++	
 	
r!   after)modec                    | j                   t        j                  u r| j                  t	        d      | j                   t        j                  ur| j                  t	        d      | S )Nz)committed publication requires message IDz1only committed publication may contain message ID)r   r{   r}   ri   rB   selfs    r"   validate_message_idz&PublicationAttempt.validate_message_id   sW    ::)3338OHII::-777DOO<WPQQr!   c                :    | j                   t        j                  u S )N)r   r{   r|   r   s    r"   requires_sendz PublicationAttempt.requires_send   s    zz-6666r!   c                   | j                   t        j                  urt        d      | j	                  t        j
                  |d      S )Nz$only prepared publication can commit)r   ri   update)r   r{   r|   rB   
model_copyr}   )r   ri   s     r"   commitzPublicationAttempt.commit   sE    ::-666CDD-77zR  
 	
r!   c                    | j                   t        j                  urt        d      | j	                  dt        j
                  i      S )Nz.only prepared publication can become uncertainr   r   )r   r{   r|   rB   r   r~   r   s    r"   mark_uncertainz!PublicationAttempt.mark_uncertain   s>    ::-666MNNw0@0J0J&KLLr!   F)no_side_effect_evidencec                   | j                   t        j                  us|st        d      | j	                  dt        j
                  i      S )Nz/retry requires positive no-side-effect evidencer   r   )r   r{   r~   rB   r   r|   )r   r   s     r"   retryzPublicationAttempt.retry   sA    ::-777?VNOOw0@0I0I&JKKr!   )r*   r)   r   r%   r   r%   returnr   )r   r   )r   rj   )ri   r)   r   r   )r   rj   r   r   )r   r   r   r   r*   r.   r   r   ri   classmethodr   r	   r   propertyr   r   r   r   r    r!   r"   r   r      s    qkJ!%67K7'89M39!J
!
 
 	

 
 

 
 '" # 7 7
M
 8= Lr!   r   )r&   r%   r*   r)   r7   r%   r   r%   )r&   r%   r*   r)   r1   r%   r   r%   )rT   r%   r   r$   )
r`   r%   ra   objectrX   z
str | NonerY   zlogging.Loggerr   None)rs   re   rt   re   r   rm   )rx   r%   r   rm   )'__doc__
__future__r   rF   r2   loggingrC   enumr   typingr   pydanticr   r   r   r	    NUTRITION_ONBOARDING_API_VERSION	getLoggerr   _INGRESS_LOGGER	frozensetr\   compiler_   r   r.   r@   r   r$   r9   r6   rW   rc   re   rm   rv   ry   r{   r   r    r!   r"   <module>r      sP   A "    	   B B $)  #'##H-
 rzz34 	1 -  "**/
0;Y ;>N >* #, 	
  
@n n KK K 	KKw 1L 1Lr!   