
    mjO                   P   d dl mZ d dlZd dlZd dlmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlmc 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mZ d dlmZ d dlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+m,Z, dLdZ-dMdNdZ.dOdNdZ/dPdZ0dQd"Z1dRd%Z2dSd'Z3dSd(Z4dSd)Z5dSd*Z6dSd+Z7dSd,Z8dSd-Z9dSd.Z:dSd/Z;dSd0Z<dSd1Z=dSd2Z>dSd3Z?dSd4Z@dSd5ZAdSd6ZBdSd7ZCdSd8ZDdSd9ZEdSd:ZFdSd;ZGdSd<ZHdSd=ZIdSd>ZJdSd?ZKdSd@ZLdSdAZMdSdBZNdTdEZOdSdFZPdSdGZQdSdHZRdSdIZSdSdJZTdSdKZUdS )U    )annotationsNDecimal)
Connection)HTTPException)
TestClient)get_db)
create_app)confirm_create_category)get_budget_charts_2026get_monthly_summary)confirm_budget_transactionconfirm_transfer!create_budget_transaction_preview)get_household_financial_summary)configure_source_mappingconfirm_household_importconfirm_household_review_actionget_household_overviewget_household_reviewlist_household_transactionspreview_household_importpreview_household_review_action)connect_memory)apply_migrationsget_schema_versionreturnr   c            
        t                      } t          |            |                     d           dD ]U\  }}|dk    rdnd}|                     dd| d|||dk    rd	ndf           |                     d
d| d| ||f           V|                                  t	          | ddddd           t	          | ddddd           t	          | ddddd           | S )NzqINSERT INTO platforms(platform_id,name,platform_type,created_at) VALUES ('p_syn','Synthetic','bank','2026-01-01')))raiHousehold A)akbHousehold B)visaCard Ar#   credit_cardcashzINSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,portfolio_bucket,created_at)
               VALUES (?,?,?,?, 'CHF',?,'2026-01-01')acct_p_syn	liabilityzINSERT INTO budget_accounts(budget_account_id,linked_account_id,name,account_type,currency,created_at)
               VALUES (?,?,?,?, 'CHF','2026-01-01')bacc_Traiffeisen_bankSYN-RAI-001bacc_rai)confirmsource_typesource_referencebudget_account_idakb_bankSYN-AKB-001bacc_akbvisa_credit_cardzSYN-CARD-001	bacc_visa)r   r   executecommitr   )connkeylabelaccount_types       -tests/unit/test_household_import_v1_golden.pydatabaser>   %   s   DTLL  E  F  F  FZ m m
U(+v}}69;H3=='SXZfwz  E  xE  xEhshs  KQ  ;R	S 	S 	S 	79FPSW\^j8k	m 	m 	m 	m 	KKMMMTtDUkx  PZ  $[  $[  \  \  \TtJdq  IS  $T  $T  U  U  UTtDVlz  R]  $^  $^  _  _  _K    -100.00SWISSLOS E-COMMERCE
2026-01-26amountstrtexttx_datec           	          d| d| d|  d| d	S )Nz@IBAN;Booked At;Text;Credit/Debit Amount;Valuta Date
SYN-RAI-001;;
 rC   rE   rF   s      r=   raiffeisen_csvrL   8   s.    twttY]tt`fttipttttr?   100.00Own account transferc           	          d| d| d| d|  d	S )Nz1Buchung;Valuta;Buchungstext;Belastung;Gutschrift
rH   z;;rI   rJ   rK   s      r=   akb_csvrP   <   s-    fff'ffTXff\bffffr?   dictc                 L    ddt                      dddt                      dgiS )Nfilesr+   profilecsv_textr2   r3   rU   r0   rV   )rL   rP   rJ   r?   r=   transfer_payloadrX   @   s6    %>3C3CDDMwyyYY  r?   sourcepreviewc                ,    | d|d         |d         dz  S )NTpreview_fingerprintbaseline_fingerprint)r.   r\   r]   rJ   )rY   rZ   s     r=   confirm_payloadr^   G   s0    WEZ=[-45K-LN N N Nr?   r9   tuple[dict, dict]c                    t          | |          }d |d         D             fd|d         D             }|d|iz  }t          | |          }|d         du sJ ||fS )Nc                    i | ]O}|                     d           dv t          |                     d                     t          |d                   PS )category_type>   incomeexpensecategory_id)getrD   ).0categorys     r=   
<dictcomp>z*business_ready_preview.<locals>.<dictcomp>N   s]       <<((,AAA 	HLL))**C0G,H,HAAAr?   
categoriesc                    i | ]T}|d          dk    rFt          |d                   v %t          |d                   t          |d                            US )
user_stateproposal_readytransaction_semantics	row_token)rD   )rg   itemby_types     r=   ri   z*business_ready_preview.<locals>.<dictcomp>S   sq       !111,-..'99 	DD1H,I(J(J K :99r?   itemscategory_overridesbusiness_ready_for_confirmT)r   )r9   rY   initial	overridesresolvedrZ   rq   s         @r=   business_ready_previewrx   L   s    &tV44G -  G
   G$  I -y99H&tX66G/0D8888Wr?   Nonec                 ,   t                      } t          |           dk    sJ d |                     d          D             }h d                    |          sJ d |                     d          D             }ddh                    |          sJ d S )	N1   c                    h | ]
}|d          S r   rJ   rg   rows     r=   	<setcomp>zPtest_schema_48_has_household_contract_and_three_unique_layers.<locals>.<setcomp>b   s    bbbc!fbbbr?   z1SELECT name FROM sqlite_master WHERE type='table'>   household_import_fileshousehold_import_itemshousehold_migros_linkshousehold_import_batches!household_account_source_mappingsc                    h | ]
}|d          S r}   rJ   r~   s     r=   r   zPtest_schema_48_has_household_contract_and_three_unique_layers.<locals>.<setcomp>e   s    ccc#s1vcccr?   z1SELECT name FROM sqlite_master WHERE type='index')ux_budget_candidates_household_source_row&ux_budget_candidates_household_logical)r>   r   r7   issubset)r9   tablesindexess      r=   =test_schema_48_has_household_contract_and_three_unique_layersr   _   s    ::Dd##r))))bb-` a abbbF@ @ @@H@P@PQ Q Qcc.a!b!bcccG79abkklstttttttr?   c                    t                      } t                      }|                                  | j        }d                    |                                           }t          | |          }t          | |          }d |                                D             }d |                                D             }||k    sJ |d         |d         k    sJ |d         d         dk    sJ t          |d         d                   d	k    sJ | j        |k    sJ d                    |                                           |k    sJ |d
         du sJ |d         d         dk    sJ t          j
        |          }d|vrd|vsJ d|vsJ d S )NrI   c                &    i | ]\  }}|d k    ||S performancerJ   rg   r:   values      r=   ri   zQtest_preview_is_strictly_read_only_deterministic_and_redacted.<locals>.<dictcomp>q   s(    WWW:3#BVBVCBVBVBVr?   c                &    i | ]\  }}|d k    ||S r   rJ   r   s      r=   ri   zQtest_preview_is_strictly_read_only_deterministic_and_redacted.<locals>.<dictcomp>r   s(    YYYJCC=DXDXS%DXDXDXr?   r\   r   api_total_secondsr   parsing_by_file   confirmableTcountssafe_transfer_pairs   r,   r3   r0   )r>   rX   r8   total_changesjoiniterdumpr   rr   lenjsondumps)	r9   payloadbefore_changesbefore_dumpfirstsecondfirst_stablesecond_stable
serializeds	            r=   =test_preview_is_strictly_read_only_deterministic_and_redactedr   i   s   ::D  GKKMMM'N))DMMOO,,K$T733E%dG44FWWWWWLYY&,,..YYYM=((((&'62G+HHHHH 349999u]#$56771<<<<////99T]]__%%44444''''?01Q6666E""J
**}J/N/N/NNZ//////r?   c                 T   t                      } d                    d t          d          D                       }ddd|z   dgi}g }|                     |j                   t          | |           |                     d            d |D             }t          |          d	k    sJ d S )
N c           
   3  V   K   | ]$}d |dz  dz   dd| d|dz    d|dz  dz   dd	V  %dS )	zSYN-RAI-001;2026-01-   r   02dz
;Merchant z;-z.00;2026-01-rI   NrJ   rg   indexs     r=   	<genexpr>zStest_preview_bulk_loads_repeated_source_mapping_once_per_binding.<locals>.<genexpr>   s{         	x
a/wwwuwwPQ	ww`ehj`jno_owwww     r?   (   rS   r+   z4IBAN;Booked At;Text;Credit/Debit Amount;Valuta Date
rT   c                    g | ]A}|                                                                                     d           rd|v ?|BS )zSELECT M.MAPPING_IDr   )lstripupper
startswith)rg   	statements     r=   
<listcomp>zTtest_preview_bulk_loads_repeated_source_mapping_once_per_binding.<locals>.<listcomp>   s`       ##%%001FGG 09<< 	 =<<r?   r   )r>   r   rangeset_trace_callbackappendr   r   )r9   rowsr   
statementsmapping_selectss        r=   @test_preview_bulk_loads_repeated_source_mapping_once_per_bindingr      s    ::D77  2YY    D
 	(ORVV
 
 G JJ-...T7+++D!!! #  O 1$$$$$$r?   c                    t                      } t                      }t          | |          }|d         d         }|d         dk    sJ |d         dk    r|d         dk    sJ |d	         d
k    sJ t          | t	          ||                    }t          | t	          ||                    }d|v r	|d         sn|d         d         dk    sJ |d         du r|d         |d         k    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         }d|vrd|vrd|vsJ d S )Ntransfer_pairsr   pairing_classsaferC   rM   currencyCHFpairing_versiontransfer_pairing_v3transfer_pair_countr   r   
idempotentTbatch_idz]SELECT COUNT(*) FROM budget_transfer_pairs WHERE status='confirmed' AND quality_status='safe'z%SELECT COUNT(*) FROM budget_transferszJSELECT COUNT(*) FROM budget_transactions WHERE transaction_type='transfer'r   zOSELECT new_values_json FROM audit_log WHERE action='household_import_confirmed'SYN-SWISSLOSrV   )r>   rX   r   r   r^   r7   fetchone)r9   r   rZ   pairr   r   audits          r=   _test_golden_raiffeisen_2026_01_26_swisslos_chf100_is_safe_v3_transfer_and_confirm_is_noop_twicer      s   ::D  G&tW55G#$Q'D F****>X%%$z*:e*C*C*CC$%)>>>>>$T?7G+L+LMME%dOGW,M,MNNF+@E+I+I5&'+I+IuU]_tOuyzOzOzOzz,4''F:,>%
BS,S,S,SS<<wxx  B  B  D  D  EF  G  KL  L  L  L  L<<?@@IIKKANRSSSSS<<deennppqrswxxxxxLLjkkttvvwxyE:U#:#:zQV?V?V?VV?V?Vr?   c                     t                      } ddt          dd          dddt          dd	          d
gi}t          | |          }|d         d         dk    sJ t	          d |d         D                       sJ d S )NrS   r+   -10.00zPayment CoffeerT   r2   r3   10.00zSalary correctionrW   r   r   r   c              3  .   K   | ]}|d          dk    V  dS )dispositiontransfer_confirmedNrJ   r~   s     r=   r   z\test_generic_payment_text_cannot_turn_unrelated_rows_into_a_safe_transfer.<locals>.<genexpr>   s-      UUcs=!%99UUUUUUr?   r   )r>   rL   rP   r   all)r9   r   rZ   s      r=   Itest_generic_payment_text_cannot_turn_unrelated_rows_into_a_safe_transferr      s    ::D%>(L\3]3]^^MwW^`sOtOtuu G 'tW55G823q8888UUWV_UUUUUUUUUUr?   c                    t                      } t                      }t          | |          }|                     d           |                                  t          j        t                    5 }t          | t          ||                     d d d            n# 1 swxY w Y   |j
        j        dk    sJ |                     d                                          d         dk    sJ d S )NzaUPDATE household_account_source_mappings SET updated_at='2026-02-01' WHERE source_type='akb_bank'  -SELECT COUNT(*) FROM household_import_batchesr   )r>   rX   r   r7   r8   pytestraisesr   r   r^   r   status_coder   )r9   r   rZ   excs       r=   2test_stale_confirm_rejected_before_any_batch_writer      s   ::D  G&tW55GLLtuuuKKMMM	}	%	% J w'H'HIIIJ J J J J J J J J J J J J J J9 C''''<<GHHQQSSTUVZ[[[[[[[s   /BB!Bc                    t                      } d}dd|dgi}t          | |          \  }}t          | t          ||                     t	          | |          }|d         d         d         dk    sJ dd|                    d	d
          dgi}t	          | |          }|d         d         d         dk    sJ |d         d         d         dk    sJ dd|dz   dgi}t	          | |          d         d         d         dk    sJ d S )NzoTransactionId,CardId,Date,Amount,Currency,MerchantName
T-001,SYN-CARD-001,2026-02-01,-12.50,CHF,Synthetic Shop
rS   r5   rT   r   r   r   duplicate_filezT-001zT-002reviewclassificationpossible_logical_duplicaterI   duplicate_source_row)r>   rx   r   r^   r   replace)r9   r#   r   rZ   	same_fileoverlaplogicalsource_overlaps           r=   =test_file_source_row_and_logical_duplicates_are_distinguishedr      sE   ::D~D%7TJJKLG-dG<<GWT?7G#D#DEEE(w77IVQ.2BBBBB%7T\\RY[bEcEcddefG&tW55G6?1m,88886?1./3OOOOO,>DSWK X XYZN#D.99&A!D]SWmmmmmmmr?   c                 ^   t                      } |                     d           |                     d           |                                  t          | ddddgi          }|d         d         }|d	         d
k    sJ |d         dk    sJ |d         du sJ |d         d         dk    sJ d S )Na  INSERT INTO budget_transaction_candidates(
             transaction_candidate_id,source_file_label,source_row_or_range,source_type,
             transaction_date,description,merchant,amount_original,currency_original,
             confidence,requires_review,status,created_at,updated_at)
           VALUES ('legacy-apple','legacy-visa.csv','R1122','credit_card_csv',
                   '2026-05-12','Apple','Apple','20.00','CHF','1',0,'confirmed',
                   '2026-05-18','2026-05-18')a  INSERT INTO budget_transactions(
             budget_transaction_id,account_id,transaction_type,transaction_date,description,payee,
             amount_original,currency_original,amount_chf,fx_status,status,source_type,
             source_candidate_id,created_at,updated_at)
           VALUES ('legacy-apple-tx','bacc_rai','expense','2026-05-12','Apple','Apple',
                   '20.00','CHF','20.00','not_needed','confirmed','import_candidate',
                   'legacy-apple','2026-05-18','2026-05-18')rS   r5   z~TransactionId,CardId,Date,Amount,Currency,MerchantName,OriginalAmount
new-apple,SYN-CARD-001,2026-05-12,20.00,CHF,Apple,20.00
rT   r   r   r   possible_legacy_duplicater   r   requires_reviewTexpected_budget_effectexpense_chf0.00)r>   r7   r8   r   )r9   rZ   r   s      r=   Utest_canonical_visa_row_overlapping_legacy_positive_household_booking_requires_reviewr      s    ::DLL	1   	LL	@   	KKMMM&-P  	
 G &/!
C $?????})))) !T))))+,];vEEEEEEr?   c            	     j   t                      } d}t          | dd|dgi          }d |d         D             }d |d         D             }d|v rd	|v sJ d
|v sJ t          | ddt          dd          dgi          }|d         d         d         dk    sJ |d         d         d         dk    sJ d S )NzTransactionId,CardId,Date,Amount,Currency,MerchantName,Status
T-P,SYN-CARD-001,2026-02-02,-20.00,CHF,Synthetic Market,pending
T-P,SYN-CARD-001,2026-02-02,-20.00,CHF,Synthetic Market,booked
T-R,SYN-CARD-001,2026-02-03,5.00,CHF,Synthetic Refund,booked
rS   r5   rT   c                    g | ]
}|d          S r   rJ   r~   s     r=   r   zRtest_credit_card_pending_final_refund_and_payment_are_explicit.<locals>.<listcomp>      BBB3C&BBBr?   r   c                    g | ]
}|d          S )r   rJ   r~   s     r=   r   zRtest_credit_card_pending_final_refund_and_payment_are_explicit.<locals>.<listcomp>  s    @@@s#$@@@r?   superseded_pending	candidatecredit_card_refundr+   z-55.00zVISA CARD PAYMENTr   r   credit_card_paymentr   r   	unmatched)r>   r   rL   )r9   rV   rZ   dispositionsclassesbank_payments         r=   >test_credit_card_pending_final_refund_and_payment_are_explicitr     s$   ::DPH 'tgDVdl8m8m7n-oppGBB'&/BBBL@@@@@G<//K<4O4O4OO7****+D7IZhvw  BU  iV  iV  >W  >W  =X  3Y  Z  ZL"#348MMMMM()!,_=LLLLLLr?   c                 (   t                      } d}d}dd|dd|dgi}t          | |          }|d         d         d	         d
k    sJ t          | t          ||                    }|d         d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ t                      }|d|d         d         d|                    dd          dgiz  }t          ||          }|d         d         d	         dk    sJ |d         d         d         dk    sJ d S )NzoTransactionId,CardId,Date,Amount,Currency,MerchantName
M-1,SYN-CARD-001,2026-03-01,-60.00,CHF,Migros Synthetic
zDatum;Zeit;Filiale;Kassennummer;Transaktionsnummer;Artikel;Umsatz
2026-03-01;12:00;Synthetic Store;1;99;Item A;24.00
2026-03-01;12:00;Synthetic Store;1;99;Item B;36.00
rS   r5   rT   migros_receiptsreceipt_linksr   statuslinkedr   receipt_link_countr   -SELECT COUNT(*) FROM budget_import_line_itemsr   (SELECT COUNT(*) FROM budget_transactionsASELECT COUNT(*) FROM household_migros_links WHERE status='linked'z36.00z36.02r   
differencez0.02)r>   r   r   r^   r7   r   r   )	r9   r#   receiptr   rZ   resultconn2mismatchr   s	            r=   Qtest_migros_links_detail_without_double_counting_and_difference_over_cent_reviewsr    s   ::D~DEG %7TJJ%6GLLN OG&tW55G?#A&x0H<<<<%dOGW,M,MNNF(01Q6666<<GHHQQSSTUVZ[[[[[<<BCCLLNNqQUVVVVV<<[\\eegghijnoooooJJE'GG$4Q$7EVdkdsdst{  ~E  eF  eF  :G  :G  $H  I  IH%eX66F/"1%h/8;;;;/"1%l3v======r?   c                 B   t                      fd} t          d          }| |j        t          <   t	          |          }|                    d                                          d         }dD ]}||v sJ 	j        }|                    d          j        dk    sJ |                    d	          j        dk    sJ j        |k    sJ t          d
          }| |j        t          <   t	          |          }|	                    di           j        dk    sJ d S )Nc               3     K    V  d S NrJ   r9   s   r=   override_dbz\test_api_contract_gets_are_side_effect_free_and_write_gate_is_preserved.<locals>.override_db&        




r?   test
write_mode/openapi.jsonpaths)%/api/budget/household/source-mappingsz$/api/budget/household/import/preview$/api/budget/household/import/confirm$/api/budget/household/import/batchesr     r  disabledr  r     )
r>   r
   dependency_overridesr	   r   rf   r   r   r   post)	r  appclientr  pathbeforeblocked_appblockedr9   s	           @r=   Gtest_api_contract_gets_are_side_effect_free_and_write_gate_is_preservedr+  $  sD   ::D    

'
'
'C'2CV$__FJJ'',,..w7Ea  u}}}}}F::=>>JcQQQQ::<==ISPPPP''''
333K/:K$V,%%G<<>R<HHTX[[[[[[[r?   c                    t                      } t                      }t          | |          }t          | t	          ||                     t                      }t          d          |d         d         d<   t          j        t                    5 }t          | t	          ||                     d d d            n# 1 swxY w Y   |j	        j
        dk    sJ dt          |j	        j                  vsJ d S )Nz-101.00rS   r   rV   r   r   )r>   rX   r   r   r^   rL   r   r   r   r   r   rD   detail)r9   r   rZ   stolenr   s        r=   =test_idempotent_confirm_recomputes_input_identity_before_noopr/  9  s+   ::D  G&tW55GT?7G#D#DEEEF%3I%>%>F7OAz"	}	%	% I vw'G'GHHHI I I I I I I I I I I I I I I9 C''''SY-........s   B;;B?B?c                    t                      } ddt          d          dgi}d |                     d          D             }|d         |d         d         d	<   t          | |          }|d
         du sJ |d         d         d         dk    sJ |d         |d         d         d	<   t	          | |          \  }}|d
         du sJ t          | t          ||                     |d         |d         d         d	<   t          j        t                    5 }t          | t          ||                     d d d            n# 1 swxY w Y   |j
        j        dk    sJ d S )NrS   r+   r   rT   c                ,    i | ]}|d          |d         S )r/   
mapping_idrJ   r~   s     r=   ri   zLtest_selected_mapping_is_bound_and_mismatch_fails_closed.<locals>.<dictcomp>I  s4        	MC-  r?   zDSELECT mapping_id,source_type FROM household_account_source_mappingsr5   r   r2  r   Ferrorscode*account_source_mapping_missing_or_mismatchTr   )r>   rL   r7   r   rx   r   r^   r   r   r   r   r   )r9   r   mapping_idsr  matchedr   s         r=   8test_selected_mapping_is_bound_and_mismatch_fails_closedr8  F  s   ::D%6NS[D\D\]]^_G << fgg  K )44F(GGGQ%'g66HM"e++++Ha (,XXXXX(34E(FGGQ%-dG<<GW=!T))))T?7G#D#DEEE(34F(GGGQ%	}	%	% J w'H'HIIIJ J J J J J J J J J J J J J J9 C''''''s   D??EEc            	        d} | D ]}t                      }t                      }t          ||          }|                    |           |                                 t          j        t                    5 }t          |t          ||                     d d d            n# 1 swxY w Y   |j
        j        dk    sJ d S )N)zFUPDATE accounts SET account_name='Changed' WHERE account_id='acct_rai'zRUPDATE budget_accounts SET updated_at='changed' WHERE budget_account_id='bacc_rai'a>  INSERT INTO budget_transactions(budget_transaction_id,account_id,transaction_type,transaction_date,description,amount_original,currency_original,amount_chf,fx_status,status,source_type,created_at,updated_at) VALUES ('drift','bacc_rai','expense','2026-01-01','x','1','CHF','1','not_needed','confirmed','manual','x','x')r   )r>   rX   r   r7   r8   r   r   r   r   r^   r   r   )	mutationssqlr9   r   rZ   r   s         r=   Ltest_baseline_covers_accounts_transactions_transfers_and_household_relationsr<  [  s   I
  , ,zz"$$*499S]=)) 	NS$T?7G+L+LMMM	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	Ny$+++++, ,s   5B  B$	'B$	c                 P   t                      } dg iddddgiddddgiddddgidddd	z  dgif}|D ]p}t          j        t                    5 }t	          | |           d d d            n# 1 swxY w Y   |j        j        d
v sJ dt          |j        j                  vsJ qd S )NrS   r5   r   rT   unknownzsecret-account-referenceautoxi P >       )	r>   r   r   r   r   r   r   rD   r-  )r9   bad_payloadsr   r   s       r=   Ftest_limits_empty_unsupported_and_errors_fail_closed_without_raw_leaksrD  l  s7   ::D	"	1rBBCD	y6PQQRS	v3MNNOP	1sFY?Z[[\]L   G G]=)) 	4S$T7333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4y$
2222)SY5E1F1FFFFFF	G Gs   A--A1	4A1	c                 *   t                      } t                      }t          | |          }t          |          }|d         r|d         sJ d|vsJ d|vsJ d|vsJ d|vsJ d|vsJ d|vsJ t	          d	 |d
         D                       sJ d S )Nr\   r]   input_fingerprintfile_fingerprintsource_row_fingerprintlogical_fingerprintmoney_candidate_idr   c              3  f   K   | ],}t          |d                                        d          V  -dS )ro   row_N)rD   r   r~   s     r=   r   zctest_public_preview_exposes_protocol_bindings_but_no_internal_file_or_row_hashes.<locals>.<genexpr>  s=      SSCs3{#$$//77SSSSSSr?   r   )r>   rX   r   rD   r   )r9   r   rZ   encodeds       r=   Ptest_public_preview_exposes_protocol_bindings_but_no_internal_file_or_row_hashesrN  |  s    ::D  G&tW55G'llG()Mg6L.MMMMg----W,,,,#72222 ////w....    SS76?SSSSSSSSSSr?   c                    t                      } d}dd|dgi}t          | |          \  }}|d         d         dk    sJ d |d	         D                                 d
          dk    sJ t          | t	          ||                    }|d         d         dk    sJ |                     d                                          d         dk    sJ t                      }d}dd|dgi}t          ||          \  }}d |d	         D             d
dgk    sJ t          |t	          ||                     |                    d                                          d         dk    sJ d S )NzTransactionId,CardId,Date,Amount,Currency,MerchantName,Status
P-1,SYN-CARD-001,2026-02-02,-20.00,CHF,Synthetic,pending
P-1,SYN-CARD-001,2026-02-02,-20.00,CHF,Synthetic,booked
P-1,SYN-CARD-001,2026-02-02,-20.00,CHF,Synthetic,booked
rS   r5   rT   r   
duplicatesr   c                    g | ]
}|d          S r   rJ   r~   s     r=   r   zYtest_same_request_duplicate_and_pending_final_have_one_writable_final.<locals>.<listcomp>  s    :::3C:::r?   r   r   r   candidate_countWSELECT COUNT(*) FROM budget_transaction_candidates WHERE household_batch_id IS NOT NULLr   zTransactionId,CardId,Date,Amount,Currency,MerchantName
D-1,SYN-CARD-001,2026-02-03,-5.00,CHF,Synthetic
D-1,SYN-CARD-001,2026-02-03,-5.00,CHF,Synthetic
c                    g | ]
}|d          S r   rJ   r~   s     r=   r   zYtest_same_request_duplicate_and_pending_final_have_one_writable_final.<locals>.<listcomp>  s    DDD3CDDDr?   r   )r>   rx   countr   r^   r7   r   )	r9   r   r   rZ   r  r  duplicate_rowsduplicate_payloadduplicate_previews	            r=   Etest_same_request_duplicate_and_pending_final_have_one_writable_finalrY    s   ::DGD %7TJJKLG-dG<<GW8\*a////::'&/:::@@MMQRRRRR%dOGW,M,MNNF(-.!3333<<qrr{{}}~  A  EF  F  F  F  FJJEIN !/A~#^#^"_`+A%IZ+[+[((DD*;F*CDDDVlHmmmmmUO4EGX$Y$YZZZ==rss||~~  @A  B  FG  G  G  G  G  G  Gr?   c                 j   t                      } d}dd|dgi}t          | |          \  }}d |d         D             }|ddgk    sJ |d         d	         d
         dk    sJ t          | t          ||                     |                     d                                          d         dk    sJ d S )NzTransactionId,CardId,Date,Amount,Currency,MerchantName
REAL-1,SYN-CARD-001,2026-02-03,-5.00,CHF,Synthetic Coffee
REAL-2,SYN-CARD-001,2026-02-03,-5.00,CHF,Synthetic Coffee
rS   r5   rT   c                    g | ]
}|d          S r   rJ   r~   s     r=   r   zmtest_distinct_provider_transactions_with_same_business_fields_are_not_silently_suppressed.<locals>.<listcomp>  r   r?   r   r   r   r   r   r   rS  r   r   )r>   rx   r   r^   r7   r   )r9   rV   r   rZ   r   s        r=   Ytest_distinct_provider_transactions_with_same_business_fields_are_not_silently_suppressedr\    s    ::DMH %7XNNOPG-dG<<GWBB'&/BBBLK222226?1./3OOOOOT?7G#D#DEEE<<a hjj     r?   c                 j   t                      } |                     d                                          d         }|                     d|f           |                                  ddt	          dd          dgi}t          | |          \  }}|d	         d         d
         dk    sJ |d	         d         d         dk    sJ t          | t          ||                     |                     d                                          d         dk    sJ t          d t          |           d         D                       }d|d         v sJ |d         dd}t          | |          }t          | i ||ddi           |                     d                                          d         dk    sJ d S )NzcSELECT budget_account_id FROM household_account_source_mappings WHERE source_type='raiffeisen_bank'r   a  INSERT INTO budget_transactions(
             budget_transaction_id,account_id,transaction_type,transaction_date,booking_date,
             description,amount_original,currency_original,fx_rate_to_chf,amount_chf,fx_status,
             status,source_type,created_at,updated_at)
           VALUES ('legacy-overlap',?,'expense','2026-01-26','2026-01-26',
                   'Synthetic Grocery','-25.50','CHF','1','-25.50','not_needed',
                   'confirmed','manual','2026-01-15T00:00:00Z','2026-01-15T00:00:00Z')rS   r+   z-25.50zSynthetic GroceryrT   r   r   r   r   r   r	  r   c              3  2   K   | ]}|d          dk    |V  dS )titlezPossible Legacy DuplicateNrJ   )rg   gs     r=   r   zOtest_legacy_productive_overlap_is_reviewed_not_counted_again.<locals>.<genexpr>  s1      nnqAgJRmDmDmDmDmDmDmnnr?   groups	duplicatesupported_actions	group_keyrd  actionr.   TzKSELECT COUNT(*) FROM budget_transaction_candidates WHERE status='duplicate')r>   r7   r   r8   rL   rx   r   r^   nextr   r   r   )r9   
account_idr   rZ   grouprf  action_previews          r=   <test_legacy_productive_overlap_is_reviewed_not_counted_againrk    s   ::Dm hjjJ 	LL	Z 
	 	 	 	KKMMM%6NS[]pDqDqrrstG-dG<<GW6?1./3NNNNN6?1m,8888T?7G#D#DEEE<<BCCLLNNqQUVVVVVnn066x@nnnnnE% 344444 -EEF4T6BBN#D*WV*W~*WyRV*W*WXXX<<U hjj     r?   c                 P   t                      } t                      }t          | |          }|                     d           t	          | t          ||                    }|d         du r| j        sJ |                                  |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ t                      } t          | |          }|                     d           |                     d           t          j
        t                    5  t	          | t          ||                     d d d            n# 1 swxY w Y   | j        sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d	                                          d         dk    sJ d S )
NzfINSERT INTO platforms(platform_id,name,platform_type,created_at) VALUES ('caller','Caller','bank','x')r   Fr   r   z9SELECT COUNT(*) FROM platforms WHERE platform_id='caller'zCREATE TEMP TRIGGER fail_household_candidate BEFORE INSERT ON budget_transaction_candidates BEGIN SELECT RAISE(ABORT,'synthetic failure'); ENDr   zHSELECT COUNT(*) FROM audit_log WHERE action='household_import_confirmed')r>   rX   r   r7   r   r^   in_transactionrollbackr   r   r   	Exception)r9   r   rZ   r  s       r=   Ttest_household_confirm_preserves_outer_transaction_and_rolls_back_only_its_savepointrp    s`   ::D  G&tW55GLLyzzz%dOGW,M,MNNF,5((T-@((@MMOOO<<GHHQQSSTUVZ[[[[[<<STT]]__`abfggggg::D&tW55GLLyzzzLL  b  c  c  c	y	!	! J J w'H'HIIIJ J J J J J J J J J J J J J J<<STT]]__`abfggggg<<GHHQQSSTUVZ[[[[[<<bccllnnopquvvvvvvvs   E99E= E=c                     t                      } t          dd          }d}t          | dd|dd|dgi          }|d         d	         d
k    sJ d S )Nr   zOrdinary purchasezmTransactionId,CardId,Date,Amount,Currency,MerchantName
R-1,SYN-CARD-001,2026-01-26,10.00,CHF,Ordinary refund
rS   r+   rT   r5   r   r   r   )r>   rL   r   )r9   bankcardrZ   s       r=   4test_transfer_false_positive_card_refund_is_not_safert    sw    ::D($788D|D&tg%488&D998 .  G 823q888888r?   c                    t                      } d}dd|dgi}t          | |          }|d         d         d         dk    sJ |                     d	                                          d         dk    sJ t	          | t          ||                     |                     d
                                          }t          |          dk    sJ t          | d          }|d         dk    r|d         dk    sJ |d         dk    sJ t                      }|                    dd                              dd          }dd|dgi}t          ||          }	|	d         d         d         du sJ t	          |t          ||	                     |                    d	                                          d         dk    sJ d S )NzoTransactionId,CardId,Date,Amount,Currency,MerchantName
RF-1,SYN-CARD-001,2026-02-10,12.50,CHF,Synthetic refund
rS   r5   rT   r   r   r   r   r	  zSSELECT transaction_type,amount_original,status,source_type FROM budget_transactions)refundz12.50	confirmedimport_candidate2026-02month
income_chfr   r   unlinked_refund_countr   z,CHF,z,EUR,zRF-1zRF-2r   T)	r>   r   r7   r   r   r^   tupler   r   )
r9   rV   r   rZ   txoverviewr  eur_csveur_payloadeur_previews
             r=   Gtest_clear_chf_card_refund_becomes_productive_refund_only_after_confirmr    s   ::D CH%7XNNOPG&tW55G6?1./3GGGGG<<BCCLLNNqQUVVVVVT?7G#D#DEEE	]
 
hjj  99LLLLL%d)<<<HL!V++0G60Q0Q0QQ+,1111JJEw0088HHG);QQRSK*5+>>Kvq!"34<<<<UOK$M$MNNN==CDDMMOOPQRVWWWWWWWr?   c                    t                      } ddddgi}t          | |          \  }}t          | t          ||                     |                     d                                          d         }ddddgi}t          | |          }|d         d         }|d	         d
k    sJ |d         du sJ d|vsJ t          | t          ||                     |                     d                                          }|d         dk    sJ t          |d                   t          d          k    sJ |d         |k    sJ t          j	        |d                   d         |k    sJ |                     d                                          d         }|dk    sJ t          | d          }	|	d         dk    sJ |	d         dk    sJ |	d         dk    sJ t          | |          }
|
d         d         d         dk    sJ dd|d         d         d                             dd          dgi}t          | |          }|d         d         d	         d k    sJ |d         d         d         d!k    sJ d S )"NrS   r5   zDate,Amount,Currency,MerchantName,TransactionId,CardId
2026-02-01,-8.25,CHF,Synthetic reverse purchase,rev-purchase,SYN-CARD-001
rT   zdSELECT budget_transaction_id FROM budget_transactions WHERE description='Synthetic reverse purchase'r   zDate,Amount,Currency,MerchantName,TransactionId,CardId
2026-02-03,8.25,CHF,Storno Synthetic reverse purchase,rev-refund,SYN-CARD-001
r   r   credit_card_reversalr   Freversal_of_transaction_idzSELECT transaction_type,amount_original,reversal_of_transaction_id,notes
           FROM budget_transactions WHERE description LIKE 'Storno %'transaction_typerv  amount_original8.25noteszhSELECT SUM(CAST(amount_chf AS REAL)) FROM budget_transactions WHERE description LIKE '%reverse purchase'ry  periodr   r   net_chfr}  r   r   rV   z
rev-refundzrev-refund-new-idr   r   )r>   rx   r   r^   r7   r   r   r   r   loadsr   r   )r9   purchasepurchase_previeworiginal_idreversalreversal_previewr   r  total
financialsr   same_business_new_provider_idlogical_overlaps                r=   Ctest_unique_reversal_deterministically_offsets_original_transactionr    s   ::D) ^
 
 H "8h!G!GHT?8=M#N#NOOO,,n hjjK
 	) b
 
 H 0h??
6
"1
%C $::::: !U****'s2222T?8=M#N#NOOO\\	I  hjj  $%11116+,--@@@@./;>>>>:fWo&&'CDSSSSLLr hjjE A::::0iHHHJm$....i F****-.!3333(x88IVQ.2BBBBB) )!,Z8@@Obcc
 
 %! /t5RSSO6"1%&67;WWWWW6"1%m4@@@@@@r?   c                    t                      } ddddgi}t          | |          \  }}t          | t          ||                     ddddgi}t	          | |          }|d         d         d         d	k    sJ |d         d         d
         du sJ |d         du sJ t          | t          ||                     |                     d                                          d         dk    sJ d S )NrS   r5   zDate,Amount,Currency,MerchantName,TransactionId,CardId
2026-02-01,-8.25,CHF,Repeated purchase,amb-1,SYN-CARD-001
2026-02-02,-8.25,CHF,Repeated purchase,amb-2,SYN-CARD-001
rT   zwDate,Amount,Currency,MerchantName,TransactionId,CardId
2026-02-03,8.25,CHF,Storno Repeated purchase,amb-r,SYN-CARD-001
r   r   r   credit_card_reversal_unmatchedr   Trt   zJSELECT COUNT(*) FROM budget_transactions WHERE description LIKE 'Storno %')r>   rx   r   r^   r   r7   r   )r9   	purchasesr  r  r  s        r=   Dtest_ambiguous_reversal_remains_review_and_never_posts_automaticallyr  F  sA   ::D)N
 
 	I #9y"I"IIT?9>N#O#OPPP 	) T
 
 H 0h??F#A&'78<\\\\\F#A&'89TAAAA89TAAAAT?8=M#N#NOOO<<deennppqrswxxxxxxxr?   c                    t                      } d}d                    d t          d          D                       }||z   dz   }dd|dgi}t          | |          }t	          | t          ||                     t          |           }t          d	 |d
         D                       }d|d         v r
|d         du sJ | j        }t          | |d         dd          }	| j        |k    sJ |d         d|	d         |	d         d}
t          | |
          }|d         dk    r
|d         du sJ |                     d                                          }t          |          dk    sJ t          | ddddd          }|d          dk    sJ |d!         d"         d#         dk    sJ |d!         d"         d$         dk    sJ t          | d%&          d          d"k    sJ t          | |
          d         du sJ d S )'N7TransactionId,CardId,Date,Amount,Currency,MerchantName
r   c              3  \   K   | ]'}d | d|dk     rdnd d|dk     r|dz   n|dz
  dd	V  (d
S )zSAFE-z,SYN-CARD-001,2026-   0102-r      r   ,-3.00,CHF,Migros
NrJ   r   s     r=   r   zUtest_review_expense_preview_confirm_is_bound_atomic_and_idempotent.<locals>.<genexpr>f  s         	J  	J  	J%"**$$$  	J  	JV[^`V`V`QRfknpfp  	J  	J  	J  	J     r?   !   z@RV-1,SYN-CARD-001,2026-02-28,-8.25,CHF,Synthetic review expense
rS   r5   rT   c              3  2   K   | ]}|d          dk    |V  dS )r_  zExpense CandidateNrJ   rg   rp   s     r=   r   zUtest_review_expense_preview_confirm_is_bound_atomic_and_idempotent.<locals>.<genexpr>q  s1      [[$d7mGZ6Z6Z6Z6Z6Z6Z[[r?   ra  rd   rc  can_confirmTrd  re  r\   r]   )rd  rf  r\   r]   confirmed_countr   r   FztSELECT transaction_type,amount_original,status FROM budget_transactions WHERE description='Synthetic review expense')rd   z-8.25rw  ry  r$   ImportzSynthetic review expensereviewed)r  accountrY   merchantr   r  rr   r   review_statussource_labelignored)r   )r>   r   r   r   r   r^   r   rg  r   r   r   r7   r   r~  r   )r9   headerknownrV   r   import_previewr   ri  r(  rj  requestr  r  filtereds                 r=   Btest_review_expense_preview_confirm_is_bound_atomic_and_idempotentr  c  s   ::DGFGG  2YY    E ~KH %7XNNOPG-dG<<NT?7N#K#KLLL!$''F[[&"2[[[[[E1222u]7Kt7S7S7SSF4E+.)DD N '''';'-.CD ./E F	 G -T7;;F#$))f\.Be.K.K.KK		7
 
 hjj  9999999*Y+J  H G!!!!GQ0J>>>>GQ/8;;;;&tI>>>wG1LLLL*499,G4OOOOOOr?   c                    t                      } d}dd|dgi}t          | |          }t          | t          ||                     |                     d                                          d         }d}dd|dgi}t          | |          }|d	         d         d
         dk    sJ t          | t          ||                     |                     d                                          }t          |          d |dfk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                    dd          }	dd|	dgi}
t          | |
          }|d	         d         d
         dk    sJ t          | t          |
|                     |                     d                                          d         dk    sJ |                     d                                          }|J |                     d                                          d         dk    sJ d S )NzpTransactionId,CardId,Date,Amount,Currency,MerchantName
MX-1,SYN-CARD-001,2026-03-01,-10.00,CHF,Migros Synthetic
rS   r5   rT   5SELECT budget_transaction_id FROM budget_transactionsr   zDatum;Zeit;Filiale;Kassennummer;Transaktionsnummer;Artikel;Umsatz
2026-03-01;12:00;Synthetic Store;1;100;A;4.00
2026-03-01;12:00;Synthetic Store;1;100;B;6.00
r  r  r  r  QSELECT money_candidate_id,money_transaction_id,status FROM household_migros_linksr  r   zISELECT COUNT(*) FROM budget_transactions WHERE transaction_type='expense'r   z;100;z;102;r   r
  zjSELECT money_candidate_id,money_transaction_id,status FROM household_migros_links WHERE status='unmatched'z+SELECT COUNT(*) FROM household_migros_linksr>   r   r   r^   r7   r   r~  r   )r9   r#   money_payloadmoney_previewtransaction_idr  receipt_payloadreceipt_previewlinksecond_receiptsecond_payloadsecond_previewsecond_links                r=   Ctest_migros_receipt_links_to_existing_money_movement_across_batchesr    s   ::DD+=4PPQRM,T=AAMT?=-#P#PQQQ\\"YZZcceefghN@G ->G!T!T UVO.t_EEO?+A.x8HDDDDT??O#T#TUUU<<klluuwwD;;4:::::<<GHHQQSSTUVZ[[[[[<<cddmmoopqrvwwwww__Wg66N,=> Z Z[\N-dNCCN/*1-h7;FFFFT?>>#R#RSSS<<K hjj    ,,	#  hjj  <<EFFOOQQRSTXYYYYYYYr?   c                 <   t                      } d}dd|dgi}t          | |          }t          | t          ||                     |                     d                                          d         }d}dd|dgi}t          | |          }|d	         d         d
         dk    sJ t          | t          ||                     |                     d                                          }t          |          d |dfk    sJ dd|                    dd          dgi}	t          | |	          }
|
d	         d         d
         dk    sJ t          | t          |	|
                     |                     d                                          d         dk    sJ d S )NzqTransactionId,CardId,Date,Amount,Currency,MerchantName
MX-2,SYN-CARD-001,2026-03-02,-10.00,CHF,Migros Productive
rS   r5   rT   r  r   zDatum;Zeit;Filiale;Kassennummer;Transaktionsnummer;Artikel;Umsatz
2026-03-02;12:00;Synthetic Store;1;101;A;4.00
2026-03-02;12:00;Synthetic Store;1;101;B;6.00
r  r  r  r  r  z;101;z;103;r   r
  r   r  )r9   r#   r  r  r  r  r  r  r  r  r  s              r=   Jtest_migros_receipt_links_to_productive_transaction_not_consumed_candidater    s   ::D AD+=4PPQRM,T=AAMT?=-#P#PQQQ\\"YZZcceefghN	: 
 ->G!T!T UVO.t_EEO?+A.x8HDDDDT??O#T#TUUU<<klluuwwD;;4::::: 	/W__WV]=^=^__`N .dNCCN/*1-h7;FFFFT?>>#R#RSSS<<K hjj     r?   c                    t                      fd} t          d          }| |j        t          <   t	          |          }|                    d                                          d         }d}t          |                              |          sJ j	        }|dd         D ]E}|                    |          }|j
        d	k    sJ |j                    d
|j        vr	d|j        vsJ Fj	        |k    sJ |                    d                                          }h d                    |          sJ |                    d                                          }	h d                    |	          sJ |                    d                                          }
|
d         du rd|
v sJ |dd          D ]"}|                    |i           j
        dv sJ #d S )Nc               3     K    V  d S r  rJ   r  s   r=   r  zItest_plural_api_and_read_models_are_side_effect_free.<locals>.override_db  r  r?   r  r  r  r  )
%/api/budget/household/imports/preview%/api/budget/household/imports/confirmz%/api/budget/household/imports/optionsz%/api/budget/household/imports/historyz/api/budget/household/importsz/api/budget/household/overviewz"/api/budget/household/transactions/api/budget/household/reviewz$/api/budget/household/review/previewz$/api/budget/household/review/confirmr      r  r   rV   z,/api/budget/household/overview?month=2026-01>   r{  r|  balance_chfdata_statusr   review_countz1/api/budget/household/transactions?period=2026-01>   rr   r  has_more	total_all
page_countnext_cursorfiltered_totalr  unsafe_groups_can_confirmFra  r!  >     r   rB  )r>   r
   r#  r	   r   rf   r   setr   r   r   rE   r$  )r  r%  r&  r  requiredr(  r'  responser  transactionsr   r9   s              @r=   4test_plural_api_and_read_models_are_side_effect_freer    s'   ::D    

'
'
'C'2CV$__FJJ'',,..w7E8H x==!!%(((((F1 O O::d###s***HM***X]**z/N/N/NN/N''''zzHIINNPPH___hhiqrrrrr::QRRWWYYLeeenno{|||||ZZ677<<>>F-.%77H<N<N<NN I I{{4b{))5HHHHHI Ir?   monkeypatchpytest.MonkeyPatchc           	     D   |                      dd           t                      fd}t          d          }||j        t          <   t          |          }d}dd|d	gi}|                    d
|          }|j        dk    sJ |j                    |	                                d         d         }d|d|d         |d         d}|                    dddi|          }	|	j        dk    sJ |                    dddi|d|d         d d         iz            }
|
j        dk    sJ |                    dddi|          j        dk    sJ j                    	                                }d|d         |d         t          |d                   |d         |d         |d          |d!         d"}t          j        t          j        |d#d$d%                                                                                    |d&<   |                    d
i |d'|gi          }|j        dk    sJ i |d'	                                gi}|                    d
|          }|j        dk    sJ |j                    |	                                }|d(         du sJ d) |d*         D             d+hk    sJ t!          ||          }|                    d,|          }|j        dk    sJ |j                    |                    d,|          }|j        dk    sJ |	                                d-         du sJ |                     t$          j        d.fd/           |                    d,|          }|j        d0k    sJ |                    d1          	                                }|d2         d3k    sJ |d4         d3k    sJ                     d5                                          }t          j        |d6                   }|d7         dk    sJ |d8         dk    sJ d S )9N$JARVIS_FINANCE_OPERATOR_APPROVAL_KEYzsynthetic-operator-keyc               3     K    V  d S r  rJ   r  s   r=   r  zotest_authenticated_owner_attestation_api_binds_exact_cluster_and_confirms_neutral_transfer.<locals>.override_db  r  r?   r  r  zIBAN;Booked At;Text;Credit/Debit Amount;Valuta Date
SYN-RAI-001;2026-07-01;Synthetic Household Counterparty;-20.00;2026-07-01
SYN-RAI-001;2026-07-02;Synthetic Household Counterparty;-30.00;2026-07-02
rS   r+   rT   r  r!  r  merchant_clustersr   T.owner_attested_known_household_counterparty_v1cluster_token
row_tokens)confirm_owner_attestationpreview_requestapproval_evidencer  approved_row_tokensz</api/budget/household/imports/owner-neutral-cluster-approvalzX-Jarvis-Operator-Approvalwrong)headersr   r"  r  r   rB  -owner_confirmed_neutral_household_transfer_v2r  approval_baseline_fingerprintapproval_issued_atapproval_expires_atapproval_nonce)scoper  r  r  r]   	issued_at
expires_atnonceF),:)ensure_ascii
separators	sort_keysapproval_tokencluster_decisionsrt   c                    h | ]
}|d          S )rn   rJ   r  s     r=   r   zmtest_authenticated_owner_attestation_api_binds_exact_cluster_and_confirms_neutral_transfer.<locals>.<setcomp>6  s    GGGdD()GGGr?   rr   !user_confirmed_unmatched_transferr  r   timec                 X    t                                           d                   dz   S )Nr  r   )intr   )approveds   r=   <lambda>zltest_authenticated_owner_attestation_api_binds_exact_cluster_and_confirms_neutral_transfer.<locals>.<lambda>H  s"    HMMOO$9:;;a? r?   r   z,/api/budget/household/overview?month=2026-07r|  r   r   zkSELECT new_values_json FROM audit_log WHERE action='household_import_confirmed' ORDER BY rowid DESC LIMIT 1new_values_json$owner_attested_neutral_cluster_count"owner_attestation_evidence_version)setenvr>   r
   r#  r	   r   r$  r   rE   r   sortedhashlibsha256r   encode	hexdigestr^   setattrhousehold_import_servicer  rf   r7   r   r  )r  r  r%  r&  rV   r   baseclusterapproval_bodydeniedsubsetforged_decisionpublic_materialforged_previewsigned_payloadpreview_responserZ   confirm_requestrw  immediate_replayexpired_replayr  r   audit_valuesr  r9   s                           @@r=   Ztest_authenticated_owner_attestation_api_binds_exact_cluster_and_confirms_neutral_transferr    sL    =?WXXX::D     
'
'
'C'2CV$__F	V 
 %6HMMNOG;;>W;MMDs"""DI"""iikk-.q1G%)"M 1&|4 M [[F-w7   F
 $$$$[[F-/GH3W\5J2A25NOO   F
 $$$${{F-/GH   H
 3&&&&&&mmooO@,-@A(9_-BCDD /0O P$%9:%&;< !12	 	O )0
?:Y]^^^eegg) )ikk $% [[/@@,.?@@ !  N %,,,,HH!4x}}6GHHN{{#JQ_{``'3...0@0E...##%%G/0D8888GGgg6FGGG+L     &ng>>O/   I  C''''''{{/ #   '3....  ""<0D8888 %????  
 [[/ !  N %,,,,zzHIINNPPHL!V++++M"f,,,,LLu hjj 
 :e$5677L>?1DDDD<=8     r?   c                 	   t                      d} d                    d t          d          D                       }dd| |z   dz   dgi}t          |          }t	          t          ||                     t                              d	                                                                        d
                                          }                    d                                          }d dd ddOfd} |ddd|d            |ddd|d            |ddd|             |d!dd"|             |d#d$d%d&'                               d(                               d)                               d*|d+         f           	                                 t          d,-          }|d.         |d/         |d0         |d1         fd2k    sJ |d3         |d.         k    r|d4         d5k    sJ d6 |d7         D             ddhk    sJ t          |d8                   d,k    r|d9         d:u r|d;         sJ t          d,|d;         <          }|d=         |d=         k    sJ |d8         d+         d>         |d8         d+         d>         k    sJ                     d?           	                                 t          j        t                    5 }	t          d,|d;         <           d d d            n# 1 swxY w Y   |	j        j        d@k    sJ t          d,-          }
                    dA|d+         f           	                                 t          j        t                    5 }t          d,|
d;         <           d d d            n# 1 swxY w Y   |j        j        d@k    sJ t          dBd:C          }|d.         d5k    r|d4         d,k    sJ |d8         d+         dD         dEk    sJ |d8         d+         dF         dGu sJ t          dBdHI          }|d4         dJk    sJ t#          dK |d8         D                       sJ t          dBd/I          }|d4         d,k    sJ dL |d8         D             d/hk    sJ t          dBd0I          }|d4         dMk    sJ dN |d8         D             d0hk    sJ d S )PNr  r   c              3  0   K   | ]}d | d|dz   ddV  dS )zSAFE-R-z,SYN-CARD-001,2026-03-r   r   r  NrJ   r   s     r=   r   zQtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.<genexpr>_  sQ         	R%QQuqyQQQQ     r?      rS   r5   zBOPEN-1,SYN-CARD-001,2026-03-25,-8.25,CHF,Synthetic review expense
rT   zXSELECT * FROM budget_transaction_candidates WHERE description='Synthetic review expense'zdSELECT category_id,name FROM budget_categories WHERE is_active=1 AND category_type='expense' LIMIT 1zcSELECT category_id,name FROM budget_categories WHERE is_active=1 AND category_type='income' LIMIT 1)proposedr/   signed_amountcandidate_idrD   r  r   r$  
str | Noner   ry   c               v   	| |||| | d|  d|  |r|d         nd |r|d         nd |p	d         |p	d         dt          |            dd	z  t                    }                    d
d                    |           dd                    d |D                        dfd|D                        d S )Nzrow-zlogical-r   r   r  signed_amount_originalz2026-03-25T00:00:0Z)transaction_candidate_idr/   r  r   descriptionr  rH  rI  proposed_category_idproposed_category_namer  r(  
updated_atz*INSERT INTO budget_transaction_candidates(r  z
) VALUES (c              3     K   | ]}d V  dS )?NrJ   )rg   _s     r=   r   z`test_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.clone.<locals>.<genexpr>  s$      [n[nde\_[n[n[n[n[n[nr?   )c                     g | ]
}|         S rJ   rJ   )rg   r:   r   s     r=   r   zatest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.clone.<locals>.<listcomp>  s    &&&#SX&&&r?   )r   listr7   r   )
r%  r  r   r#  r/   r$  keysr   r9   originals
          @r=   clonezMtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.clonep  s    (4&,'$&;\&;&;#<l#<#<3;$EHQKK5=&Ghqkk4,K9J0K&3&Yx@X7YCs</@/@CCC
 
 
 Cyyq$qqSVS[S[[n[nim[n[n[nSnSnqqq&&&&&&&	
 	
 	
 	
 	
r?   proposalneeds_reviewincome_candidater  )r  r   r#  r$  zwrong-proposalrd   r+   )r  r   r#  r/   zinactive-proposal)r  r   r#  specialr   coveredcovered_by_sourcemigros_receipt_detailr  )r  r   r/   zdUPDATE budget_transaction_candidates SET requires_review=0 WHERE transaction_candidate_id='proposal'zUPDATE budget_transaction_candidates
           SET status='pending',requires_review=1,classification='possible_logical_duplicate'
           WHERE transaction_candidate_id='covered'z<UPDATE budget_categories SET is_active=0 WHERE category_id=?r   r   )limit
total_openrm   decision_neededspecial_cases)   r      r   r  r  rC  c                    h | ]
}|d          S )r   rJ   r  s     r=   r   zQtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.<setcomp>  s    >>>dDM>>>r?   source_optionsrr   r  Tr  )r?  cursordata_version
item_tokenzqUPDATE budget_transaction_candidates SET amount_original='999.00' WHERE transaction_candidate_id='wrong-proposal'r   a1  INSERT INTO budget_review_rules(
             rule_id,merchant_contains,source_type,category_id,target_status,is_active,
             priority,confidence,created_at,updated_at)
           VALUES ('review-rule-mutation','wrong-proposal','raiffeisen_bank',?,'review',1,
                   100,'1.0','x','x')   )r?  special_onlyrl   special_caser  Fneeds_decision)r?  state   c              3  .   K   | ]}|d          dk    V  dS )rl   rm   NrJ   r  s     r=   r   zQtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.<genexpr>  s-      ZZ$tL!%55ZZZZZZr?   c                    h | ]
}|d          S rl   rJ   r  s     r=   r   zQtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.<setcomp>      >>>4D>>>r?   rD  c                    h | ]
}|d          S rR  rJ   r  s     r=   r   zQtest_review_summary_is_canonical_filtered_and_cursor_paginated.<locals>.<setcomp>  rS  r?   )
r%  rD   r  rD   r   rD   r$  r&  r   ry   )r>   r   r   r   r   r^   rQ   r7   r   r8   r   r   r   r   r   r   r   r   )r  r  r   rZ   expense_categoryincome_categoryr7  r   r   stale_reviewfreshstale_classifierr;  rM  	proposals	decisionsr9   r6  s                   @@r=   >test_review_summary_is_canonical_filtered_and_cursor_paginatedr\  \  s   ::DGFGG  2YY    E %7Ve^  W\  F\  ]  ]  ^  _G&tW55GT?7G#D#DEEEDLLb hjj H ||n hjj  llm hjj  &$(
 
 
 
 
 
 
 
 
< 
E)     
E  %    
E
nYYijjjj	E)N;Wbrssss	E)/@Wevwwww 	LLwxxxLL	7  
 	LLORbcdReQghhhKKMMM Q///E,'7!8%@Q:RTYZiTjko{{{{{ E,$777EBR<SWX<X<X<XX>>e,<&=>>>CUWhBiiiiiuW~!##j(9T(A(AeMFZ(A(AZ!$am8LMMMF.!U>%:::::'?1l+uW~a/@/NNNNNLL{   	KKMMM	}	%	% IT53GHHHHI I I I I I I I I I I I I I I)S0000 Q///ELL	)
 
!	   	KKMMM	}	%	% I)9T53GHHHHI I I I I I I I I I I I I I I!-4444"4rEEEG< A%%'2B*Cq*H*H*HH7A|,>>>>7A}-6666)$b@PQQQN*+q0000ZZ.QXBYZZZZZZZZ$T;KLLLI%&!++++>>9W+=>>>CSBTTTTT$T;LMMMI%&!++++>>9W+=>>>CTBUUUUUUUs$   'LLLN))N-0N-c                 X  	 t                      		                    d                                          d         } 	                    d| f                                          d         }	                    d                                          d         }dEdF	fd} |ddd|             |ddd|            |dddd d           	                    dt          j        ddi          f            |ddd            |ddd            |ddd           	                                 t          	d          }|d         dk    sJ |d         d k    sJ |d!         d"k    sJ |d#         d$k    sJ |d%         d&k    sJ |d'         d(k    sJ t          d) |d*         D                       t          d           k    sJ t          d+ |d*         D                       t          d          k    sJ t          	d,          }|d         |d         |d-         fd.k    sJ |d/         d0k    sJ |d%         d1         d&k    sJ d2|d%         d3         v sJ 	                    d4           	                                 t          	dd(5          }|d6         d7k    r|d8         d7k    r|d9         d(k    sJ |d:         d;u r|d<         sJ 	                    d=           	                                 t          j        t                    5 }t          	dd(|d<         >           d d d            n# 1 swxY w Y   |j        j        d?k    sJ t          	d|d@A          }|d8         d(k    sJ dB |dC         D             ddhk    sJ dD |dC         D             |hk    sJ d S )GNz_SELECT category_id FROM budget_categories WHERE is_active=1 AND category_type='expense' LIMIT 1r   z6SELECT name FROM budget_categories WHERE category_id=?z^SELECT category_id FROM budget_categories WHERE is_active=1 AND category_type='income' LIMIT 1tx_idrD   tx_typerC   r   ry   c                D                         d| d|| ||||f           d S )Na  INSERT INTO budget_transactions(
                 budget_transaction_id,account_id,transaction_type,transaction_date,description,
                 amount_original,currency_original,amount_chf,fx_status,category_id,status,source_type,
                 reversal_of_transaction_id,created_at,updated_at)
               VALUES (?,?,?,'2026-04-15',?,?,'CHF',?,'not_needed',?,'confirmed','manual',?,'2026-04-15T00:00:00Z','2026-04-15T00:00:00Z')r-   r7   r^  r_  rC   re   r  r9   s        r=   transactionz\test_financial_semantics_reconcile_refunds_transfers_categories_and_net.<locals>.transaction  s?    N
 JXV	
 	
 	
 	
 	
r?   rd   r@   rc   200.00zlinked-refundrv  20.00zrUPDATE budget_transactions SET reversal_of_transaction_id=NULL,notes=? WHERE budget_transaction_id='linked-refund'r  zunlinked-refundz5.00ztransfer-outtransferz-50.00zcard-settlement50.00z2026-04r  r|  r   80.00r  120.00r}  r   r  partialneutral_transfer_countr   c              3  @   K   | ]}t          |d                    V  dS )r   Nr   r~   s     r=   r   zZtest_financial_semantics_reconcile_refunds_transfers_categories_and_net.<locals>.<genexpr>  s/      LLsws=)**LLLLLLr?   rj   c              3  @   K   | ]}t          |d                    V  dS )r|  Nr   r~   s     r=   r   zZtest_financial_semantics_reconcile_refunds_transfers_categories_and_net.<locals>.<genexpr>   s/      KKcws<())KKKKKKr?   rz  r  )rd  rh  ri  neutral_transfers_chfr   r  u!   nicht verknüpfte RückerstattungmessagezeUPDATE budget_transactions SET updated_at='2026-04-17T00:00:00Z' WHERE budget_transaction_id='income')r  r?  r     r  r  r  Tr  zXUPDATE budget_transactions SET amount_chf='999.00' WHERE budget_transaction_id='expense')r  r?  rG  r   
   r  rh   r?  c                    h | ]
}|d          S )r  rJ   r  s     r=   r   zZtest_financial_semantics_reconcile_refunds_transfers_categories_and_net.<locals>.<setcomp>  s    HHHD#$HHHr?   rr   c                    h | ]
}|d          S )category_namerJ   r  s     r=   r   zZtest_financial_semantics_reconcile_refunds_transfers_categories_and_net.<locals>.<setcomp>  s    EEEdD!EEEr?   )NN)r^  rD   r_  rD   rC   rD   r   ry   )r>   r7   r   r   r   r8   r   sumr   r   r   r   r   r   r   r   )
rU  expense_category_namerV  rc  summaryr  pagestalecategory_pager9   s
            @r=   Gtest_financial_semantics_reconcile_refunds_transfers_categories_and_netr|    s   ::D||i hjj !LL@	  hjj llh hjjO
 
 
 
 
 
 
 K	9i1ABBBK(Ho>>>K7D)DDDLL|	19=	>	>@   K!8V444K
H555K!:w777KKMMM-d9EEEG< H,,,,=!W,,,,9))))*+q0000=!Y....+,1111LLgl6KLLLLLPWX_P`P`````KKW\5JKKKKKwW_O`O`````%d)<<<H\"H]$;Xm=TUYvvvvv+,6666M"8,	9999.(=2I)2TTTTTLLo   	KKMMM&tIQGGGD!!d+;&<&A&Ad<FX\]F]F]F]]
t##](;##;LLklllKKMMM	}	%	% a#D!DQ^L_````a a a a a a a a a a a a a a a;"c))))/&	  M )*a////HHw1GHHHYX`LaaaaaEEmG.DEEEJ_I```````s   L99L= L=c                    t                      } |                     d                                          d         }|                     d|f           |                                  t	          | d          }|d         dk    r|d         dk    sJ |d	         d
k    r|d         dk    sJ t          | d          }|d         dk    sJ |d	         d
k    sJ |d         d         dk    sJ t          | d          }|d	         d
k    sJ |d         dk    sJ t          | d          }|d         d         d         J |d         d         d         dk    sJ |d         d         d         dk    sJ d S )N_SELECT category_id FROM budget_categories WHERE category_type='expense' AND is_active=1 LIMIT 1r   a  INSERT INTO budget_transactions(
             budget_transaction_id,account_id,transaction_type,transaction_date,description,
             amount_original,currency_original,amount_chf,fx_status,category_id,status,source_type,
             created_at,updated_at)
           VALUES ('foreign-missing','bacc_rai','expense','2026-05-01','Synthetic foreign',
                   '100.00','EUR',NULL,'missing',?,'confirmed','manual','x','x')z2026-05r  r   r   r  unavailable_chf_countr   r  rj  rz  r  rr   
amount_chfr  rM   r   EUR)r>   r7   r   r8   r   r   r   r   )r9   re   rx  r  monthlyry  s         r=   Ftest_unconverted_foreign_currency_is_partial_and_never_invented_as_chfr    s   ::D,,i hjjK 	LL	T 
   	KKMMM-d9EEEG=!V++	0Bf0L0L0LL*+q00W]5Ky5X5X5XX%d)<<<HM"f,,,,+,1111M"8,	9999!$i888G*+q0000=!Y....&tI>>>D=L)111=-.(::::=J'5000000r?   c            	        t                                          d                                          d         }                     d                                          }|d         }d8d9fd} |ddd|             |ddd|            |ddd| d            |ddd| d            |ddd| d                                            t	          d          }|d         |d         |d         fdk    sJ |d          d!k    r|d"         d#k    sJ t          dt          |d$                   d%&          }|d'         d(k    sJ |d)         d         d*         dk    sJ t          d+,          }t          d- |d.         D                       }|d"         d#k    sJ d/dd0d1d2d3| dd4}t          j
        t                    5 }	t          |           d d d            n# 1 swxY w Y   |	j        j        d5k    sJ t          j
        t                    5 }
t          |d6dd7z             d d d            n# 1 swxY w Y   |
j        j        d5k    sJ d S ):Nr~  r   zcSELECT category_id,name FROM budget_categories WHERE category_type='income' AND is_active=1 LIMIT 1re   r^  rD   r_  rC   r  r&  r   ry   c                F                         d| || ||||| | f	           d S )Na  INSERT INTO budget_transactions(
                 budget_transaction_id,account_id,transaction_type,transaction_date,description,
                 amount_original,currency_original,amount_chf,fx_status,category_id,status,source_type,
                 reversal_of_transaction_id,created_at,updated_at)
               VALUES (?, 'bacc_rai', ?, '2026-06-01', ?, ?, 'CHF', ?, 'not_needed', ?,
                       'confirmed','manual',? ,?,?)ra  rb  s        r=   rc  zPtest_refund_links_are_eligible_bounded_and_writer_validated.<locals>.transactionG  sA    7 GUFFK5RWX	
 	
 	
 	
 	
r?   zexpense-originrd   rM   zincome-originrc   zrefund-validrv  z60.00zrefund-excessrg  zrefund-incomere  2026-06r  r|  r   r  )rM   rg  rg  r}  r   r  rj  namerq  rr  r  r   rr   r  2026yearc              3  2   K   | ]}|d          dk    |V  dS r{  r  NrJ   r~   s     r=   r   zNtest_refund_links_are_eligible_bounded_and_writer_validated.<locals>.<genexpr>i  0      XXc'li>W>W>W>W>W>WXXr?   cashflow_by_monthr-   
2026-06-02zSynthetic invalid refundr   r   )rh  r  transaction_dater+  r  currency_originalre   r  rB  zSynthetic excessive refund)r+  r  r  )r^  rD   r_  rD   rC   rD   re   rD   r  r&  r   ry   )r>   r7   r   r8   r   r   rD   r   rg  r   r   r   r   r   r   r   )rU  income_category_rowrV  rc  rx  income_pagechartsjuneinvalid_income_linkinvalid_origin	excessiver9   s              @r=   ;test_refund_links_are_eligible_bounded_and_writer_validatedr  =  s   ::D||i hjj ,,m hjj  *-8O	
 	
 	
 	
 	
 	
 	
 K )X7GHHHK8_EEEK'3CEUVVVK74DFVWWWK74DoVVVKKMMM-d9EEEGL!7=#979;MN S    
 *+q00W]5Ky5X5X5XX-(011	  K '(A----w"#56(BBBB#Dv666FXXv&9:XXXXXD)++++ !$(1""'&5	 	 
}	%	% E)$0CDDDE E E E E E E E E E E E E E E+s2222	}	%	% 
";.># # 	
 	
 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 ?&#------s$   G%%G),G)H>>IIc                    t                      } |                     d           |                                  t          | d          }|d         dk    sJ |d         J |d         dk    sJ |d         dk    r|d	         d
k    sJ t	          | d          }|d         J |d         dk    r|d	         d
k    sJ t          | d          }t          d |d         D                       }|d	         d
k    sJ d S )Na  INSERT INTO budget_transactions(
             budget_transaction_id,account_id,transaction_type,transaction_date,description,
             amount_original,currency_original,amount_chf,fx_status,status,source_type,created_at,updated_at)
           VALUES ('foreign-transfer','bacc_rai','transfer','2026-06-01','Synthetic FX transfer',
                   '100.00','EUR',NULL,'missing','confirmed','manual','x','x')r  r  rk  r   neutral_transfer_volume_chfunavailable_transfer_countr  r  rj  rz  r  r  c              3  2   K   | ]}|d          dk    |V  dS r  rJ   r~   s     r=   r   zJtest_missing_fx_transfer_volume_is_unavailable_not_zero.<locals>.<genexpr>  r  r?   r  )r>   r7   r8   r   r   r   rg  )r9   rx  r  r  r  s        r=   7test_missing_fx_transfer_volume_is_unavailable_not_zeror    sI   ::DLL	R   	KKMMM-d9EEEG+,111101999/0A5555*+q00W]5Ky5X5X5XX!$i888G01999/0A55'-:PT]:]:]:]]#Dv666FXXv&9:XXXXXD)++++++r?   c                 f   t                      } t          | ddddddd           t          | d	          }|d
         dk    sJ |d         dk    sJ |d         dk    sJ t          | d          }|d         dk    sJ |d         dk    sJ dD ]"}t          | d|          }|d         dk    sJ #|                     d           t          | d	          }|d         dk    sJ |d
         dk    sJ |d         J |d         dk    sJ |d         dk    sJ |d         dk    sJ d |d         D             dgk    sJ t          | d          }|d         dk    sJ |d         dk    sJ t          | d          }t          d |d          D                       }|d         dk    sJ |                     d!           t          | d"d#d$          d%         t          | dd#dd&d'dd(           t          | ddd)ddd*d           |                     d+          
                                }	|                     d,          
                                d         }
|                     d-           t          |	d.          D ]5\  }}|                     d/d0| |
|ddt          |d1z            df           6t          | d	          }|d         d2k    sJ |d
         d3k    sJ |d4         d'k    sJ t          fd5|d6         D                       d'k    sJ |d         J |d         d.k    sJ |d         d.k    sJ t          | d          }|d         d7         dk    sJ |d         d.k    sJ |                     d8           |                     d9           t          | dd:d;d<d=dd>           t          | d	          }|d
         d?k    sJ |d         d@k    sJ t          | ddd'dAdBdCd           t          | dD	          }|d
         dk    sJ |d         J |d         d.k    sJ d S )ENr-   r4   z900.00r   r  zSynthetic internal transfer)from_account_idto_account_idr  r  r  r+  r  r  rk  r   r  r  r   rz  rn  r   )r    r"   )r  r  a  INSERT INTO budget_transfers(
             transfer_id,from_transaction_id,to_transaction_id,from_account_id,to_account_id,
             amount_original,currency_original,fx_rate_to_chf,created_at,transfer_type)
           SELECT 'duplicate-membership',from_transaction_id,to_transaction_id,from_account_id,to_account_id,
                  amount_original,currency_original,fx_rate_to_chf,'x',transfer_type
           FROM budget_transfers LIMIT 1confirmed_transaction_countr  "transfer_membership_conflict_countr  rj  c                    g | ]
}|d          S )r4  rJ   r  s     r=   r   zRtest_paired_transfer_volume_is_counted_once_and_unmatched_once.<locals>.<listcomp>  s    :::TDL:::r?   warningstransfer_membership_conflictr  r  c              3  2   K   | ]}|d          dk    |V  dS r  rJ   r~   s     r=   r   zQtest_paired_transfer_volume_is_counted_once_and_unmatched_once.<locals>.<genexpr>  s4      jjPST[P\`iPiPiPiPiPiPijjr?   r  zEDELETE FROM budget_transfers WHERE transfer_id='duplicate-membership'zMalformed membership categoryrd   )r  rb   	entity_idzMalformed membership expenserg  )rh  re   r  r  r+  r  r  z30.00z Malformed membership counterpartz`SELECT from_transaction_id,to_transaction_id FROM budget_transfers WHERE amount_original='30.00'zfSELECT budget_transaction_id FROM budget_transactions WHERE description='Malformed membership expense'z:DELETE FROM budget_transfers WHERE amount_original='30.00'r   a   INSERT INTO budget_transfers(
                 transfer_id,from_transaction_id,to_transaction_id,from_account_id,to_account_id,
                 amount_original,currency_original,created_at,transfer_type)
               VALUES(?,?,?,?,?,?,?,'x','internal')z
malformed-rq  rC  rO  r   c              3  @   K   | ]}|d          k    |d         V  dS )re   r   NrJ   )rg   r   malformed_categorys     r=   r   zQtest_paired_transfer_volume_is_counted_once_and_unmatched_once.<locals>.<genexpr>  sE        }!333 	M3333 r?   rj   r  zADELETE FROM budget_transfers WHERE transfer_id LIKE 'malformed-%'zNDELETE FROM budget_transactions WHERE description LIKE 'Malformed membership%'rf  z
2026-06-03zSynthetic unmatched transferrM   )rh  r  r  r+  r  r  rD  z1000.00r  z
2026-07-02zSynthetic unconverted pairz2026-07)r>   r   r   r   r7   r   r   rg  r   r   r   	enumeraterD   )r9   rx  r  account_namescopedconflictconflict_monthconflict_chartsconflict_junemalformed_pair
expense_idr   counterpart_id	malformedmalformed_overviewwith_unmatchedunavailable_pairr  s                    @r=   >test_paired_transfer_volume_is_counted_once_and_unmatched_oncer    s5   ::DT%##"(4     .d9EEEG+,111101X====/0A5555%d)<<<H+,666612h>>>>6 A A0iQ]^^^34@@@@@LL	,   /tIFFFH12a7777,-222212:::+,111189Q>>>>M"i////::Xj%9:::?]>^^^^^(Y???N>?1DDDD-(I5555,T???Ojj8K(LjjjjjM'94444LLXYYY06SS  t 1CYb(9W"& &   
 T%
W^"9    
 \\j hjj  p hjjJ 	LLMNNN!*>1!=!= 
 
~7 "%!!:~z:WZ[`ce[eWfWfhmn	
 	
 	
 	
 0YGGGI23q8888-.!3333]#w....    \*     
	   
 23;;;12a77779:a????/IFFFm,X6)CCCCBCqHHHHLLTUUULLabbbt &(5#"& &    5T)LLLN23q888878IEEEET%#""(3     7tINNN45::::9:BBB89Q>>>>>>r?   )r   r   )r@   rA   rB   )rC   rD   rE   rD   rF   rD   r   rD   )rM   rN   rB   )r   rQ   )rY   rQ   rZ   rQ   r   rQ   )r9   r   rY   rQ   r   r_   )r   ry   )r  r  r   ry   )V
__future__r   r  r   decimalr   sqlite3r   r   fastapir   fastapi.testclientr   (jarvis_finance.services.household_importserviceshousehold_importr  jarvis_finance.api.dependenciesr	   jarvis_finance.api.mainr
   )jarvis_finance.services.budget_categoriesr   'jarvis_finance.services.budget_overviewr   r   +jarvis_finance.services.budget_transactionsr   r   r   ,jarvis_finance.services.household_financialsr   r   r   r   r   r   r   r   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r>   rL   rP   rX   r^   rx   r   r   r   r   r   r   r   r   r  r  r+  r/  r8  r<  rD  rN  rY  r\  rk  rp  rt  r  r  r  r  r  r  r  r  r\  r|  r  r  r  r  rJ   r?   r=   <module>r     s   " " " " " "                ! ! ! ! ! ! ) ) ) ) ) ) K K K K K K K K K 2 2 2 2 2 2 . . . . . . M M M M M M _ _ _ _ _ _ _ _         
 Y X X X X X	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ; : : : : : R R R R R R R R   &u u u u ug g g g g   N N N N
   &u u u u0 0 0 0.% % % %2W W W W&V V V V	\ 	\ 	\ 	\n n n n &F &F &F &FRM M M M > > > >0\ \ \ \*
/ 
/ 
/ 
/( ( ( (*, , , ,"G G G G T T T TG G G G2       @w w w w.9 9 9 9X X X X24A 4A 4A 4Any y y y:*P *P *P *PZ Z  Z  Z  ZF   <I I I I>i i i iXvV vV vV vVrEa Ea Ea EaP1 1 1 1@D. D. D. D.N, , , ,.r? r? r? r? r? r?r?   