
    qn[j              
         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ZddlZddl	Z	ddl
Z
ddlZddlmZmZ ddlmZ ddlmZ ddlmZ 	 ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZm Z!  ejR                         dz  dz  dz  Z*e*dz  jO                         Z+ejX                  j[                  d      r# eejX                  d         jO                         ndZ. eejX                  j[                  d e%e*dz  dz                    jO                         Z/ eejX                  j[                  d e%e*dz  dz                    jO                         Z0ejX                  j[                  d      r# eejX                  d         jO                         ndZ1 ee&      jO                         jP                  Z2e2dz  Z3e2dz  Z4e2dz  Z5dZ6 ejn                  d      Z8 ed      Z9dZ:d Z; e<e:e;h      Z= e<h d!      Z> e<h d"      Z? e<h d#      Z@ e<h d$      ZAd%ZBdNd&ZC eCejX                  j[                  d'            ZDdOd(ZEdPd)ZFdPd*ZGdQd+ZHd,d-dRd.ZIdPd/ZJdSd0ZKdTd1ZLdUd2ZMdVd3ZNdWd4ZOdXd5ZPdYd6ZQdZd7ZRd[d8ZSd9d:d:d:d:d:d:d:d;d<	ZTd\d=ZUd]d>ZVd]d?ZWd^d@ZXd_dAZYd`dBZZd]dCZ[dadDZ\dadEZ]dbdFZ^dQdGZ_dcdHZ`dadIZadddedJZbdfdKZcdgdLZdeedMk(  r ef ed             y# e"$ rf ejF                  jI                  d e% ee&      jO                         jP                               ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZm Z! Y w xY w)hzLConsume locally queued Dashboard actions outside the network-facing service.    )annotationsN)datedatetime)Path)Any)ZoneInfo)REQUIRED_PATIENT_ACTION_COLUMNS)assert_supplement_schema)validate_supplement_payload)TRANSITIONSvalidate_action)METHOD_VERSIONassert_schemaz.hermesassets
Gesundheitzhealth_data.dbHEALTH_DASHBOARD_DBHEALTH_DASHBOARD_ACTION_INBOXruntimezdashboard-actionsHEALTH_DASHBOARD_FILEreportszhealth_dashboard_v4.htmlHEALTH_DASHBOARD_V5_FILEzhealth_symptom_quick_add.pyzhealth_dashboard_v4.pyzhealth_dashboard_v5.py)aphthengifatigueskineyesjointsvascularz[0-9a-f]{32}\.jsonzEurope/Zurichdefaultzhealth-record-6e>   assignignore	composite>   lowhighmedium>   local_aliasmanual_reviewsighi_referenceingredient_label>   unclearunknowndocumented_tolerateddocumented_not_toleratedsighi_mapping_load_v2c                J    | | dk(  rt         n| }|t        vrt        d      |S )zHReturn the one allowed regeneration profile or fail before any mutation. z#invalid HEALTH_DASHBOARD_V5_PROFILE)V5_PROFILE_DEFAULTALLOWED_V5_PROFILESRuntimeError)rawvalues     O/home/agent/.hermes/assets/Gesundheit/scripts/health_dashboard_action_worker.pyparse_v5_profiler7   M   s.    "%+E''@AAL    HEALTH_DASHBOARD_V5_PROFILEc                 P    t        j                  t              j                         S N)r   nowLOCAL_TIMEZONEr    r8   r6   local_todayr?   X   s    <<',,..r8   c           	        t        |       h dk7  rt        d      | d   dk7  s| d   dk7  rt        d      	 t        j                  | d         }|j
                  d
k  s|t               kD  rt        d      | d   t        t              rt              t        t              k7  rt        d      t        fdt        D              rt        d      | d   }t        |t              rt        |      dkD  rt        d      dd|j                         t        D ci c]  }||   
 c}|j                         dS # t        t        f$ r}t        d	      |d }~ww xY wc c}w )N>   r   notesactionscoresversioninvalid payload shaperD      rB   symptom_checkinunsupported actionr   zinvalid date  zdate outside allowed rangerC   zincomplete scoresc              3  j   K   | ]*  }t        |         t        uxs |   t        d       v , yw)   N)typeintrange).0fieldrC   s     r6   	<genexpr>z+validate_symptom_payload.<locals>.<genexpr>p   s<       	VE]3&G&-uQx*GGs   03invalid scorerA   ,  zinvalid notes)rD   rB   r   rC   rA   )set
ValueErrorr   fromisoformat	TypeErroryearr?   
isinstancedictFIELDSanystrlen	isoformatstrip)payloaddayexcrA   rP   rC   s        @r6   validate_symptom_payloadrd   \   s_   
7|   011yQ'("37H"H-..2  1 xx$#-566XFfd#s6{c&k'A,--
   ))GEeS!SZ#%5))#5;<E5&-'<  z" 2(c12& =s   D> E!
>EEEc                   h d}t        |       |k7  rt        d      | d   dk7  s| d   dk7  rt        d      | d   }| d	   }d
j                  t        | d   xs d      j	                               }d
j                  t        | d   xs d      j	                               }| d   }| d   }| d   }d
j                  t        | d   xs d      j	                               }	d
j                  t        | d   xs d      j	                               }
d
j                  t        | d   xs d      j	                               }| d   }t        | d   xs d      }d
j                  t        | d   xs d      j	                               }t        |t              rt        j                  d|      st        d      |t        vs|t        vs|t        vrt        d      d|dfd|dfd|	dfd|
d fd|d!fd"|dffD ]G  \  }}}t        |      |kD  s&t        j                  d#|t        j                        s;t        d$|        |r|	r|
st        d%      |d&k7  r)t        |      t        us|t!        d'      vrt        d(      t        |      t"        urt        d)      |t$        vrt        d*      |d+k(  r|r|d&k(  s|r;t        d,      |d-k(  r|d&k7  s|s$t        d.      |d/k(  r|d&k7  s|s|rt        d0      dd||||||||	|
||||d1S )2N>   notealiasrB   rD   decision	queue_key
confidencesighi_scoresource_labelcanonical_foodmapping_methodsource_versionpersonal_tolerance_notepersonal_tolerance_statusingredient_review_requiredzinvalid mapping payload shaperD   rF   rB   nutrition_mappingrH   rh   ri    rg   r0   rm   rk   rj   rn   rl   ro   rf   rr   rq   rp   [0-9a-f]{32}zinvalid queue keyzinvalid mapping value   zcanonical foodx   zsource labelP   zsource version(   rS   zpersonal tolerance note)[\x00-\x1f\x7f]|https?://|/|\\\\|\.hermeszinvalid z&required mapping documentation missingr+   rK   rR   zinvalid ingredient review flagz!invalid personal tolerance statusr    z9assign requires canonical score without ingredient reviewr"   z6composite must stay unclassified for ingredient reviewr!   zignore must not classify)rD   rB   rh   ri   rg   rm   rk   rj   rn   rl   ro   rf   rr   rq   rp   )rT   rU   joinr]   splitrY   re	fullmatchMAPPING_DECISIONSMAPPING_CONFIDENCEMAPPING_METHODSr^   searchIrL   rM   rN   boolPERSONAL_TOLERANCE_STATUSES)ra   requiredrh   ri   rg   	canonicalscorerj   methodrl   ro   rf   ingredient_reviewtolerance_statustolerance_note
field_nametextmaximums                     r6   validate_mapping_payloadr      s^   H" 7|x899yQ'("37J"J-..z"H$IHHS)/R06689EW%56<"=CCEFIM"E&J%&F88C 7 =2>DDFGLXXc'*:";"ArBHHJKN88C-2.4467D <=7#>?E2FXXc'*C"D"JKQQSTNi%R\\/9-U,--((J>P,PTZbqTq011	%	9c*	r*	>2.	s	"NC8& 	6!
D' t9w")),XZ^`b`d`d"ex
|455	6 NABB	tE{#5eAh9N))d*9::::<==8EY.2CXYY	[	 I%6UVV	X	I.?788%#  $(&7%5#1 r8   c                n   t        | t              st        d      	 t        j                  |       }|j
                  ?|j                  dk  s0|j                  t              t        j                  t              kD  rt        d      |j                  d      S # t        $ r}t        d      |d }~ww xY w)Nzinvalid occurred_atrI   )tzinfominutestimespec)rY   r]   rU   r   rV   r   rX   replacer=   r<   r_   )r5   parsedrc   s      r6   _validate_occurred_atr      s    eS!.//9''. }} FKK$$6&..P^.:_bjbnbno}b~:~.//Y//	  9./S89s   B 	B4#B//B4Fr   c                   t        | t              st        d      dj                  | j	                               }|r|r3t        |      |kD  s%t        j                  d|t        j                        rt        d      |S )Nzinvalid textrt   rz   )	rY   r]   rU   r{   r|   r^   r}   r   r   )r5   r   r   cleaneds       r6   _payload_textr      ss    eS!((hhu{{}%GS\G%;ryyIuw~  AC  AE  AE  @F((Nr8   c                   | j                  d      }|dk(  rh d}t        |       |k7  sW| j                  d      dk7  sC| j                  d      dvs0t        | j                  d            t        us| d   t	        d	      vrt        d
      | d   rt        | d         nd}| d   }|&t        |      t        us
|dk  s|dkD  rt        d      d|t        | d         | d   | d   ||t        | d   d| d   dk(        t        | d   d      d	S |dk(  rh d}t        |       |k7  s'| j                  d      dk7  s| j                  d      dvrt        d      d|t        | d         | d   t        | d   dd       t        | d!   d"      t        | d#   d$      t        | d%   d&      t        | d   d      d'	S |d(k(  rh d)}t        |       |k7  s'| j                  d      dk7  s| j                  d*      d+vrt        d,      | d-   }|)t        |      t        us|t	        d	      vrt        d.      d|t        | d         | d*   t        | d   d/d       |t        | d   d      d0S t        d1      )2NrB   symptom_event>	   labelrA   rB   rD   onset_atseverityoccurred_atsymptom_typeduration_minutesrD   rF   r   >   r   r   r   otherr   aphthaer   headacher   rK   zinvalid symptom eventr   r0   r   r   i`'  zinvalid symptom durationr   r   rx   r   r   rA   rS   )	rD   rB   r   r   r   r   r   r   rA   medication_event>	   doseunitrA   routerB   rD   
event_typer   medication_namer   >   missed	correctedadministeredzinvalid medication eventr   rw   Tr   ry   r      r   <   )	rD   rB   r   r   r   r   r   r   rA   general_event>   r   rA   rB   rD   category	intensityr   r   >   heatr   stresstravel	infectionappointmentphysical_loadsleep_disruptionzinvalid general eventr   zinvalid event intensityd   )rD   rB   r   r   r   r   rA   zunsupported patient action)getrT   rL   rM   rN   rU   r   r   )ra   rB   r   onsetdurationr   s         r6   validate_patient_payloadr      sw   [["F  Fw<8#w{{9'='BgkkR`Fa  ju  Gu  y}  ~E  ~I  ~I  JT  ~U  yV  ^a  ya  el  mw  ex  @E  FG  @H  eH455>Ej>Q%gj&9:WY-.T(^3%>(Q,RZ]bRb788?TU\]jUk?l  F  GU  V  dk  lv  dw  EJ  `h  s@  AH  IP  AQ  SU  `g  hv  `w  {B  `B  sC  N[  \c  dk  \l  nq  Nr  s  	s##zw<8#w{{9'='BgkkR^F_  hO  GO788?TU\]jUk?l  }D  EQ  }R  gt  u|  }N  uO  QT  _c  gd  n{  |C  DJ  |K  MO  nP  Zg  ho  pv  hw  y{  Z|  GT  U\  ]d  Ue  gi  Gj  uB  CJ  KR  CS  UX  uY  Z  	Z bw<8#w{{9'='BgkkR\F]  fL  GL455K(	 d9oS&@IUZ[\U]D]677?TU\]jUk?l  {B  CM  {N  Yf  gn  ov  gw  y|  GK  YL  [d  o|  }D  EL  }M  OR  oS  T  	T
1
22r8   c                
   t        | t              st        d      | j                  d      }|dk(  rt	        |       S |dk(  rt        |       S |dv rt        |       S |dv rt        |       S |dv rt        |       S t        d      )	NrE   rB   rG   rs   >   r   r   r   >   supplement_plansupplement_intake>   observation_statusobservation_upsertobservation_checkinobservation_phase_upsertobservation_result_snapshotrH   )	rY   rZ   rU   r   rd   r   r   r   validate_observation_action)ra   rB   s     r6   validate_payloadr     s    gt$011[["F""'00$$'00GG'0099*733  P  P*733
)
**r8   c                F    i }| D ]  \  }}||v rt        d      |||<    |S )Nzduplicate JSON key)rU   )pairsresultkeyr5   s       r6   reject_duplicate_object_pairsr     s=     "F 
U&=122s Mr8   c                 &   t         j                  ddd       t         j                         } t        j                  | j
                        r!| j                  t        j                         k7  rt        d      t        j                  t         d       y )N  Tmodeparentsexist_okz-action inbox is not a private owned directory)ACTION_INBOXmkdirlstatstatS_ISDIRst_modest_uidosgetuidOSErrorchmod)metadatas    r6   ensure_private_inboxr      sb    E4$?!!#H<<(()X__		-KEFFHH\5!r8   c                   t         j                  | j                        st        d      t	        j
                  | t        j                  t        j                  z        }	 t	        j                  |      }t        j                  |j                        rC|j                  t	        j                         k7  s"t        j                  |j                        dk7  rt        d      |j                  dkD  rt        d      t	        j                   |d      }t	        j"                  |       t%        |      dkD  rt        d      t'        t)        j*                  |j-                  d      t.        	            S # t	        j"                  |       w xY w)
Nzinvalid filename  zinvalid action file permissionsi   zinvalid action filei  zaction too largeutf-8)object_pairs_hook)NAME_REr~   namerU   r   openO_RDONLY
O_NOFOLLOWfstatr   S_ISREGr   r   r   S_IMODEst_sizereadcloser^   r   jsonloadsdecoder   )path
descriptorr   r4   s       r6   load_actionr   (  s   TYY'+,,r{{R]]:;J88J'X--."))+-||H,,-6>??d"233ggj$'

3x$+,,

3::g&:WX  	s   !B2E4 4Fc                   t         t        d      t        j                  t	        t
              dt	        t               d| d|g}t        D ]$  }|j                  d| t	        ||         f       & t        j                  |dddd       t         t        k(  rGt        j                  t        j                  t	        t              d	t	        t              gdddd       y y )
NHEALTH_DASHBOARD_DB is required--dbz--datez--notesz--Trw   checktimeoutcapture_outputr   --output)DASHBOARD_DBr3   sys
executabler]   	QUICK_ADDr[   extend
subprocessrunDEFAULT_DASHBOARD_DBDASHBOARD_V4DASHBOARD_FILE)rb   rC   rA   commandrP   s        r6   apply_symptom_actionr  @  s    <==IL	G  ;"UGc&-&89:;NN7$DtT++^^S.
C<OP	
 ,r8   c                v    d| j                  d      z   }t        j                  |      j                         d d S )Ns   health-nutrition-queue-v1:r       )encodehashlibsha256	hexdigest)normalized_namematerials     r6   nutrition_queue_keyr  Z  s6    ,/E/Eg/NNH>>(#--/44r8   c                    | j                         j                  t        j                  dddddddd            }t	        j
                  dd	t	        j
                  d
d	|            j                         S )Naeoeueeass)   ä   ö   ü   é   è   à   ßz\s+rt   z
[^a-z0-9]+)casefold	translater]   	maketransr}   subr`   )r5   
normalizeds     r6   _normalize_food_identityr)  _  sj    !++
	
J 66&#rvvmS*EFLLNNr8   c                
    |ryy)Nr+   
classifiedr>   )	max_scorer+   loads      r6   _score_labelr.  p  s    r8   c                    	 t        |       }||k(  r|t        d      t        d      hvr|S d S # t        t        f$ r Y y w xY w)Ninfz-inf)floatrW   rU   )r5   numerics     r6   _public_numericr3  v  sS    , (WU5\5QW=<Y-Y7c_cc z" s   . A A kcalgmg)	zenergy.energyznutrient.proteinznutrient.carbznutrient.fatznutrient.fiberznutrient.sugarznutrient.saturatedznutrient.saltznutrient.sodiumc                   |sydj                  d |D              }i }| j                  d| d|      D ]c  }t        |d   xs d      }t        |d   xs d      }t        |d	         }|t        vs|t        |   k7  s|L|j                  |d
      |z   ||<   e t        j                  t        |j                               D ci c]  \  }}|t        |d       c}}d      S c c}}w )Nz{},c              3      K   | ]  }d   yw)?Nr>   )rO   _s     r6   rQ   z#_nutrient_totals.<locals>.<genexpr>  s     2AC2s   z[SELECT nutrient_key,value,unit FROM nutrition_item_nutrients
            WHERE item_id IN ()nutrient_keyr0   r   r5              r8  :)
separators)r{   executer]   r3  NUTRIENT_ALLOWLISTr   r   dumpssorteditemsround)
connectionitem_idsplaceholderstotalsrowr   r   r5   s           r6   _nutrient_totalsrN    s    88222L!F!!+nA	1 
3
 #n%+,3v;$"%G-((D4Fs4K,Ku}jjc*U2s
3 ::fV\\^>TU
UsE%O+UblmmUs   C&
c                   | j                  d      D ci c]I  }t        |t        j                        r|d   n|d   t        |t        j                        r|d   n|d   K }}|r|d   | j	                  d       | j                  d	      D ci c]I  }t        |t        j                        r|d   n|d   t        |t        j                        r|d   n|d   K }}|r|d   | j	                  d
       yyyc c}w c c}w )zMAlign upgraded summary tables with the canonical fail-closed nullable schema.z-PRAGMA table_info(nutrition_daily_summary_v2)r   rF   
dflt_valuerK   histamine_scoreNa  
            ALTER TABLE nutrition_daily_summary_v2 RENAME TO nutrition_daily_summary_v2_s6g_legacy;
            CREATE TABLE nutrition_daily_summary_v2 (
                datum TEXT PRIMARY KEY,
                kcal REAL DEFAULT 0,
                protein_g REAL DEFAULT 0,
                carb_g REAL DEFAULT 0,
                fat_g REAL DEFAULT 0,
                item_count INTEGER DEFAULT 0,
                nutrient_json TEXT,
                histamine_score REAL,
                histamine_max INTEGER DEFAULT 0,
                histamine_unknown_count INTEGER DEFAULT 0,
                histamine_label TEXT DEFAULT 'unknown',
                updated_at TEXT DEFAULT CURRENT_TIMESTAMP
            );
            INSERT INTO nutrition_daily_summary_v2
                (datum,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,histamine_score,
                 histamine_max,histamine_unknown_count,histamine_label,updated_at)
            SELECT datum,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,histamine_score,
                   histamine_max,histamine_unknown_count,histamine_label,updated_at
              FROM nutrition_daily_summary_v2_s6g_legacy;
            DROP TABLE nutrition_daily_summary_v2_s6g_legacy;
            z)PRAGMA table_info(nutrition_meal_summary)ad  
            ALTER TABLE nutrition_meal_summary RENAME TO nutrition_meal_summary_s6g_legacy;
            CREATE TABLE nutrition_meal_summary (
                datum TEXT NOT NULL,
                meal TEXT NOT NULL,
                kcal REAL DEFAULT 0,
                protein_g REAL DEFAULT 0,
                carb_g REAL DEFAULT 0,
                fat_g REAL DEFAULT 0,
                item_count INTEGER DEFAULT 0,
                nutrient_json TEXT,
                histamine_score REAL,
                histamine_label TEXT DEFAULT 'unknown',
                updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (datum, meal)
            );
            INSERT INTO nutrition_meal_summary
                (datum,meal,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,
                 histamine_score,histamine_label,updated_at)
            SELECT datum,meal,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,
                   histamine_score,histamine_label,updated_at
              FROM nutrition_meal_summary_s6g_legacy;
            DROP TABLE nutrition_meal_summary_s6g_legacy;
            )rC  rY   sqlite3Rowexecutescript)rI  rM  daily_defaultsmeal_defaultss       r6   +_ensure_nullable_histamine_summary_defaultsrW    s&   
 %%&UV  #34V#a&(gkk:\	A
GN 
 .):;G  	
: %%&QR  #34V#a&(gkk:\	A
GM 
 '89E  	
 F}K@s   AC:AC?c                   t        |        | j                  d       dddddddddddddddddddddddddddj                         D ]  \  }}| j                  d| d      D ch c]&  }t	        |t
        j                        r|d	   n|d
   ( }}|j                         D ]$  \  }}||vs| j                  d| d| d|        &  | j                  d      j                         }|r-t        t	        |t
        j                        r|d   n|d         nd}|rd|vsd|vr| j                  d       y y y c c}w )Na=	  
        CREATE TABLE IF NOT EXISTS nutrition_mapping_action_log (
            action_id TEXT PRIMARY KEY,
            action_hash TEXT NOT NULL,
            queue_key TEXT NOT NULL,
            decision TEXT,
            alias TEXT,
            canonical_food TEXT,
            sighi_score INTEGER,
            confidence TEXT,
            mapping_method TEXT,
            source_label TEXT,
            source_version TEXT,
            note TEXT,
            ingredient_review_required INTEGER,
            personal_tolerance_status TEXT,
            personal_tolerance_note TEXT,
            definition_version TEXT,
            applied_at TEXT DEFAULT CURRENT_TIMESTAMP
        );
        CREATE TABLE IF NOT EXISTS nutrition_mapping_provenance (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            action_id TEXT NOT NULL,
            normalized_name TEXT NOT NULL,
            decision TEXT,
            alias TEXT,
            canonical_food TEXT,
            sighi_score INTEGER,
            confidence TEXT,
            mapping_method TEXT,
            source_label TEXT,
            source_version TEXT,
            note TEXT,
            ingredient_review_required INTEGER,
            personal_tolerance_status TEXT,
            personal_tolerance_note TEXT,
            definition_version TEXT,
            affected_day TEXT NOT NULL,
            applied_at TEXT DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(action_id, affected_day)
        );
        CREATE TABLE IF NOT EXISTS personal_food_tolerance (
            canonical_food TEXT PRIMARY KEY,
            personal_status TEXT NOT NULL DEFAULT 'unknown'
                CHECK(personal_status IN ('unknown','documented_tolerated','documented_not_tolerated','unclear','safe','problematic')),
            evidence_level TEXT DEFAULT 'user_documented'
                CHECK(evidence_level IN ('low','medium','high','user_documented')),
            notes TEXT,
            updated_at TEXT DEFAULT CURRENT_TIMESTAMP
        );
        CREATE TABLE IF NOT EXISTS nutrition_composite_product_review (
            normalized_name TEXT PRIMARY KEY,
            canonical_food TEXT,
            status TEXT NOT NULL DEFAULT 'needs_ingredient_review'
                CHECK(status IN ('needs_ingredient_review','reviewed')),
            updated_at TEXT DEFAULT CURRENT_TIMESTAMP
        );
        TEXTINTEGER)rh   rg   rm   rk   rj   rn   rl   ro   rf   rr   rq   rp   definition_version)rh   rg   rj   rn   rl   ro   rf   rr   rq   rp   r[  )nutrition_mapping_action_lognutrition_mapping_provenancezPRAGMA table_info(r<  r   rF   zALTER TABLE z ADD COLUMN rt   zSSELECT sql FROM sqlite_master WHERE type='table' AND name='personal_food_tolerance'sqlr   r0   user_documentedr,   a  
            ALTER TABLE personal_food_tolerance RENAME TO personal_food_tolerance_legacy;
            CREATE TABLE personal_food_tolerance (
                canonical_food TEXT PRIMARY KEY,
                personal_status TEXT NOT NULL DEFAULT 'unknown'
                    CHECK(personal_status IN ('unknown','documented_tolerated','documented_not_tolerated','unclear','safe','problematic')),
                evidence_level TEXT DEFAULT 'user_documented'
                    CHECK(evidence_level IN ('low','medium','high','user_documented')),
                notes TEXT,
                updated_at TEXT DEFAULT CURRENT_TIMESTAMP
            );
            INSERT OR REPLACE INTO personal_food_tolerance
                (canonical_food,personal_status,evidence_level,notes,updated_at)
            SELECT canonical_food,
                   CASE
                     WHEN personal_status IN ('unknown','documented_tolerated','documented_not_tolerated','unclear','safe','problematic')
                     THEN personal_status ELSE 'unknown'
                   END,
                   CASE
                     WHEN evidence_level IN ('low','medium','high','user_documented')
                     THEN evidence_level ELSE 'user_documented'
                   END,
                   notes,updated_at
              FROM personal_food_tolerance_legacy;
            DROP TABLE personal_food_tolerance_legacy;
            )	rW  rT  rG  rC  rY   rR  rS  fetchoner]   )	rI  tablecolumnsrM  existingr   declarationpersonal_sqlpersonal_ddls	            r6   ensure_nutrition_mapping_schemarg    s   /
;9	;| 6Zc FFfl)bh'-"()
 vY_"ff*3RX'-"()
 eg[w$ ")),>ugQ*GH
 &c7;;7CKSVC
 
 ") 	[D+8#""\%TF!K=#YZ	[)[. %%]hj  nz3jw{{.S|E*YefgYhi  @BL-!5  	
 6 
s   '+D;c                ,   | d   }t        | d   xs d      j                         }t        | d   xs d      j                         }t        | d   xs d      j                         }t        |      t        usd|cxk  rdk  rn y |r|dvs|t        vry |S )	Nrk   rm   r0   traffic_lightrj   r   r?  >   redgreenorangeyellowr+  )r]   r`   rL   rM   r   )rM  r   r   trafficrj   s        r6   _classified_scorero  ]  s    EC()/R0668I#o&,"-335GS&,"-335JU3EQ
 	 LL//Lr8   c                T   t        | j                  d|f            }| j                  d|f       |s| j                  d|f       y dddddddg t               g d
}i }|D ]  }|d   dv r|d   nd	}|j                  |dddddddg t               g d
      }||fD ]  }|d
xx   dz  cc<   |d   j	                  t        |d                dD ]8  \  }	}
||	   |d   j                  |
        ||
xx   t        ||	         z  cc<   : t        |      }||dxx   dz  cc<   |d   j	                  |       |dxx   |z  cc<     |j                         D ]  \  }}t        |d   xs dg      }t        |t        |d         t        |d               }dD ci c]$  }|||d   v rd nt        t        ||         d      & }}| j                  d|||d   |d   |d   |d   t        |d
         t        | |d         |d   st        |d   d      nd |f
        t        |d   xs dg      }t        |t        |d         t        |d               }| j                  d|d|d   v rd nt        t        |d         d      d|d   v rd nt        t        |d         d      d|d   v rd nt        t        |d         d      d|d   v rd nt        t        |d         d      t        |d
         t        | |d         |d   st        |d   d      nd |t        |d         |f       y c c}w )Na  SELECT i.id,i.meal,i.kcal,i.protein_g,i.carb_g,i.fat_g,
                      h.canonical_food,h.sighi_score,h.traffic_light,h.confidence
               FROM nutrition_items i LEFT JOIN nutrition_histamine_scores h ON h.item_id=i.id
               WHERE i.datum=?z0DELETE FROM nutrition_meal_summary WHERE datum=?z4DELETE FROM nutrition_daily_summary_v2 WHERE datum=?r>  r   )
r4  proteincarbfatrG  r+   r-  rC   missingidsmeal>   lunchsnackdinner	breakfast
unassignedrG  rF   ru  id))r4  r4  )	protein_grq  )carb_grr  )fat_grs  rt  r+   rC   r-  )r4  rq  rr  rs  zINSERT OR REPLACE INTO nutrition_meal_summary
               (datum,meal,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,histamine_score,histamine_label,updated_at)
               VALUES(?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)r4  rq  rr  rs  a  INSERT OR REPLACE INTO nutrition_daily_summary_v2
           (datum,kcal,protein_g,carb_g,fat_g,item_count,nutrient_json,histamine_score,histamine_max,histamine_unknown_count,histamine_label,updated_at)
           VALUES(?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP))listrC  rT   
setdefaultappendrM   addr1  ro  rG  maxr.  rH  rN  )rI  rb   rowsrL  by_mealrM  rv  buckettargetsourcedestr   r,  r   r   valuess                   r6   recompute_nutrition_dayr  m  sF   " F	
D IC6RQTWSYZc3sQ[\fiuw  EH  EJ  SU  VF)+G (!&k-VVs6{\h##D33PS\_jkxy  DG  SU  be  bg  pr  +s  tv& 	(F7Oq O5M  SY0 r 7v;&9%))$/4LE#f+$66L	7
 &c*E}y!Q&!x ''.v%'	(("   	
fx(/QC0	YF9,=(>fVn@UV fH  I^a#sfY&77tU5PSCUWX=YY  I  I@ $vy(96&>6RW=Z]^del^mZn  qA  BL  NT  UZ  N[  q\  ~D  EN  ~O  ^c  dj  kq  dr  tu  ^v  UY  [`  a		
		
 F8$+,ICy(9$:E&.<QRE	> fY//DU5;PRS5T	!22DeF9DU>VXY8ZfY//DU5;PRS5TVI..DE%u:NPQ4Rw Z7,29,=E&.!$4y!"	
	 Is   )L%c                
   t         t        d      t        j                  t	        j
                  | dd      j                  d            j                         }t        j                  t               }t        j                  |_        	 |5  t        |       |j                  d|f      j                         }|-|d   |k7  rt        d      	 d d d        |j                          y |j                  d	      j!                         }|D cg c]%  }t#        t%        |d
   xs d            | d   k(  r|' }}t'        |      dk7  rt        d      t%        |d   d
   xs d      }t%        |d   d   xs d      }	| d   |	k7  rt        d      t)        |j                  d            }
|
D ch c].  }t+        t%        |d   xs d            |k(  rt%        |d         0 }}||	hk7  rt        d      |
D cg c]  }t%        |d   xs d      |	k(  s| }}|st        d      | d   }| d   dk(  rd n| d   }| d   }| d   }| d   dk(  r| d   dk(  r|j                  d |f      j                         }||d   |k7  rt        d!      t%        |d"   xs d      j-                         }t%        |d#   xs d      j-                         }|r|rt'        |      d$kD  st'        |      d%kD  rt        d&      t/        |D ch c]  }|d'   s	|d'    c}      }t'        |      d(kD  rt        d)      | d   d*k(  r|j                  d+||f       n| d   dk(  r|D ]  }|d,   4|d   /t1        |      |k7  st%        |d   xs d      |k7  rt        d-      <|d,   Mt%        |d   xs d      j-                         s"t%        |d.   xs d      j-                         d/vrt        d0      |j                  d1|d2   ||d3| d   | d4   | d5   xs d6f        | d7   dk7  r|j                  d8|| d7   | d9   xs d f       |j                  d:|f       n|j                  d;|f       |D ]w  }| d   dk(  rt3        |t%        |             |j                  d<||| d   | d   |xs d || d4   | d   ||| d5   t5        | d=         | d7   | d9   xs d t6        t%        |      f       y |j                  d>||| d   | d   | d   |xs d || d4   | d   ||| d5   t5        | d=         | d7   | d9   xs d t6        f       d d d        |j                          y c c}w c c}w c c}w c c}w # 1 sw Y   .xY w# |j                          w xY w)?Nr   Tr@  )	sort_keysrB  r   zFSELECT action_hash FROM nutrition_mapping_action_log WHERE action_id=?action_hashzconflicting idempotency keyzSSELECT normalized_name,example_name FROM nutrition_review_queue WHERE status='open'r  r0   ri   rF   zmapping queue item not foundr   example_namerg   z+mapping alias does not match queue identitya2  SELECT i.id,i.datum,i.name,
                              h.item_id AS mapped_item_id,h.canonical_food,h.sighi_score,
                              h.traffic_light,h.confidence
                         FROM nutrition_items i
                         LEFT JOIN nutrition_histamine_scores h ON h.item_id=i.idr   z#ambiguous normalized queue identityz*mapping queue has no exact nutrition itemsrm   rk   r+   rl   ro   rh   r    rn   r(   z}SELECT canonical_food,sighi_score,source,updated_at
                         FROM histamine_food_rules WHERE canonical_food=?z5SIGHi reference does not match a local versioned ruler  
updated_atrx   ry   z(SIGHi reference provenance is incompletedatumin  zaffected day limit exceededr"   zINSERT OR REPLACE INTO nutrition_composite_product_review
                       (normalized_name,canonical_food,status,updated_at)
                       VALUES(?,?, 'needs_ingredient_review', CURRENT_TIMESTAMP)mapped_item_idz5existing classification conflicts with mapping actionri  >   r0   r+   z6invalid existing classification requires manual repaira  INSERT INTO nutrition_histamine_scores
                           (item_id,canonical_food,sighi_score,traffic_light,tags,confidence,reason,scored_at)
                           VALUES(?,?,?,?,?,?,?,CURRENT_TIMESTAMP)
                           ON CONFLICT(item_id) DO UPDATE SET
                             canonical_food=excluded.canonical_food,
                             sighi_score=excluded.sighi_score,
                             traffic_light=excluded.traffic_light,
                             tags=excluded.tags,
                             confidence=excluded.confidence,
                             reason=excluded.reason,
                             scored_at=CURRENT_TIMESTAMPr|  r+  rj   rf   zlocal validated mapping actionrq   a  INSERT INTO personal_food_tolerance
                           (canonical_food,personal_status,evidence_level,notes,updated_at)
                           VALUES(?,?, 'user_documented', ?, CURRENT_TIMESTAMP)
                           ON CONFLICT(canonical_food) DO UPDATE SET
                             personal_status=excluded.personal_status,
                             evidence_level=excluded.evidence_level,
                             notes=excluded.notes,
                             updated_at=CURRENT_TIMESTAMPrp   zfUPDATE nutrition_review_queue SET status='mapped',updated_at=CURRENT_TIMESTAMP WHERE normalized_name=?zgUPDATE nutrition_review_queue SET status='ignored',updated_at=CURRENT_TIMESTAMP WHERE normalized_name=?a  INSERT OR IGNORE INTO nutrition_mapping_provenance
                       (action_id,normalized_name,decision,alias,canonical_food,sighi_score,confidence,
                        mapping_method,source_label,source_version,note,ingredient_review_required,
                        personal_tolerance_status,personal_tolerance_note,definition_version,affected_day)
                       VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)rr   a  INSERT INTO nutrition_mapping_action_log
                   (action_id,action_hash,queue_key,decision,alias,canonical_food,sighi_score,confidence,
                    mapping_method,source_label,source_version,note,ingredient_review_required,
                    personal_tolerance_status,personal_tolerance_note,definition_version)
                   VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?))r  r3   r  r  r   rE  r  r  rR  connectrS  row_factoryrg  rC  r`  r   fetchallr  r]   r^   r  r)  r`   rF  ro  r  rM   HISTAMINE_DEFINITION_VERSION)ra   	action_idr  rI  rc  queuerM  matchedr(  r  	all_itemscandidate_names	item_rowsr   r   effective_source_labeleffective_source_versionruleaffectedrb   s                       r6   apply_mapping_actionr    s   <==..GtPZ![!b!bcj!klvvxK.J$[[J` ]	+J7!))*ru~  uA  B  K  K  MH#M*k9&'DEE]	~ 	q &&ehj 
 !&s3/@+A+GR'HI;'( G  7|q "#ABBWQZ(9:@bAJwqz.9?R@Lw</"#PQQ""UI %+CF0Ar,BCzQ CK O 
 <.0"#HII(1\SV9J5K|5[\I\"#OPP 01I#M2i?DW]E[E%,^%<"'./?'@$z"h.7;K3LPa3a!))ML (*	 
 <4#6%#?&'^__),T(^-Ar)B)H)H)J&+.tL/A/GR+H+N+N+P(.312R734r9&'QRRyQCLs7|QRH8}s""#@AAz"k1""T  +	 $0$ "C+,8S=O=[-c2e;"3'7#8#>B?9L"./f"gg +,8C 017R8>>@s?39r:@@B/Y*+cdd&&
<  I%!(#$45#L1#FOO/O"F 679D&&= &#$?@#$=>F$ ""  $L  OY  N[  \""  $M  PZ  O\  ] :&(2+JCA""B ":wz/BGGDTV_Vgcgw|4g>N6OQg0'&/3wOkGlCm ;<gF_>`>hdh4c#h" > {GK,@'*BUW^_fWg%ugl.CWM]E^*,Dgfo <=>Hc@d56>$@\a]	~ 	k* ]0 R}]	 ]	~ 	sv   	U" AUU" '#U
*U4A6U*3UU4UUC'U:
U
U
HU)U" UUU" "U4c                @   t        j                         D ]  \  }}| j                  d|f      j                         }|t	        d      | j                  d| d      D ch c]  }t        |d          c}t        fd|D              sxt	        d       y c c}w )Nz9SELECT 1 FROM sqlite_master WHERE type='table' AND name=?zpatient-action schema missingzPRAGMA table_info("z")rF   c              3  ,   K   | ]  \  }}|v  y wr;   r>   )rO   r   _kindactuals      r6   rQ   z0_assert_patient_action_schema.<locals>.<genexpr>a  s     =kdEt6!=s   )r	   rG  rC  r`  r3   r]   r\   )rI  ra  rb  existsrM  r  s        @r6   _assert_patient_action_schemar  W  s    9??A 
@w##G%

(* 	 >>??#-#5#58KE7RT6U#V
CAK
 =W==>??
@
s   !Bc                   t         t        d      t        j                  t               }	 |j	                  d       t        |       |j	                  d       | d   dk(  rW|j	                  d| d   | d   xs d | d	   | d
   | d   | d   | d   xs d | d   | d   | d   xs d | d   | d   | d   xs d f       nF|j	                  d| d   | d   | d   xs d | d	   | d
   | d   | d   | d   | d   | d   | d   xs d f       |j                          	 |j                          y # t        $ r |j                           w xY w# |j                          w xY w)Nr   PRAGMA foreign_keys=ONBEGIN IMMEDIATErB   r   a(  INSERT INTO supplement_plans
                   (product,brand_variant,nutrient_key,amount,unit,schedule_type,weekdays,
                    interval_days,start_date,end_date,composition_source,
                    assignment_reliability,notes)
                   VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)productbrand_variantr=  amountr   schedule_typeweekdaysinterval_days
start_dateend_datecomposition_sourceassignment_reliabilityrA   zINSERT INTO supplement_intakes
                   (plan_id,product,brand_variant,nutrient_key,amount,unit,status,
                    occurred_at,composition_source,assignment_reliability,notes)
                   VALUES(?,?,?,?,?,?,?,?,?,?,?)plan_idstatusr   )
r  r3   rR  r  rC  r
   commit	Exceptionrollbackr   )ra   rI  s     r6   apply_supplement_actionr  e  s   <==.J'34 ,,-8 118 I&(@(HDN+WX->O,gj.A.ITO,gl.CJ'/49M1N45ww7G7O4  4
 I&	(:O,4gn6MH%wv8IM*G4H,I45ww7G7O4 	
 		   	s   C"D   D;;D> >Ec                   t         t        d      t        j                  t               }	 t	        |       |j                  d       |j                  d       | d   }t        |      j                  dd      d   }| d   d	k(  r<| d
   dk(  r| d   n| d
   }|j                  d||| d   | d   || d   xs d | d   f       n| d   dk(  r|j                  d      D ch c]  }t        |d          }}| d   |vrt        d      dj                  d | d   | d   fD              }|j                  d|| d   |xs d | d   xs d | d   | d   xs d |f       n,|j                  d|| d   | d   | d   | d   xs d || d   f       |j                          	 |j                          y c c}w # t        $ r |j                           w xY w# |j                          w xY w) Nr   r  r  r   TrF   r   rB   r   r   r   r   zINSERT INTO symptom_log
                   (datum,symptom,schwergrad,kontext,notizen,occurred_at,onset_at,duration_minutes)
                   VALUES(?,?,?,'additional_symptom',?,?,?,?)r   rA   r   r   r   zlSELECT DISTINCT medication_name FROM medication_administrations WHERE trim(COALESCE(medication_name,''))<>''r   z,medication is not in the known exact catalogrt   c              3  &   K   | ]	  }|s|  y wr;   r>   )rO   parts     r6   rQ   z'apply_patient_action.<locals>.<genexpr>  s     XTSWDXs   r   r   zINSERT INTO medication_administrations
                   (datum,medication_name,dose,route,event_type,notes,source,occurred_at)
                   VALUES(?,?,?,?,?,?, 'dashboard_v5_patient_action', ?)r   r   zINSERT INTO health_events
                   (date,category,parameter,value,unit,source,notes,occurred_at,intensity)
                   VALUES(?,?,?,?,NULL,'dashboard_v5_patient_action',?,?,?)r   r   )r  r3   rR  r  r  rC  r]   r|   r{   r  r  r  r   )ra   rI  r   rb   symptomrM  knownr   s           r6   apply_patient_actionr    s   <==.J%%j134,-m,+$$S!,Q/8/*1.*AW*Lgg&RYZhRiGA gwz2GG4DkSZ[eSfSnjnpw  yK  qL  M	 X"44,6,>,>  @n  -o  pSSQ[  pE  p()6"#QRR88Xgfowv-OXXDL g/0$,$@P@XTXZabnZoqx  zA  rB  rJ  FJ  LW  X	 O gj)77+;W[=QSZ[bScSkgkmx  {B  CN  {O  P	 	
 	- p$   	s+   B/F) F$0B"F) $F) )GG Gc                2    | t        j                  d      z   S )N   )secrets	token_hex)prefixs    r6   _opaquer    s    G%%b)))r8   c                4    t        j                  | ddd      S )NTr@  ensure_asciir  rB  )r   rE  )r5   s    r6   _canonical_jsonr    s    ::e$$:VVr8   c                   	 ddl m}m} ddlmm	 d	 fd} | ||      } ||      }t         j                  d|f      j                         d         } j                  dt        d      ||t        |d         t        |d	         t        |d
         t        |d   t        j                  t              j                  d      f	       y )Nr   )evaluate_observationsnapshot_payload)APIError_seriesc                    	  | |j                         |j                         dd      S # $ r!}|j                  dv rg dddidcY d }~S  d }~ww xY w)Nrb   )metricfromto
resolution>   metric_not_foundmetric_not_releasedr0   rL   not_documented)pointsr   r  )r_   code)	metric_idstartenderrorr  r  rI  s       r6   loaderz,_insert_observation_snapshot.<locals>.loader  sp    	:)U__EV^a^k^k^m  ~C  (D  E  E 	zzHH"$bVEU<VWW	s    )- AAAAAzaSELECT COALESCE(MAX(result_version),0)+1 FROM personal_observation_results WHERE observation_id=?zINSERT INTO personal_observation_results
           (id,observation_id,result_version,configuration_json,phases_json,summary_json,
            method_version,configuration_hash,created_at) VALUES(?,?,?,?,?,?,?,?,?)result_configurationphasessummaryconfiguration_hashsecondsr   )r  r]   r  r   r  r   returndict[str, Any])dashboard_v5.observation_enginer  r  dashboard_v5.read_apir  r  rM   rC  r`  r  r  r   r   r<   r=   r_   )
rI  observation_idr  r  r  analysissnapshotrD   r  r  s
   `       @@r6   _insert_observation_snapshotr    s    V7 $JGH)H*$$  &I  LZ  K\  ]  f  f  h  ij  k  lG	W 
	^WohF_6`	(+	,ohy>Q.R	"67n9U9_9_ir9_9s	u	r8   c                   t         t        d      t        j                  t               }t        j                  |_        	 |j                  d       t        |       |j                  d       t        j                  t              j                  d      }| d   }|dk(  r| d   xs t        d	      }|j                  d
|f      j                         }|| d   rt        d      | d   dvrt        d      |j                  d|d| d   | d   t        | d         t        | d         | d   | d   | d   | d   | d   | d   t        | d         t         ||f       n>t#        |d         }| d   t$        |   vrt        d      |j                  d|| d   | d   f      j                         }|t        d      |j                  d| d   | d   t        | d         t        | d         | d   | d   | d   | d   | d   | d   t        | d         t         ||f       |dk7  r{| d   dk(  rrt'        ||       nd|d k(  r/|j                  d!| d   f      j                         }||d   d"v rt        d#      | d   |d   k  s| d   |d   kD  rt        d$      | d%   xs t        d&      }	|j                  d'|	f      j                         }| d(   | d)   | d   | d   | d*   t        | d+         t        | d,         | d   | d   | d-   | d.   f}
|0| d%   rt        d/      |j                  d0|	| d   g|
||       n`|d   | d   k7  rt        d1      |j                  d2g |
||	       n/|d3k(  rV|j                  d!| d   f      j                         }|(|d   d4k7  s |d   | d5   cxk  r|d   k  st        d6       t        d6      | d%   xs d }	|	rY|j                  d7|	f      j                         }|+|d   | d   k7  s |d   | d5   cxk  r|d   k  sdt        d8       t        d8      |j                  d9| d   | d5   | d5   f      j)                         }t+        |      dk(  rt#        |d:   d;         nd }	|j                  d<t        d=      | d   |	| d5   | d-   | d>   | d?   | d@   | dA   | dB   | dC   | dD   | d   ||f       n|dEk(  r|j                  d
| d   f      j                         }|| d   t$        t#        |d            vrt        d      |j                  dF| d   || d   f       |d   dk7  r`| d   dk(  rXt'        || d          nH|j                  d
| d   f      j                         }||d   dk7  rt        dG      t'        || d          |j-                          	 |j3                          y # t.        $ r |j1                           w xY w# |j3                          w xY w)HNr   r  r  r  r   rB   r   r  obs_z3SELECT status FROM personal_observations WHERE id=?zobservation not foundr  >   draftactivez&initial observation status not alloweda7  INSERT INTO personal_observations
                       (id,contract_version,title,question,influences_json,outcomes_json,lag_min,lag_max,
                        start_date,end_date,status,note,include_doctor,method_version,created_at,updated_at)
                       VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)rF   titlequestion
influencesoutcomeslag_minlag_maxr  r  rf   include_doctorzstatus transition not allowedziSELECT 1 FROM personal_observation_phases WHERE observation_id=? AND (start_date<? OR end_date>?) LIMIT 1z observation range excludes phasezUPDATE personal_observations SET title=?,question=?,influences_json=?,outcomes_json=?,lag_min=?,lag_max=?,
                       start_date=?,end_date=?,status=?,note=?,include_doctor=?,method_version=?,updated_at=? WHERE id=?	completedr   zGSELECT status,start_date,end_date FROM personal_observations WHERE id=?>   archivedr  zobservation cannot be editedzphase outside observationphase_idphase_zASELECT observation_id FROM personal_observation_phases WHERE id=?
phase_typer   behavior_goalmetricsevents	adherencerA   zphase not founda  INSERT INTO personal_observation_phases
                  (id,observation_id,phase_type,name,start_date,end_date,behavior_goal,metrics_json,events_json,lag_min,lag_max,adherence,notes,created_at,updated_at)
                  VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)zphase owner mismatchzUPDATE personal_observation_phases SET phase_type=?,name=?,start_date=?,end_date=?,behavior_goal=?,metrics_json=?,events_json=?,lag_min=?,lag_max=?,adherence=?,notes=?,updated_at=? WHERE id=?r   r  rb   zno active observation for dayzUSELECT observation_id,start_date,end_date FROM personal_observation_phases WHERE id=?zinvalid checkin phasezSELECT id FROM personal_observation_phases WHERE observation_id=? AND start_date<=? AND end_date>=? ORDER BY start_date,id LIMIT 2r   r|  a  INSERT INTO personal_observation_checkins
              (id,observation_id,phase_id,day,adherence,stress,sleep_disruption,infection,unusual_activity,travel,
               medication_change_fact,supplement_change_fact,note,created_at,updated_at)
              VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
              ON CONFLICT(observation_id,day) DO UPDATE SET phase_id=excluded.phase_id,adherence=excluded.adherence,
               stress=excluded.stress,sleep_disruption=excluded.sleep_disruption,infection=excluded.infection,
               unusual_activity=excluded.unusual_activity,travel=excluded.travel,medication_change_fact=excluded.medication_change_fact,
               supplement_change_fact=excluded.supplement_change_fact,note=excluded.note,updated_at=excluded.updated_atcheck_r   r   r   unusual_activityr   medication_change_factsupplement_change_factr   zAUPDATE personal_observations SET status=?,updated_at=? WHERE id=?z/only completed observations can be recalculated)r  r3   rR  r  rS  r  rC  assert_observation_schemar   r<   r=   r_   r  r`  r  rM   r   r]   r   r  r  r^   r  r  r  r   )ra   rI  r<   rB   r  rc  
old_statusoutsideownerr  r  phasematchesrM  s                 r6   apply_observation_actionr    s[	   <==.J$[[J`34!*-,-ll>*44i4H"))$%56I'&/N!))*_bpars||~H+,&'>??8$,??&'OPP""B $Agg&6wz7J?[bco[pKq$WZ%89'):LWU^M_`ght`uZ():76?3wWgOhKijxy|  ~AB !(!34
8$K
,CC&'FGG$,,  .Y  \j  kr  s  k@  AH  IS  AT  [U  V  _  _  a&&'IJJ""|W%gj&9/'R^J_:`apqx  zD  rE  bFY'	(:7<;PQXYcQdelmuevw~  @F  xG!123N3~W ,1Bk1Q0^L11&&'psz  |L  tM  sO  P  Y  Y  [E}h3K K"#ABB|$u\'::gj>QTYZdTe>e"#>??z*?gh.?H!))*mpxoz{  E  E  GHL)'&/',:OPWXbPcdkl{d|  ~M  NU  V_  N`  ~a  bq  ry  zB  rC  bD  EL  MV  EW  X_  `i  Xj  kr  s~  k  @G  HO  @P  QF:&&'899"" $;=EgN^F_<pag<phk<plo<pr ,-9I1JJ&'=>>""  $i  kA  ms  kA  tw  kA  x@  kA  B,,&&'psz  |L  tM  sO  P  Y  Y  [E}h8 ;5CVZabgZhC}lqr|l}C}"#BCC D~"#BCCz*2dH"**  ,C  FN  EP  Q  Z  Z  \=E*:$;wGW?X$X`efr`sw~  @E  xF  a[  JO  PZ  J[  a[&'>?? a[&'>??"**  ,p  sz  {K  sL  MT  UZ  M[  \c  di  \j  rk  l  u  u  w25g,/WQZ-.t  { x )9!:8GENSZ[fSghopxhy  {B  CU  {V  W^  _j  Wk  ls  tF  lG  HO  PX  HY  Za  bz  Z{  |C  D\  |]  ^e  fl  ^m  nq  ru  vw ++""#XZabrZsYuv  BC{gh/{3s8}CU7VV"#BCCbdkltduvy  {B  CS  {T  dU  V8}+0A[0P,ZAQ9RS""#XZabrZsYuv  BC{c(m{:"#TUU(G<L4MN
 		   	s   U*V= =WW W-c           	        t        | t              r't        |t              r|t        d      d| ||d}d}n| }t        |t              st        d      |}|d   dk(  rt	        |d   |d   |d	          nY|d   d
k(  rt        ||       nD|d   dv rt        |       n1|d   dv rt        |       n|d   dv rt        |       nt        d      t        t        j                  t        t              dt        t              dt        t              dt               j                         g}t         t"        k(  r|j%                  g d       t'        j(                  |dddd       y y )Nzinvalid legacy symptom actionrG   )rB   r   rC   rA   zlegacy-symptom-actionzinvalid action idrB   r   rC   rA   rs   >   r   r   r   >   r   r   >   r   r   r   r   r   rH   r   r   z--today)z--health-record-6ez--explorer-6cz--calendar-day-6dTrw   r   )rY   r]   rZ   rU   r  r  r  r  r  DASHBOARD_V5_FILEr  r  DASHBOARD_V5r  r?   r_   DASHBOARD_V5_PROFILEV5_PROFILE_HEALTH_RECORD_6Er  r  r  )ra   r  rA   normalized_payloadnormalized_action_id
v5_commands         r6   apply_actionr  H  s   '3)T*em<=='	.
  7$)S)011((#'88/79KH9UWijqWrs	H	%)<	</1EF	H	%)_	_/0	H	%)Q	Q 23	H	%  *h  
h !34-..$NN!"M##%	

  #>>Z[	
 %r8   c                V   t        j                  d|       st        d      t        dz  }|j	                         r|j                         rt        d      |j                  ddd       t        j                  |d       ||  d	z  }|d
|  d
t        j                          dz  }d| ddt        j                  t              j                  d      d}t        j                  |t        j                   t        j"                  z  t        j$                  z  t        j&                  z  d      }	 t        j(                  |dd      5 }t+        j,                  ||ddd       |j/                  d       |j1                          t        j2                  |j5                                d d d        t        j6                  ||       t        j                  |d       	 |j9                          y # 1 sw Y   GxY w# t:        $ r Y y w xY w# 	 |j9                          w # t:        $ r Y w w xY wxY w)Nru   zinvalid receipt action idreceiptsz'receipt directory must not be a symlinkr   FTr   z.json.z.tmprF   rs   	processedr  r   )rD   r  rB   r  processed_atr   wr   )encodingr@  r  
)r}   r~   rU   r   r  
is_symlinkr3   r   r   r   getpidr   r<   r=   r_   r   O_WRONLYO_CREATO_EXCLr   fdopenr   dumpwriteflushfsyncfilenor   unlinkFileNotFoundError)r  receipt_dirr  tempra   r   handles          r6   write_mapping_receiptr/  z  s   <<3455+K 6 6 8DEE5%$?HH[% i[..F1YKqT::D% ^4>>	>RG r{{RZZ7"))CbmmSUZ[JYYz39 	&VIIgvDDU_`LLLLNHHV]]_%		&
 	

4 
	KKM	& 	& ! 			KKM  		s[   .H AG+%4H G7 +G40H 7	HHH(HH(	H%"H($H%%H(c                 F   t         t        dt        j                         yt	                d} t        t        j                  d            D ]  }	 t        |      }|j                  d      dk(  rt        |d   |d	   |d
          nt        ||j                         |j                  d      dk(  rt        |j                         |j                           | rdS dS # t        $ r9 | dz  } 	 |j                  |j!                  d             n# t"        $ r Y nw xY wY w xY w)Nr   )file   r   z*.jsonrB   rG   r   rC   rA   rs   rF   z.failed)r  printr  stderrr   rF  r   globr   r   r  stemr/  r*  r  r   with_suffixr   )failuresr   ra   s      r6   mainr9    s   /cjjAH|((23 	!$'G{{8$(99WV_gh.?AQRWdii0{{8$(;;%dii0KKM  1a  	MHT--i89 		s7   BCD - DD 	DD DD D __main__)r4   
str | Noner  r]   )r  r   )ra   r  r  r  )r5   r   r  r]   )r5   r   r   rM   r   r   r  r]   )ra   r   r  r  )r   zlist[tuple[str, object]]r  zdict[str, object])r  None)r   r   r  r  )rb   r]   rC   zdict[str, int]rA   r]   r  r<  )r  r]   r  r]   )r5   r]   r  r]   )r,  rM   r+   rM   r-  r1  r  r]   )r5   r   r  zfloat | None)rI  sqlite3.ConnectionrJ  z	list[int]r  r]   )rI  r=  r  r<  )rM  zsqlite3.Rowr  z
int | None)rI  r=  rb   r]   r  r<  )ra   r  r  r]   r  r<  )ra   r  r  r<  )r  r]   r  r]   )rI  r=  r  r]   r  r<  r;   )ra   zdict[str, Any] | strr  zstr | dict[str, int]rA   r;  r  r<  )r  r]   r  r<  )r  rM   )g__doc__
__future__r   r   r   r}   r   r  r  rR  r  r  r   r   pathlibr   typingr   zoneinfor   "dashboard_v5.patient_action_schemar	   dashboard_v5.sprint6f_b_schemar
    dashboard_v5.supplement_contractr   !dashboard_v5.observation_contractr   r   r   dashboard_v5.sprint6f_c_schemar   r   r  ModuleNotFoundErrorr   insertr]   __file__resolveparenthomeBASEr  environr   r  r   r
  r  
SCRIPT_DIRr  r	  r  r[   compiler   r=   r1   r  	frozensetr2   r   r   r   r   r  r7   r  r?   rd   r   r   r   r   r   r   r   r   r  r  r)  r.  r3  rD  rN  rW  rg  ro  r  r  r  r  r  r  r  r  r  r  r/  r9  __name__
SystemExitr>   r8   r6   <module>rU     s   R "  	 	   
    #   jRGLmi tyy{Y)L8//88:  
zz~~+, 	)	*+335	 
 JJNN'D9223
 
')  JJNND999:
 
')  
zz~~01 	.	/088:	 
 (^##%,,
66	4444	K
"***
+/* 0 !35P QR ?@ 89 cd'N   7  (

7T(UV /"JRj	0 AF 36+""0
45
O"d 
 n&A
Hx
v >BfR@+\)X*W2eP/
dB 2 z
TV
 u$  jHHOOAs4>113::;<RGLmiijs   "K A'M M