
    %fjP                        d dl mZ d dlmZ d dlmZmZ d dlmZ d dlm	Z	m
Z
 h dZe G d d                      Zd&dZd'dZd(dZd)d*dZdddd+dZddddd,d!Zddddd"d-d$Zd%S ).    )annotations)	dataclass)datetimetimezone)
Connection)create_alertutc_now>   crypto_price_stalecrypto_price_missingcrypto_price_missing_localc                      e Zd ZU ded<   dZded<   dZded<   dZded	<   dZded
<   dZded<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   dS )DataQualityCheckResultstrscopeFbooldry_runresolve_fixedr   intactive_crypto_assetsfresh_price_assets active_stale_price_alerts_beforeactive_stale_price_alerts_afterresolved_alertswarningserrorsmissing_price_assetsN)__name__
__module____qualname____annotations__r   r   r   r   r   r   r   r   r   r        r/home/agent/.hermes/worktrees/FinanceManager-sprint10-portfolio-go-live/src/jarvis_finance/quality/data_quality.pyr   r      s         JJJGM !!!!!,-$----+,#,,,,OHFOOOO !!!!!!!r"   r   connr   returnr   c                    d                     d t          D                       }|                     d| dt          t	          t                                                                        d         S )N,c              3     K   | ]}d V  dS ?Nr!   .0_s     r#   	<genexpr>z,_active_price_alert_count.<locals>.<genexpr>    "      BBACBBBBBBr"   zGSELECT COUNT(*) AS n FROM alerts WHERE status='active' AND rule_id IN ()n)joinCRYPTO_PRICE_ALERT_RULESexecutetuplesortedfetchone)r$   placeholderss     r#   _active_price_alert_countr9      sn    88BB)ABBBBBL<<aR^aaaf-..//  hjj r"   value
str | Nonedatetime | Nonec                    | sd S 	 t          j        |                     dd                    }n# t          $ r Y d S w xY w|j        r|n|                    t
          j                  S )NZz+00:00)tzinfo)r   fromisoformatreplace
ValueErrorr?   r   utc)r:   dts     r#   	_parse_dtrE   '   sw     t#EMM#x$@$@AA   tt?22

(,
 ? ??s   (/ 
==	timestampmax_age_secondsr   c                   t          |           }|dS t          j        t          j                  |z
                                  |k    S )NT)rE   r   nowr   rC   total_seconds)rF   rG   rD   s      r#   	_is_stalerK   1   sA    	9		B	ztL&&+::<<NNr"   CHFasset_idr   currencyc                z    |                      d||                                f                                          S )Nz
        SELECT * FROM crypto_prices
        WHERE asset_id=? AND price_currency=?
        ORDER BY COALESCE(provider_timestamp, fetched_at, '') DESC, fetched_at DESC
        LIMIT 1
        )r4   upperr7   )r$   rM   rN   s      r#   _latest_crypto_price_rowrQ   8   s<    <<	 
8>>##$  hjjr"   iQ rN   rG   c                   t          | ||          }t          |o-|d         dk    o!|d         dvot          |d         |                     S )Nquality_statusfreshprice)N 
fetched_at)rG   )rQ   r   rK   )r$   rM   rN   rG   latests        r#   has_fresh_crypto_pricerZ   D   s    %dHh??F  n6"23w>  n6'?ZdCd  nmvw}  K  xL  ^m  nn  nn  nn  jn  o  o  or"   FrN   rG   r   r   c                  d                     d t          D                       }|                     d| dt          t	          t                                                                        }t                      }d}|D ]E}|d         }	|	r9t          | |	||          r&|dz  }|s|                     d	|||d
         f           F|r|s|                                  |S )a  Resolve active stale/missing crypto-price alerts whose asset now has a fresh local price.

    Alert history is retained; rows are never deleted. Updating last_seen_at on resolution makes the
    lifecycle explicit without creating another alert occurrence.
    r'   c              3     K   | ]}d V  dS r)   r!   r+   s     r#   r.   z4resolve_fixed_crypto_price_alerts.<locals>.<genexpr>U   r/   r"   z
        SELECT alert_id, entity_id
        FROM alerts
        WHERE status='active'
          AND entity_type='crypto_asset'
          AND rule_id IN (z&)
        ORDER BY created_at
        r   	entity_idrR      z
                    UPDATE alerts
                    SET status='resolved', resolved_at=?, last_seen_at=?
                    WHERE alert_id=? AND status='active'
                    alert_id)	r2   r3   r4   r5   r6   fetchallr	   rZ   commit)
r$   rN   rG   r   r8   alertsrI   resolvedalertrM   s
             r#   !resolve_fixed_crypto_price_alertsrf   I   s!    88BB)ABBBBBL\\	
 (	 	 	 	f-..//
 
 hjj  ))CH  % 
	.tXbqrrr 
	MH 
 #uZ01     Or"   )rN   rG   r   r   r   c                  t          d||          }|                     d                                          }t          |          |_        t          |           |_        |D ]}t          | |d         ||          r|xj        dz  c_        ,|xj	        dz  c_	        |xj
        dz  c_
        |sUt          | ddd	|d         d
d|d         |d         |                                dd|                                 	  	         |rt          | |||          |_        |s|                                  t          |           |_        |r$|r"t#          d|j        |j        z
            |_        |S )Ncrypto)r   r   r   zZSELECT asset_id, symbol, coingecko_id FROM crypto_assets WHERE is_active=1 ORDER BY symbolrM   rR   r_   warnungmarket_datacrypto_assetr   zBCrypto asset has no fresh local price during data quality recheck.symbolcoingecko_id)rl   rm   rN   zcrypto_price_missing_local:)prioritycategoryentity_typer^   rule_idmessageevidencefingerprintr[   r   )r   r4   ra   lenr   r9   r   rZ   r   r   r   r   rP   rf   r   rb   r   max)r$   rN   rG   r   r   resultassetsassets           r#   check_crypto_data_qualityrz   u   s    $(GS`aaaF\\d hjj  #&f++F.G.M.MF+  !$j(9H^mnnn 	%%*%%##q(##1 	"&*
+4\$)(OU>EZhphvhvhxhxyyL(..:J:JLL
 
 
 
  
!B+	"
 "
 "
  -Ft-L-LF* z= z14Q8_bhbx8x1y1y.Mr"   N)r$   r   r%   r   )r:   r;   r%   r<   )rF   r;   rG   r   r%   r   )rL   )r$   r   rM   r   rN   r   )
r$   r   rM   r   rN   r   rG   r   r%   r   )
r$   r   rN   r   rG   r   r   r   r%   r   )r$   r   rN   r   rG   r   r   r   r   r   r%   r   )
__future__r   dataclassesr   r   r   sqlite3r   jarvis_finance.quality.alertsr   r	   r3   r   r9   rE   rK   rQ   rZ   rf   rz   r!   r"   r#   <module>r      s   " " " " " " ! ! ! ! ! ! ' ' ' ' ' ' ' '       ? ? ? ? ? ? ? ?    " " " " " " " "   @ @ @ @O O O O	 	 	 	 	 PUms o o o o o o !) ) ) ) ) )^ !. . . . . . . .r"   