
    iU(                        S r SSKJrJrJr  SSKJrJr  SSKJr  SSK	J
r
  SSKr\
" \5      R                  5       R                  r\S-  r\S-  r\S	-  r\S
-  r\S-  r\S-  r\S-  r\S-  r\S-  rS\4S jrS\4S jrS\4S jr\ " S S5      5       r\ " S S5      5       r\ " S S5      5       r\ " S S5      5       r S\4S jr!S\4S  jr"S!\ 4S" jr#S-S#\$S\%4S$ jjr&S\%4S% jr'S\4S& jr(\)S':X  aM   SSK*r*\+" S(5        \+" S)5        \*RT                  " \(" 5       5        \+" 5         \+" S*\ 35        \+" S+\S,-   35        gg).u)  
Kitzu Wellness Intelligence Platform — Unified Data Schema

This module defines the canonical data structures for the Kitzu data lake.
All collectors normalize their source data into these formats before storage.
The inference engine reads only from these normalized structures.

Design principles:
  - Every record has: source, timestamp, confidence
  - Units are standardized (metric where possible, mg/dL for blood)
  - Historical data is append-only (never overwrite, always add)
  - Schema is extensible — new fields don't break existing code
    )	dataclassfieldasdict)datedatetime)Optional)PathNdataourabloodgenetics
microbiomevitalscgm
modalitiesunifiedreturnc                      [         S-  n U R                  5       (       a$  [        R                  " U R	                  5       5      $ [        5       $ )z.Load the unified profile, or create empty one.profile.json)UNIFIED_DIRexistsjsonloads	read_text_empty_profile)paths    $/Users/bsyrros/clawd/kitzu/schema.pyload_profiler   &   s6    'D{{}}zz$..*++    profilec                     [         S-  nUR                  R                  SSS9  [        R                  " 5       R                  5       U S'   UR                  [        R                  " U S[        S95        g)zSave the unified profile.r   Tparentsexist_oklast_updated   indentdefaultN)
r   parentmkdirr   now	isoformat
write_textr   dumpsstr)r    r   s     r   save_profiler1   .   sU    'DKKdT2&lln668GNOODJJwq#>?r   c                      S[         R                  " 5       R                  5       SSSSSS/ SS.S0 S/ SS.SS0 / SS.S/ / / / S.0 SS.SS/ / SS	.S
SSS/ SS./ 0 SS./ SS/ / S.S.$ )z)Create a blank unified profile structure.z1.0N)sleep	readiness
heart_ratestepsexercise	hrv_trend	last_sync)latest_testmarkers	inner_agetest_historyr9   r   )source	snp_counthealth_snpscarrier_statusr9   )
superfoodsenjoyminimizeavoid)r>   	food_recsscoresr9   )blood_pressureweight
bp_historyweight_historyr9   F)activesensor	daily_avgtime_in_rangespikesr9   )sessionsresponse_profileslast_session)score_7ddetected_sessionsmissed_protocols)versioncreatedr%   r   r   r   r   r   r   r   insightsactive_protocol
compliance)r   r,   r-    r   r   r   r   6   s     <<>++- 
  
  
  	 

 # 
 !
 !# 
 !# "
AE Er   c                   n   \ rS rSr% Sr\\S'   Sr\\	   \S'   Sr
\\   \S'   Sr\\   \S'   Sr\\   \S'   Sr\\   \S	'   Sr\\   \S
'   Sr\\   \S'   Sr\\   \S'   Sr\\	   \S'   Sr\\   \S'   Sr\\   \S'   Sr\\   \S'   Sr\\   \S'   \" \S9r\\S'   Sr\\S'   Sr\\   \S'   S\4S jrSrg)OuraDailyRecord   u4   One day of Oura data — sleep, readiness, activity.r   Nsleep_hourssleep_scoredeep_sleep_minrem_sleep_minlight_sleep_min	awake_minbedtime	wake_timeavg_hrv
resting_hrreadiness_scorer6   active_caloriesdefault_factory	exercisesOurar>   	synced_atr   c                 t    [        U 5      R                  5        VVs0 s H  u  pUc  M
  X_M     snn$ s  snnf Nr   itemsselfkvs      r   to_dictOuraDailyRecord.to_dict   1    !'!3!3!5G!5!5GGG   	44r\   )__name__
__module____qualname____firstlineno____doc__r0   __annotations__r`   r   floatra   intrb   rc   rd   re   rf   rg   rh   ri   rj   r6   rk   r   listrn   r>   rp   dictry   __static_attributes__r\   r   r   r^   r^      s    >
I#'K%'!%K#%$(NHSM(#'M8C='%)OXc])#Ix}#!GXc]!#Ix}##GXe_# $J$%)OXc])E8C=%)OXc])D1It1FC#Ix}#H Hr   r^   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   S	r\\S
'   \	" \
S9r\
\S'   Sr\\   \S'   S\4S jrSrg)BloodMarker   z!A single blood biomarker reading.namevalueunitoptimal_rangestatusr   InsideTrackerr>   rl   trendNactionr   c                     [        U 5      $ rr   )r   )rv   s    r   ry   BloodMarker.to_dict   s    d|r   r\   )r}   r~   r   r   r   r0   r   r   r>   r   r   r   r   r   r   ry   r   r\   r   r   r   r      sW    +
IL
IK
I!FC!-E4- FHSM  r   r   c                   h    \ rS rSr% Sr\\S'   \\S'   \\S'   Sr\	\
   \S'   Sr\\S	'   S
\4S jrSrg)	BloodTest   zA complete blood test result.r   r>   r;   Nr<   r   marker_countr   c                     [        U 5      nU R                   Vs/ s H&  n[        US5      (       a  UR                  5       OUPM(     snUS'   U$ s  snf )Nry   r;   )r   r;   hasattrry   )rv   dms      r   ry   BloodTest.to_dict   sI    4LMQ\\Z\wq)'<'<		!C\Z) [s   -Ar\   )r}   r~   r   r   r   r0   r   r   r<   r   r   r   r   r   ry   r   r\   r   r   r   r      s8    '
IKM!%Ix%L# r   r   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   Sr\	\   \S'   Sr
\	\   \S	'   Sr\	\   \S
'   \" \S9r\\S'   Sr\	\   \S'   S\4S jrSrg)ModalitySession   z#A single wellness modality session.r   modalityskuduration_minNtime_of_day	pre_score
post_scorerl   device_readingsnotesr   c                 t    [        U 5      R                  5        VVs0 s H  u  pUc  M
  X_M     snn$ s  snnf rr   rs   ru   s      r   ry   ModalitySession.to_dict   r{   r|   r\   )r}   r~   r   r   r   r0   r   r   r   r   r   r   r   r   r   r   ry   r   r\   r   r   r   r      so    -
IM	H!%K#%#Ix}# $J$!$7OT7E8C=H Hr   r   recordc                     [         U R                   S3-  nUR                  R                  SSS9  UR	                  [
        R                  " U R                  5       SS95        g)z,Append a daily Oura record to the data lake..jsonTr"   r&   )r(   N)OURA_DIRr   r*   r+   r.   r   r/   ry   )r   r   s     r   store_daily_ourar      sL    U++DKKdT2OODJJv~~/:;r   testc                 (   [         U R                   SU R                  R                  5       R	                  SS5       S3-  nUR
                  R                  SSS9  UR                  [        R                  " U R                  5       S[        S95        g)	zStore a blood test result._ r   Tr"   r&   r'   N)	BLOOD_DIRr   r>   lowerreplacer*   r+   r.   r   r/   ry   r0   )r   r   s     r   store_blood_testr      sn    $))Adkk&7&7&9&A&A#s&K%LERRDKKdT2OODJJt||~aEFr   sessionc                 P   [         S-  nUR                  R                  SSS9  / nUR                  5       (       a$  [        R
                  " UR                  5       5      nUR                  U R                  5       5        UR                  [        R                  " US[        S95        g)zAppend a modality session.zsessions.jsonTr"   r&   r'   N)MODALITIES_DIRr*   r+   r   r   r   r   appendry   r.   r/   r0   )r   r   existings      r   store_modality_sessionr      st    O+DKKdT2H{{}}::dnn./OOGOO%&OODJJx3?@r   daysc                    / n[         R                  5       (       d  U$ [        [         R                  S5      SS9SU  nU H7  n UR	                  [
        R                  " UR                  5       5      5        M9     U$ ! [         a     MJ  f = f)zLoad recent Oura daily records.*.jsonT)reverseN)	r   r   sortedglobr   r   r   r   	Exception)r   recordsfilesfs       r   load_oura_historyr      sz    G??8==*D9%4@E	NN4::akkm45 
 N  		s   3A==
B
Bc                     / n [         R                  5       (       d  U $ [        [         R                  S5      5       H7  n U R	                  [
        R                  " UR                  5       5      5        M9     U $ ! [         a     MJ  f = f)zLoad all blood test records.r   )	r   r   r   r   r   r   r   r   r   )r   r   s     r   load_blood_historyr      sn    GINN8,-	NN4::akkm45 .
 N  		s    3A99
BBc                  J   0 n S[         4S[        4S[        4S[        4S[        4S[
        4S[        44 Hf  u  pUR                  5       (       aE  [        UR                  S5      5      n[        U5      U(       a  [        S	 U 5       5      OS
S.X'   M_  SS
S.X'   Mh     [        S-  nUR                  5       S
S.U S'   UR                  5       (       a>   [        R                  " UR                  5       5      nUR!                  S5      U S   S'   U $ U $ ! ["         a     U $ f = f)z,Return a summary of what's in the data lake.r   r   r   r   r   r   r   r   c              3   8   #    U  H  oR                   v   M     g 7frr   )stem).0r   s     r   	<genexpr>#data_lake_status.<locals>.<genexpr>  s     4effes   N)r   latestr   r   )r   r%   r    r%   )r   r   GENETICS_DIRMICROBIOME_DIR
VITALS_DIRCGM_DIRr   r   r   r   lenmaxr   r   r   r   getr   )r   r   	directoryr   profile_pathps         r   data_lake_statusr     s3   F 
	)	\"	~&	:		~& 12EU8=#4e444FL
 &'$7FL!& /L%%'F9 	

<1134A01n0EF9n- M6M  	M	s   ;D 
D"!D"__main__zKitzu Data Lake Statusz(========================================zData root: zProfile:   r   )   ),r   dataclassesr   r   r   r   r   typingr   pathlibr	   r   __file__resolver*   
KITZU_ROOT	DATA_ROOTr   r   r   r   r   r   r   r   r   r   r1   r   r^   r   r   r   r   r   r   r   r   r   r   r   r}   pprintprintr\   r   r   <module>r      s   1 0 #    (^##%,,
	 v	:%\)!

e
\))#
d @$ @G GX H H H0        H H H$<_ <G9 G
AO 
AC  D  #$ #L z5	
"#	(O
MM"$%	G	K	{
#$	Kn45
67 r   