Output:
Chunk ID: 392fff
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 6100
Output:
              AND instrument_id IS NOT NULL
              AND COALESCE(is_confirmed,0)=1
              AND COALESCE(is_voided,0)=0
              AND lower(transaction_type) IN ('buy','sell','partial_sell','full_sell')
              AND trade_date>? AND trade_date<=?""",
        (*account_ids, snapshot_date, effective_as_of),
    ).fetchall()
    deltas: dict[str, Decimal] = {}
    for row in rows:
        instrument_id = str(row["instrument_id"])
        quantity = abs(_decimal(row["quantity"]))
        if str(row["transaction_type"]) in {"sell", "partial_sell", "full_sell"}:
            quantity = -quantity
        deltas[instrument_id] = deltas.get(instrument_id, Decimal("0")) + quantity
    return deltas

def latest_audited_market_values(
    conn: Connection,
) -> dict[tuple[str, str], AuditedMarketValue]:
    """Return the latest immutable market-analysis values without writing on GET."""

    row = conn.execute(
        """SELECT pas.as_of,pas.summary_json,mdr.completed_at
           FROM portfolio_analysis_snapshots pas
           JOIN market_data_runs mdr ON mdr.run_id=pas.run_id
           ORDER BY pas.as_of DESC,pas.created_at DESC LIMIT 1"""
    ).fetchone()
    if not row:
        return {}
    try:
        payload = json.loads(row["summary_json"] or "{}")
    except json.JSONDecodeError:
        return {}
    values: dict[tuple[str, str], AuditedMarketValue] = {}
    for item in payload.get("positions", []):
        if not isinstance(item, dict) or item.get("quality_status") != "fresh":
            continue
        account_id = str(item.get("account_id") or "")
        instrument_id = str(item.get("instrument_id") or "")
        if not account_id or not instrument_id or item.get("value_chf") in {None, ""}:
            continue
        provenance = item.get("price_input_provenance")
        provider = (
            str(item.get("provider") or "")
            or (str(provenance.get("provider") or "") if isinstance(provenance, dict) else "")
        )
        values[(account_id, instrument_id)] = AuditedMarketValue(
            account_id=account_id,
            instrument_id=instrument_id,
            value_chf=_decimal(item["value_chf"]),
            close=_decimal(item["close"]) if item.get("close") not in {None, ""} else None,
            currency=str(item.get("currency") or ""),
            as_of=str(row["as_of"]),
            completed_at=str(row["completed_at"]),
            provider=provider,
            quantity=(
                _decimal(item["quantity"])
                if item.get("quantity") not in {None, ""}
                else None
            ),
        )
    return values
diff --git a/tests/test_postfinance_sprint13.py b/tests/test_postfinance_sprint13.py
index ecf37e7..08ee0e1 100644
--- a/tests/test_postfinance_sprint13.py
+++ b/tests/test_postfinance_sprint13.py
@@ -1,12 +1,18 @@
 from __future__ import annotations

 import base64
+import json
 from dataclasses import replace
 from decimal import Decimal
 from hashlib import sha256

 import pytest

+from jarvis_finance.dashboard.data import (
+    get_cash_overview,
+    get_command_center_summary,
+    get_positions,
+)
 from jarvis_finance.imports.postfinance_documents import (
     PFBundle,
     PFDocument,
@@ -14,8 +20,18 @@ from jarvis_finance.imports.postfinance_documents import (
     PFSnapshot,
     PFSnapshotCash,
     PFSnapshotPosition,
+    _reconcile_cash_components,
 )
 from jarvis_finance.services import postfinance_service as service
+from jarvis_finance.services.cash_service import get_cash_position_detail, get_cash_summary
+from jarvis_finance.services.equity_service import get_equity_summary
+from jarvis_finance.services.portfolio_aggregation import (
+    latest_official_postfinance_cash,
+    latest_official_postfinance_positions,
+)
+from jarvis_finance.services.portfolio_analytics import confirmed_canonical_positions
+from jarvis_finance.services.portfolio_data import build_portfolio_reconciliation
+from jarvis_finance.services.portfolio_service import get_overview
 from jarvis_finance.storage.database import connect_memory
 from jarvis_finance.storage.migrations import apply_migrations

@@ -23,6 +39,23 @@ DEPOT = "account_pf_depot_test"
 CASH = "account_pf_trading_cash_test"

+def test_cash_component_reconciliation_preserves_negative_balances():
+    reconciled = _reconcile_cash_components(
+        [
+            PFSnapshotCash("EUR", Decimal("-100"), Decimal("1"), Decimal("-100")),
+            PFSnapshotCash("USD", Decimal("20"), Decimal("1"), Decimal("20")),
+        ],
+        Decimal("-80.01"),
+    )
+    assert [item.source_value_chf for item in reconciled] == [
+        Decimal("-100.01"),
+        Decimal("20.00"),
+    ]
+    assert sum((item.source_value_chf for item in reconciled), Decimal("0")) == Decimal(
+        "-80.01"
+    )
+
+
 def make_conn():
     conn = connect_memory()
     apply_migrations(conn)
@@ -461,3 +494,372 @@ def test_immutable_postfinance_source_and_snapshot_rows(monkeypatch, tmp_path):
             conn.execute(f"UPDATE {table} SET created_at=created_at WHERE {predicate}")
         with pytest.raises(Exception, match="cannot be deleted"):
             conn.execute(f"DELETE FROM {table} WHERE {predicate}")
+
+
+def test_global_read_model_counts_official_postfinance_components_once(monkeypatch, tmp_path):
+    """Reproduce the production placeholder/exposure/settlement-position collision."""
+    conn = make_conn()
+    monkeypatch.setenv("JARVIS_FINANCE_RUNTIME_DIR", str(tmp_path))
+    original = bundle()
+    stock_total = Decimal("255791.97")
+    etf_total = Decimal("37673.19")
+
+    def split_total(total: Decimal) -> list[Decimal]:
+        values = [(total / Decimal("11")).quantize(Decimal("0.01")) for _ in range(11)]
+        values[-1] += total - sum(values, Decimal("0"))
+        return values
+
+    source_values = split_total(stock_total) + split_total(etf_total)
+    positions = tuple(
+        replace(item, quantity=Decimal("1"), market_price_original=value, market_value_chf=value)
+        for item, value in zip(original.snapshot.positions, source_values, strict=True)
+    )
+    realistic = replace(
+        original,
+        snapshot=replace(
+            original.snapshot,
+            positions=positions,
+            cash=(
+                PFSnapshotCash("EUR", Decimal("21693.27"), Decimal("0.9293"), Decimal("71623.09")),
+                PFSnapshotCash("USD", Decimal("9235.55"), Decimal("0.8146"), Decimal("249526.14")),
+            ),
+            securities_total_chf=Decimal("293465.16"),
+            cash_total_chf=Decimal("27684.07"),
+            total_value_chf=Decimal("321149.23"),
+            stock_total_chf=stock_total,
+            etf_total_chf=etf_total,
+        ),
+    )
+    monkeypatch.setattr(service, "parse_postfinance_bundle", lambda _zip, _overview: realistic)
+    conn.execute(
+        """INSERT INTO cash_account_snapshots(snapshot_id,account_id,snapshot_type,balance_date,
+               amount_original,currency,amount_chf,source,note,created_at,created_by)
+           VALUES('legacy-total',?,'manual_balance','2026-07-26','321149.23','CHF',
+                  '321149.23','manual','historical depot total placeholder',
+                  '2026-07-26T00:00:00Z','synthetic')""",
+        (CASH,),
+    )
+    conn.execute(
+        "INSERT INTO platforms(platform_id,name,platform_type,country,default_currency,is_active,created_at) VALUES('tw','True Wealth','wealth','CH','CHF',1,'2026-01-01')"
+    )
+    conn.execute(
+        """INSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,
+               performance_included,is_active,created_at,portfolio_bucket)
+           VALUES('account_tw','tw','True Wealth','brokerage','CHF',1,1,'2026-01-01','truewealth')"""
+    )
+    conn.execute(
+        """INSERT INTO account_value_snapshots(snapshot_id,account_id,valuation_date,
+               total_value_chf,currency,source_type,quality_status,created_at,is_active)
+           VALUES('tw-value','account_tw','2026-07-27','152845.00','CHF',
+                  'synthetic_truewealth','complete','2026-07-27T00:00:00Z',1)"""
+    )
+    conn.commit()
+
+    payload = request()
+    preview = service.preview_postfinance_import(conn, payload)
+    service.confirm_postfinance_import(
+        conn,
+        {**payload, "preview_id": preview["preview_id"],
+         "confirmation_id": preview["confirmation_id"], "confirm": True},
+    )
+    before_gets = conn.total_changes
+    cash = get_cash_summary(conn)
+    equity = get_equity_summary(conn)
+    overview = get_overview(conn)
+    command = get_command_center_summary(conn)
+    reconciliation = build_portfolio_reconciliation(conn, as_of="2026-07-27")
+    rows = get_positions(conn)
+
+    assert conn.total_changes == before_gets
+    assert cash.cash_chf == "27684.07"
+    assert sum(Decimal(item.used_value_chf) for item in cash.positions if item.account_id == CASH) == Decimal("27684.07")
+    usd_position = next(item for item in cash.positions if item.account_id == CASH and item.currency == "USD")
+    assert get_cash_position_detail(conn, usd_position.id).currency == "USD"
+    assert equity.equity_value_chf == "293465.16"
+    assert equity.as_of == "2026-07-27T09:14:30+02:00"
+    assert sum(Decimal(row["market_value_chf"]) for row in rows if row["account_id"] == DEPOT) == Decimal("293465.16")
+    assert not [row for row in rows if row["account_id"] == CASH and row["asset_class"] in {"stock", "equity", "etf"}]
+    assert Decimal(cash.cash_chf) + Decimal(equity.equity_value_chf) == Decimal("321149.23")
+    assert overview.truewealth_value_chf == "152845.00"
+    assert command["cash_total_chf"] == "27684.07"
+    pf_reconciliation = next(
+        item for item in reconciliation["account_totals"]
+        if item["reported_total"] == "321149.23"
+    )
+    assert pf_reconciliation["derived_total"] == "321149.23"
+    assert pf_reconciliation["status"] == "matched"
+    assert conn.execute("SELECT amount_chf FROM cash_account_snapshots WHERE snapshot_id='legacy-total'").fetchone()[0] == "321149.23"
+    assert conn.execute("SELECT COUNT(*) FROM transactions WHERE internal_transfer_group_id IS NOT NULL").fetchone()[0] == 2
+
+    market_positions = []
+    for row, value in zip(
+        [row for row in rows if row["account_id"] == DEPOT],
+        split_total(Decimal("160000")) + split_total(Decimal("140000")),
+        strict=True,
+    ):
+        market_positions.append({
+            "account_id": DEPOT, "instrument_id": row["instrument_id"],
+            "quality_status": "fresh", "value_chf": str(value), "close": str(value),
+            "currency": "CHF", "provider": "synthetic-market",
+        })
+    conn.execute(
+        """INSERT INTO market_data_runs(run_id,source_key,as_of,input_fingerprint,status,
+               started_at,completed_at,price_total,price_stored,fx_total,fx_stored,
+               benchmark_total,benchmark_stored,valuation_stored,missing_instruments_json,
+               reason_codes_json)
+           VALUES('newer-run','synthetic','2026-07-28','fp','complete','2026-07-28T00:00:00Z',
+                  '2026-07-28T00:01:00Z',22,22,0,0,0,0,22,'[]','[]')"""
+    )
+    conn.execute(
+        """INSERT INTO portfolio_analysis_snapshots(analysis_snapshot_id,run_id,as_of,
+               base_currency,total_value_chf,price_coverage_pct,fx_coverage_pct,
+               benchmark_coverage_pct,quality_status,reason_codes_json,summary_json,created_at)
+           VALUES('newer-analysis','newer-run','2026-07-28','CHF','300000','100','100','0',
+                  'complete','[]',?,'2026-07-28T00:01:00Z')""",
+        (json.dumps({"positions": market_positions}),),
+    )
+    conn.commit()
+    newer = get_equity_summary(conn)
+    assert newer.equity_value_chf == "300000.00"
+    assert newer.as_of == "2026-07-28"
+    assert get_cash_summary(conn).cash_chf == "27684.07"
+    assert service.get_postfinance_summary(conn)["latest_snapshot"]["total_chf"] == "321149.23"
+
+    duplicate = service.preview_postfinance_import(conn, payload)
+    second = service.confirm_postfinance_import(
+        conn,
+        {**payload, "preview_id": duplicate["preview_id"],
+         "confirmation_id": duplicate["confirmation_id"], "confirm": True},
+    )
+    assert duplicate["duplicate"] is True and duplicate["conflict"] is False
+    assert second["idempotent"] is True
+    assert conn.execute("SELECT COUNT(*) FROM postfinance_import_batches").fetchone()[0] == 1
+
+
+def test_official_snapshot_resolvers_honor_historical_as_of_and_cutoff(monkeypatch, tmp_path):
+    conn = make_conn()
+    monkeypatch.setenv("JARVIS_FINANCE_RUNTIME_DIR", str(tmp_path))
+    monkeypatch.setattr(service, "parse_postfinance_bundle", lambda _zip, _overview: bundle())
+    payload = request()
+    preview = service.preview_postfinance_import(conn, payload)
+    service.confirm_postfinance_import(
+        conn,
+        {**payload, "preview_id": preview["preview_id"],
+         "confirmation_id": preview["confirmation_id"], "confirm": True},
+    )
+    original_cash_total = sum(
+        (item.amount_chf for item in latest_official_postfinance_cash(conn)), Decimal("0")
+    )
+    original_position_total = sum(
+        (
+            item.market_value_chf
+            for item in latest_official_postfinance_positions(conn).values()
+        ),
+        Decimal("0"),
+    )
+    conn.execute("UPDATE accounts SET account_type='checking' WHERE account_id=?", (CASH,))
+    assert sum(
+        (
+            Decimal(item.used_value_chf)
+            for item in get_cash_summary(conn).positions
+            if item.account_id == CASH
+        ),
+        Decimal("0"),
+    ) == original_cash_total
+    platform_id = conn.execute(
+        "SELECT platform_id FROM accounts WHERE account_id=?", (CASH,)
+    ).fetchone()["platform_id"]
+    conn.execute(
+        """INSERT INTO accounts(
+               account_id,platform_id,account_name,account_type,currency,balance_mode,
+               portfolio_bucket,is_active,created_at)
+           VALUES('generic-usd-cash',?,'Generic Multi-Currency','cash','CHF','csv_calculated',
+                  'cash',1,'2026-07-27T10:00:00Z')""",
+        (platform_id,),
+    )
+    conn.execute(
+        """INSERT INTO transactions(
+               transaction_id,transaction_type,account_id,trade_date,gross_amount_original,
+               net_amount_original,currency_original,fx_rate_to_chf,fx_status,source_type,
+               source_id,is_confirmed,quality_status,created_at)
+           VALUES('generic-usd-deposit','cash_deposit','generic-usd-cash','2026-07-27',
+                  '100','100','USD','0.9','ok','csv_import','generic-usd-deposit',1,
+                  'ok','2026-07-27T10:00:00Z')"""
+    )
+    conn.execute(
+        """INSERT INTO transactions(
+               transaction_id,transaction_type,account_id,trade_date,gross_amount_original,
+               net_amount_original,currency_original,fx_rate_to_chf,fx_status,source_type,
+               source_id,is_confirmed,quality_status,created_at)
+           VALUES('generic-eur-deposit','cash_deposit','generic-usd-cash','2026-07-27',
+                  '50','50','EUR','1.1','ok','csv_import','generic-eur-deposit',1,
+                  'ok','2026-07-27T10:00:01Z')"""
+    )
+    generic_rows = [
+        row for row in get_cash_overview(conn) if row["account_id"] == "generic-usd-cash"
+    ]
+    assert {row["currency"] for row in generic_rows} == {"EUR", "USD"}
+    generic_usd = next(row for row in generic_rows if row["currency"] == "USD")
+    generic_eur = next(row for row in generic_rows if row["currency"] == "EUR")
+    assert generic_usd["amount_original"] == "100.00"
+    assert generic_usd["amount_chf"] == "90.00"
+    assert generic_eur["amount_original"] == "50.00"
+    assert generic_eur["amount_chf"] == "55.00"
+    conn.execute(
+        "UPDATE accounts SET balance_mode='manual' WHERE account_id='generic-usd-cash'"
+    )
+    conn.execute(
+        """INSERT INTO cash_account_snapshots(
+               snapshot_id,account_id,snapshot_type,balance_date,amount_original,currency,
+               amount_chf,source,created_at,created_by)
+           VALUES('generic-manual-total','generic-usd-cash','manual_balance','2026-07-27',
+                  '1000','CHF','1000','manual','2026-07-27T10:01:00Z','user')"""
+    )
+    conn.execute(
+        """INSERT INTO cash_balances(
+               cash_balance_id,account_id,balance_date,currency,amount_original,
+               fx_rate_to_chf,amount_chf,source_type,quality_status,created_at)
+           VALUES('generic-missing-fx','generic-usd-cash','2026-07-27','GBP','10',
+                  NULL,NULL,'manual_import','missing_fx','2026-07-27T10:01:01Z')"""
+    )
+    controlled_rows = [
+        row for row in get_cash_overview(conn) if row["account_id"] == "generic-usd-cash"
+    ]
+    assert [(row["currency"], row["amount_chf"]) for row in controlled_rows] == [
+        ("CHF", "1000.00")
+    ]
+
+    batch = dict(conn.execute("SELECT * FROM postfinance_import_batches LIMIT 1").fetchone())
+    batch.update(
+        batch_id="future-batch",
+        bundle_sha256=sha256(b"future-bundle").hexdigest(),
+        snapshot_at="2026-08-01T09:14:30+02:00",
+        confirmed_at="2026-08-01T10:00:00Z",
+    )
+    columns = list(batch)
+    conn.execute(
+        f"INSERT INTO postfinance_import_batches({','.join(columns)}) VALUES({','.join('?' for _ in columns)})",
+        [batch[column] for column in columns],
+    )
+    source_snapshot = dict(conn.execute("SELECT * FROM postfinance_snapshots LIMIT 1").fetchone())
+    source_snapshot.update(
+        snapshot_id="future-snapshot",
+        batch_id="future-batch",
+        snapshot_at="2026-08-01T09:14:30+02:00",
+        total_chf="1299.00",
+        securities_chf="300.00",
+        cash_chf="999.00",
+        stocks_chf="100.00",
+        etfs_chf="200.00",
+        component_total_chf="1299.00",
+        difference_chf="0.00",
+        created_at="2026-08-01T10:00:00Z",
+    )
+    columns = list(source_snapshot)
+    conn.execute(
+        f"INSERT INTO postfinance_snapshots({','.join(columns)}) VALUES({','.join('?' for _ in columns)})",
+        [source_snapshot[column] for column in columns],
+    )
+    conn.execute(
+        """INSERT INTO postfinance_snapshot_positions(
+               snapshot_position_id,snapshot_id,source_row_reference,instrument_id,asset_class,
+               quantity,provider_average_cost_original,provider_cost_total_original,
+               price_original,price_currency,value_chf,weight_pct,computed_cost_basis_original,
+               computed_cost_basis_status,provenance_json,created_at)
+           SELECT 'future-'||snapshot_position_id,'future-snapshot',source_row_reference,
+                  instrument_id,asset_class,quantity,provider_average_cost_original,
+                  provider_cost_total_original,price_original,price_currency,value_chf,weight_pct,
+                  computed_cost_basis_original,computed_cost_basis_status,provenance_json,
+                  '2026-08-01T10:00:00Z'
+           FROM postfinance_snapshot_positions WHERE snapshot_id<> 'future-snapshot'"""
+    )
+    conn.execute(
+        """INSERT INTO postfinance_snapshot_cash(
+               snapshot_cash_id,snapshot_id,currency,amount_original,fx_rate_to_chf,value_chf,created_at)
+           SELECT 'future-'||snapshot_cash_id,'future-snapshot',currency,amount_original,
+                  fx_rate_to_chf,value_chf,'2026-08-01T10:00:00Z'
+           FROM postfinance_snapshot_cash WHERE snapshot_id<> 'future-snapshot'"""
+    )
+    conn.commit()
+
+    assert sum((item.amount_chf for item in latest_official_postfinance_cash(conn)), Decimal("0")) == Decimal("999.00")
+    historical_cash = latest_official_postfinance_cash(conn, as_of="2026-07-27")
+    assert sum((item.amount_chf for item in historical_cash), Decimal("0")) == original_cash_total
+    cutoff_cash = latest_official_postfinance_cash(
+        conn,
+        as_of="2026-08-01",
+        data_cutoff="2026-07-31T23:59:59Z",
+    )
+    assert sum((item.amount_chf for item in cutoff_cash), Decimal("0")) == original_cash_total
+    historical_positions = latest_official_postfinance_positions(conn, as_of="2026-07-27")
+    assert sum(
+        (item.market_value_chf for item in historical_positions.values()), Decimal("0")
+    ) == original_position_total
+    assert {item.valuation_at for item in historical_positions.values()} == {"2026-07-27T09:14:30+02:00"}
+    current_positions = latest_official_postfinance_positions(conn)
+    assert sum((item.market_value_chf for item in current_positions.values()), Decimal("0")) == Decimal("300.00")
+    assert {item.valuation_at for item in current_positions.values()} == {"2026-08-01T09:14:30+02:00"}
+
+    selected = next(iter(current_positions.values()))
+    baseline_quantity = selected.quantity
+    conn.execute(
+        """INSERT INTO transactions(
+               transaction_id,transaction_type,account_id,instrument_id,trade_date,
+               settlement_date,quantity,currency_original,source_type,source_id,
+               external_transaction_id,row_hash,is_confirmed,quality_status,created_at,
+               updated_at,is_voided)
+           VALUES('post-snapshot-buy','buy',?,?, '2026-08-02','2026-08-02','2',
+                  'CHF','manual_confirmed_trade','post-snapshot-buy','post-snapshot-buy',?,
+                  1,'ok','2026-08-02T10:00:00Z','2026-08-02T10:00:00Z',0)""",
+        (CASH, selected.instrument_id, sha256(b"post-snapshot-buy").hexdigest()),
+    )
+    conn.execute(
+        """INSERT INTO transactions(
+               transaction_id,transaction_type,account_id,trade_date,gross_amount_original,
+               net_amount_original,currency_original,fx_rate_to_chf,fx_status,source_type,
+               source_id,is_confirmed,quality_status,created_at,is_voided)
+           VALUES('post-snapshot-cash','cash_deposit',?,'2026-08-02','10','10','USD',
+                  '0.8','ok','manual_confirmed_cash','post-snapshot-cash',1,'ok',
+                  '2026-08-02T10:01:00Z',0)""",
+        (CASH,),
+    )
+    conn.execute(
+        """INSERT INTO transactions(
+               transaction_id,transaction_type,account_id,instrument_id,trade_date,
+               settlement_date,quantity,gross_amount_original,net_amount_original,
+               currency_original,fx_rate_to_chf,fx_status,source_type,source_id,
+               is_confirmed,quality_status,created_at,is_voided)
+           VALUES('post-snapshot-sell','sell',?,?, '2026-08-02','2026-08-02','1',
+                  '20','20','USD','0.8','ok','manual_confirmed_trade',
+                  'post-snapshot-sell',1,'ok','2026-08-02T10:02:00Z',0)""",
+        (CASH, selected.instrument_id),
+    )
+    conn.execute(
+        """INSERT INTO cash_balances(
+               cash_balance_id,account_id,balance_date,currency,amount_original,
+               fx_rate_to_chf,amount_chf,source_type,quality_status,created_at)
+           VALUES('post-snapshot-dividend-cash',?,'2026-08-02','EUR','5','1','5',
+                  'vue_equity_dividend','ok','2026-08-02T10:03:00Z')""",
+        (CASH,),
+    )
+    conn.commit()
+    post_snapshot_cash = [
+        item for item in get_cash_summary(conn).positions if item.account_id == CASH
+    ]
+    assert sum(
+        (Decimal(item.used_value_chf) for item in post_snapshot_cash), Decimal("0")
+    ) == Decimal("1028.00")
+    assert next(item for item in post_snapshot_cash if item.currency == "USD").amount == "130.00"
+    assert next(item for item in post_snapshot_cash if item.currency == "EUR").amount == "105.00"
+    dashboard_position = next(
+        row
+        for row in get_positions(conn)
+        if row["account_id"] == DEPOT and row["instrument_id"] == selected.instrument_id
+    )
+    assert Decimal(dashboard_position["quantity"]) == baseline_quantity + Decimal("1")
+    canonical_position = next(
+        item
+        for item in confirmed_canonical_positions(conn, as_of="2026-08-02")
+        if item.account_id == DEPOT and item.instrument_id == selected.instrument_id
+    )
+    assert canonical_position.quantity == baseline_quantity + Decimal("1")


grep -R "postfinance_account_roles" -n . | head -20 && grep -R "portfolio_analysis_snapshots" -n src/jarvis_finance/storage/migrations* src | head -30


Output:
Chunk ID: c46cb5
Wall time: 0.8180 seconds
Process exited with code 0
Original token count: 1547
Output:
grep: ./src/jarvis_finance/storage/__pycache__/postfinance_schema.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/dashboard/__pycache__/data.cpython-312.pyc: binary file matches
grep: ./src/jarvis_finance/dashboard/__pycache__/data.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/postfinance_service.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/portfolio_data.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/cash_service.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/portfolio_aggregation.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/portfolio_analytics.cpython-312.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/portfolio_aggregation.cpython-312.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/portfolio_analytics.cpython-311.pyc: binary file matches
grep: ./src/jarvis_finance/services/__pycache__/postfinance_service.cpython-312.pyc: binary file matches
grep: ./tests/__pycache__/test_postfinance_sprint13.cpython-311-pytest-9.1.1.pyc: binary file matches
grep: ./tests/__pycache__/test_postfinance_sprint13.cpython-311.pyc: binary file matches
grep: ./tests/__pycache__/test_postfinance_sprint13.cpython-311-pytest-9.0.2.pyc: binary file matches
./src/jarvis_finance/storage/postfinance_schema.py:15:        CREATE TABLE IF NOT EXISTS postfinance_account_roles (
./src/jarvis_finance/dashboard/data.py:16:    postfinance_account_roles,
./src/jarvis_finance/dashboard/data.py:564:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_aggregation.py:65:def postfinance_account_roles(conn: Connection) -> dict[str, str]:
./src/jarvis_finance/services/portfolio_aggregation.py:71:            "SELECT role,account_id FROM postfinance_account_roles ORDER BY role"
./src/jarvis_finance/services/portfolio_aggregation.py:102:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_aggregation.py:155:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_aggregation.py:225:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_data.py:34:    postfinance_account_roles,
./src/jarvis_finance/services/portfolio_data.py:1599:    pf_roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_analytics.py:31:    postfinance_account_roles,
./src/jarvis_finance/services/portfolio_analytics.py:238:    trading_cash_id = postfinance_account_roles(conn).get("etrading_cash")
./src/jarvis_finance/services/postfinance_service.py:541:                "INSERT OR IGNORE INTO postfinance_account_roles(role,account_id,source_reference_hash,created_at) VALUES(?,?,NULL,?)",
./src/jarvis_finance/services/postfinance_service.py:545:                "SELECT account_id FROM postfinance_account_roles WHERE role=?", (role,)
./src/jarvis_finance/services/cash_service.py:279:                  SELECT account_id FROM postfinance_account_roles
./tests/test_postfinance_sprint13.py:301:    assert conn.execute("SELECT COUNT(*) FROM postfinance_account_roles").fetchone()[0] == 3
./tests/test_postfinance_sprint13.py:302:    roles = dict(conn.execute("SELECT role,account_id FROM postfinance_account_roles"))
grep: src/jarvis_finance/storage/__pycache__/migrations.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/portfolio_aggregation.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/equity_service.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/portfolio_analytics.cpython-312.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/portfolio_aggregation.cpython-312.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/equity_service.cpython-312.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/portfolio_analytics.cpython-311.pyc: binary file matches
src/jarvis_finance/storage/migrations.py:1891:        CREATE TABLE IF NOT EXISTS portfolio_analysis_snapshots (
src/jarvis_finance/storage/migrations.py:1907:        CREATE INDEX IF NOT EXISTS idx_portfolio_analysis_snapshots_time
src/jarvis_finance/storage/migrations.py:1908:            ON portfolio_analysis_snapshots(as_of DESC, created_at DESC);
src/jarvis_finance/storage/migrations.py:1919:        CREATE TRIGGER IF NOT EXISTS portfolio_analysis_snapshots_immutable
src/jarvis_finance/storage/migrations.py:1920:        BEFORE UPDATE ON portfolio_analysis_snapshots
src/jarvis_finance/storage/migrations.py:1922:        CREATE TRIGGER IF NOT EXISTS portfolio_analysis_snapshots_no_delete
src/jarvis_finance/storage/migrations.py:1923:        BEFORE DELETE ON portfolio_analysis_snapshots
src/jarvis_finance/storage/migrations.py:1891:        CREATE TABLE IF NOT EXISTS portfolio_analysis_snapshots (
src/jarvis_finance/storage/migrations.py:1907:        CREATE INDEX IF NOT EXISTS idx_portfolio_analysis_snapshots_time
src/jarvis_finance/storage/migrations.py:1908:            ON portfolio_analysis_snapshots(as_of DESC, created_at DESC);
src/jarvis_finance/storage/migrations.py:1919:        CREATE TRIGGER IF NOT EXISTS portfolio_analysis_snapshots_immutable
src/jarvis_finance/storage/migrations.py:1920:        BEFORE UPDATE ON portfolio_analysis_snapshots
src/jarvis_finance/storage/migrations.py:1922:        CREATE TRIGGER IF NOT EXISTS portfolio_analysis_snapshots_no_delete
src/jarvis_finance/storage/migrations.py:1923:        BEFORE DELETE ON portfolio_analysis_snapshots
src/jarvis_finance/services/portfolio_aggregation.py:264:           FROM portfolio_analysis_snapshots pas
src/jarvis_finance/services/equity_service.py:32:             FROM portfolio_analysis_snapshots pas
src/jarvis_finance/services/portfolio_analytics.py:731:            """INSERT OR REPLACE INTO portfolio_analysis_snapshots(
src/jarvis_finance/services/portfolio_analytics.py:929:    latest = conn.execute("SELECT * FROM portfolio_analysis_snapshots ORDER BY as_of DESC,created_at DESC LIMIT 1").fetchone()


sed -n '1,80p' src/jarvis_finance/storage/postfinance_schema.py && sed -n '520,560p' src/jarvis_finance/services/postfinance_service.py && sed -n '1,80p' src/jarvis_finance/services/equity_service.py


Output:
Chunk ID: f5f884
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2465
Output:
from __future__ import annotations

from sqlite3 import Connection

def create_postfinance_ledger_import_v1(conn: Connection) -> None:
    """Create immutable PostFinance source, ledger, snapshot and cost-basis tables."""
    position_columns = {row[1] for row in conn.execute("PRAGMA table_info(positions_snapshot)")}
    if "source_type" not in position_columns:
        conn.execute("ALTER TABLE positions_snapshot ADD COLUMN source_type TEXT")
    if "source_reference" not in position_columns:
        conn.execute("ALTER TABLE positions_snapshot ADD COLUMN source_reference TEXT")
    conn.executescript(
        """
        CREATE TABLE IF NOT EXISTS postfinance_account_roles (
            role TEXT PRIMARY KEY CHECK(role IN ('efinance','etrading_depot','etrading_cash')),
            account_id TEXT NOT NULL REFERENCES accounts(account_id),
            source_reference_hash TEXT,
            created_at TEXT NOT NULL,
            UNIQUE(account_id, role)
        );
        CREATE TABLE IF NOT EXISTS postfinance_import_batches (
            batch_id TEXT PRIMARY KEY,
            bundle_sha256 TEXT NOT NULL UNIQUE CHECK(length(bundle_sha256)=64),
            zip_sha256 TEXT NOT NULL CHECK(length(zip_sha256)=64),
            overview_sha256 TEXT NOT NULL CHECK(length(overview_sha256)=64),
            parser_id TEXT NOT NULL,
            parser_version TEXT NOT NULL,
            db_revision TEXT NOT NULL,
            archive_reference TEXT NOT NULL,
            snapshot_at TEXT NOT NULL,
            status TEXT NOT NULL CHECK(status='confirmed'),
            audit_id TEXT NOT NULL,
            confirmed_at TEXT NOT NULL,
            confirmed_by TEXT NOT NULL DEFAULT 'user'
        );
        CREATE TABLE IF NOT EXISTS postfinance_documents (
            document_hash TEXT PRIMARY KEY CHECK(length(document_hash)=64),
            filename_hash TEXT NOT NULL CHECK(length(filename_hash)=64),
            semantic_identity TEXT NOT NULL UNIQUE CHECK(length(semantic_identity)=64),
            semantic_reference_hash TEXT NOT NULL CHECK(length(semantic_reference_hash)=64),
            document_type TEXT NOT NULL,
            document_date TEXT,
            account_reference_hash TEXT,
            account_role TEXT NOT NULL CHECK(account_role IN ('efinance','etrading_depot','etrading_cash')),
            page_count INTEGER NOT NULL CHECK(page_count > 0),
            archive_reference TEXT NOT NULL,
            parser_version TEXT NOT NULL,
            created_at TEXT NOT NULL
        );
        CREATE TABLE IF NOT EXISTS postfinance_batch_documents (
            batch_id TEXT NOT NULL REFERENCES postfinance_import_batches(batch_id),
            document_hash TEXT NOT NULL REFERENCES postfinance_documents(document_hash),
            PRIMARY KEY(batch_id, document_hash)
        );
        CREATE TABLE IF NOT EXISTS postfinance_snapshots (
            snapshot_id TEXT PRIMARY KEY,
            batch_id TEXT NOT NULL UNIQUE REFERENCES postfinance_import_batches(batch_id),
            account_id TEXT NOT NULL REFERENCES accounts(account_id),
            snapshot_at TEXT NOT NULL,
            total_chf TEXT NOT NULL,
            securities_chf TEXT NOT NULL,
            cash_chf TEXT NOT NULL,
            stocks_chf TEXT NOT NULL,
            etfs_chf TEXT NOT NULL,
            component_total_chf TEXT NOT NULL,
            difference_chf TEXT NOT NULL,
            tolerance_chf TEXT NOT NULL,
            position_count INTEGER NOT NULL,
            cash_count INTEGER NOT NULL,
            open_orders INTEGER NOT NULL,
            reconciliation_status TEXT NOT NULL CHECK(reconciliation_status IN ('matched','within_tolerance')),
            created_at TEXT NOT NULL
        );
        CREATE TABLE IF NOT EXISTS postfinance_snapshot_positions (
            snapshot_position_id TEXT PRIMARY KEY,
            snapshot_id TEXT NOT NULL REFERENCES postfinance_snapshots(snapshot_id),
            source_row_reference TEXT NOT NULL,
            instrument_id TEXT NOT NULL REFERENCES instruments(instrument_id),
            asset_class TEXT NOT NULL CHECK(asset_class IN ('stock','etf')),
        event.event_fingerprint: _event_instrument(event, bundle, position_map, conn)
        for event in bundle.events
    }
    archive_refs: list[tuple[str, bool]] = []
    zip_ref, created = _archive(zip_raw, bundle.zip_hash, "zip")
    archive_refs.append((zip_ref, created))
    overview_ref, created = _archive(overview_raw, bundle.overview_hash, "pdf")
    archive_refs.append((overview_ref, created))
    for document in bundle.documents:
        reference, created = _archive(document.raw, document.document_hash, "pdf")
        archive_refs.append((reference, created))
    now = _now()
    batch_id = _id("pfbatch")
    snapshot_id = _id("pfsnapshot")
    try:
        conn.execute("BEGIN IMMEDIATE")
        if _revision(conn, accounts) != preview["db_revision"]:
            raise ValueError("PostFinance database revision changed before persistence")
        _ensure_efinance_account(conn, accounts, now)
        for role, account_id in accounts.items():
            conn.execute(
                "INSERT OR IGNORE INTO postfinance_account_roles(role,account_id,source_reference_hash,created_at) VALUES(?,?,NULL,?)",
                (role, account_id, now),
            )
            mapped = conn.execute(
                "SELECT account_id FROM postfinance_account_roles WHERE role=?", (role,)
            ).fetchone()
            if not mapped or mapped["account_id"] != account_id:
                raise ValueError(
                    "PostFinance account-role mapping conflicts with confirmed mapping"
                )
        audit_id = _audit(conn, batch_id, bundle, now)
        conn.execute(
            """INSERT INTO postfinance_import_batches(batch_id,bundle_sha256,zip_sha256,overview_sha256,parser_id,parser_version,db_revision,archive_reference,snapshot_at,status,audit_id,confirmed_at,confirmed_by) VALUES(?,?,?,?,?,?,?,?,?,'confirmed',?,?,'user')""",
            (
                batch_id,
                bundle.bundle_hash,
                bundle.zip_hash,
                bundle.overview_hash,
                PARSER_ID,
                PARSER_VERSION,
from __future__ import annotations

import json
from collections.abc import Mapping
from decimal import Decimal
from sqlite3 import Connection

from fastapi import HTTPException

from jarvis_finance.api.schemas.positions import EquityPortfolioSummary, EquityPosition
from jarvis_finance.dashboard import data as dashboard_data
from jarvis_finance.services.api_helpers import optional_decimal_text

def _asset_class_label(value: object) -> str:
    return "ETF" if str(value or "").lower() == "etf" else "Aktie"

def _account_label(row: dict[str, str]) -> str:
    platform = str(row.get("platform") or "").strip()
    account = str(row.get("account_name") or "").strip()
    if "postfinance" in platform.lower():
        if not account or "manual" in account.lower():
            return "PostFinance E-Trading"
        return account if "postfinance" in account.lower() or "e-trading" in account.lower() else f"PostFinance · {account}"
    return account or platform

def _latest_analysis(conn: Connection) -> tuple[dict[str, object] | None, dict[tuple[str, str], dict[str, object]], dict[str, str]]:
    row = conn.execute(
        """SELECT pas.*,mdr.completed_at,mdr.missing_instruments_json
             FROM portfolio_analysis_snapshots pas
             JOIN market_data_runs mdr ON mdr.run_id=pas.run_id
            ORDER BY pas.as_of DESC,pas.created_at DESC LIMIT 1"""
    ).fetchone()
    if not row:
        return None, {}, {}
    try:
        payload = json.loads(row["summary_json"] or "{}")
    except json.JSONDecodeError:
        payload = {}
    values = {
        (str(item.get("account_id") or ""), str(item.get("instrument_id") or "")): item
        for item in payload.get("positions", [])
        if isinstance(item, dict)
    }
    try:
        missing_rows = json.loads(row["missing_instruments_json"] or "[]")
    except json.JSONDecodeError:
        missing_rows = []
    missing = {
        str(item.get("instrument_id") or ""): str(item.get("reason_code") or "price_missing")
        for item in missing_rows
        if isinstance(item, dict)
    }
    return dict(row), values, missing

def _status_reason(code: str) -> str:
    labels = {
        "fmp_endpoint_restricted": "Der primäre Provider beschränkt diesen historischen Kurs im aktuellen Tarif.",
        "plan_restricted": "Der Provider beschränkt diesen historischen Kurs im aktuellen Tarif.",
        "fmp_rate_limited": "Das Provider-Limit wurde erreicht. Der Lauf kann kontrolliert fortgesetzt werden.",
        "rate_limited": "Das Provider-Limit wurde erreicht. Der Lauf kann kontrolliert fortgesetzt werden.",
        "currency_mismatch": "Die Kurswährung stimmt nicht mit der bestätigten Instrumentwährung überein.",
        "exchange_mismatch": "Der Handelsplatz des Provider-Ergebnisses ist nicht bestätigt.",
        "future_price_rejected": "Der gelieferte Kurs liegt nach dem zulässigen Börsenstichtag.",
        "stale_price": "Der letzte bestätigte Kurs ist für den Börsenstichtag zu alt und wird nicht bewertet.",
        "mapping_required": "Die Provider-Zuordnung ist noch nicht eindeutig bestätigt.",
        "fx_rate_missing": "Für die CHF-Bewertung fehlt ein bestätigter FX-Kurs.",
    }
    return labels.get(code, "Für den Börsenstichtag konnte noch kein bestätigter Kurs geladen werden.")

def _position_status(row: Mapping[str, object]) -> str:
    """Compatibility status when no audited market-analysis snapshot exists yet."""

    if "quantity" in row and Decimal(str(row.get("quantity") or "0")) <= 0:
        return "Einstand unvollständig"
    market_value = row.get("market_value_chf")


Output:
Chunk ID: b939dc
Wall time: 2.3999 seconds
Process exited with code 0
Original token count: 25
Output:
.........                                                                [100%]
9 passed in 2.13s


grep -R "def get_overview" -n src/jarvis_finance/services src/jarvis_finance/dashboard && sed -n '1,180p' src/jarvis_finance/services/portfolio_service.py


Output:
Chunk ID: 665fdc
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 988
Output:
src/jarvis_finance/services/portfolio_service.py:50:def get_overview(conn: Connection) -> PortfolioSummary:
from __future__ import annotations

from decimal import Decimal
from sqlite3 import Connection

from jarvis_finance.api.schemas.overview import PortfolioSummary
from jarvis_finance.dashboard import data as dashboard_data
from jarvis_finance.services.api_helpers import decimal_text, user_quality_status
from jarvis_finance.services.cash_service import get_cash_summary
from jarvis_finance.services.equity_service import get_equity_summary

def _latest_truewealth_value(conn: Connection) -> Decimal:
    row = conn.execute(
        """
        SELECT avs.total_value_chf
        FROM account_value_snapshots avs
        JOIN accounts a ON a.account_id = avs.account_id
        JOIN platforms p ON p.platform_id = a.platform_id
        WHERE a.is_active = 1
          AND COALESCE(avs.is_active,1) = 1
          AND (lower(p.name || ' ' || a.account_name) LIKE '%true%wealth%' OR lower(a.account_type) IN ('managed_portfolio','robo_portfolio'))
        ORDER BY avs.valuation_date DESC,
                 CASE avs.source_type WHEN 'truewealth_official_import' THEN 3 WHEN 'truewealth_manual_provisional' THEN 2 ELSE 1 END DESC,
                 COALESCE(avs.valuation_at,avs.created_at) DESC, avs.created_at DESC
        LIMIT 1
        """
    ).fetchone()
    return dashboard_data.d(row["total_value_chf"]) if row else Decimal("0")

def _postfinance_equity_value(conn: Connection) -> Decimal:
    row = conn.execute(
        """
        SELECT COALESCE(SUM(CAST(t.gross_amount_chf AS REAL)), 0) AS value_chf
        FROM transactions t
        JOIN accounts a ON a.account_id = t.account_id
        JOIN platforms p ON p.platform_id = a.platform_id
        JOIN instruments i ON i.instrument_id = t.instrument_id
        WHERE COALESCE(t.is_voided,0)=0
          AND COALESCE(a.is_active,1)=1
          AND lower(i.asset_class) IN ('stock','etf')
          AND lower(p.name || ' ' || a.account_name) NOT LIKE '%true%wealth%'
          AND lower(a.account_type) NOT IN ('managed_portfolio','robo_portfolio')
        """
    ).fetchone()
    return dashboard_data.d(row["value_chf"]) if row else Decimal("0")

def get_overview(conn: Connection) -> PortfolioSummary:
    summary = dashboard_data.get_command_center_summary(conn)
    truewealth = _latest_truewealth_value(conn)
    equity_summary = get_equity_summary(conn)
    if equity_summary.as_of is None:
        # Legacy/read-model compatibility before the first audited market run.
        equity = _postfinance_equity_value(conn)
        equity_partial = equity
        equity_complete = True
    else:
        equity_partial = dashboard_data.d(equity_summary.valued_partial_chf)
        equity = dashboard_data.d(equity_summary.equity_value_chf) if equity_summary.coverage_complete else None
        equity_complete = equity_summary.coverage_complete
    crypto = dashboard_data.d(summary.get("crypto_total_chf"))
    cash = dashboard_data.d(get_cash_summary(conn).cash_chf)
    partial_total = cash + crypto + equity_partial + truewealth
    total = partial_total if equity is not None else None
    return PortfolioSummary(
        total_value_chf=decimal_text(total, 2) if total is not None else None,
        crypto_value_chf=decimal_text(crypto, 2),
        equity_value_chf=decimal_text(equity, 2) if equity is not None else None,
        postfinance_equity_value_chf=decimal_text(equity, 2) if equity is not None else None,
        truewealth_value_chf=decimal_text(truewealth, 2),
        cash_value_chf=decimal_text(cash, 2),
        unpriced_positions_count=equity_summary.unvalued_positions,
        critical_alerts_count=int(summary.get("critical_alert_count") or 0),
        last_price_update=equity_summary.last_successful_run or summary.get("last_price_update_at") or None,
        data_quality_status="ok" if equity_complete else user_quality_status("partial"),
    )


Output:
Chunk ID: b80f58
Wall time: 30.0011 seconds
Process running with session ID 61478
Original token count: 7
Output:
............................


Output:
Chunk ID: dfdabf
Wall time: 30.0010 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output:
Chunk ID: bc6f12
Wall time: 30.0012 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output:
Chunk ID: 0d38c0
Wall time: 30.0010 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output:
Chunk ID: f6a6fa
Wall time: 30.0010 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output:
Chunk ID: b49de0
Wall time: 30.0013 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output: write_stdin failed: stdin is closed for this session; rerun exec_command with tty=true to keep stdin open


sed -n '80,150p' src/jarvis_finance/storage/postfinance_schema.py


Output:
Chunk ID: bb49a1
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1011
Output:
            asset_class TEXT NOT NULL CHECK(asset_class IN ('stock','etf')),
            quantity TEXT NOT NULL,
            provider_average_cost_original TEXT,
            provider_cost_total_original TEXT,
            price_original TEXT NOT NULL,
            price_currency TEXT NOT NULL,
            value_chf TEXT NOT NULL,
            weight_pct TEXT NOT NULL,
            computed_cost_basis_original TEXT,
            computed_cost_basis_status TEXT NOT NULL CHECK(computed_cost_basis_status IN ('complete','partial','unavailable')),
            provenance_json TEXT NOT NULL CHECK(json_valid(provenance_json)),
            created_at TEXT NOT NULL,
            UNIQUE(snapshot_id, source_row_reference),
            UNIQUE(snapshot_id, instrument_id)
        );
        CREATE TABLE IF NOT EXISTS postfinance_snapshot_cash (
            snapshot_cash_id TEXT PRIMARY KEY,
            snapshot_id TEXT NOT NULL REFERENCES postfinance_snapshots(snapshot_id),
            currency TEXT NOT NULL,
            amount_original TEXT NOT NULL,
            fx_rate_to_chf TEXT NOT NULL,
            value_chf TEXT NOT NULL,
            created_at TEXT NOT NULL,
            UNIQUE(snapshot_id, currency)
        );
        CREATE TABLE IF NOT EXISTS postfinance_ledger_events (
            event_id TEXT PRIMARY KEY,
            event_fingerprint TEXT NOT NULL UNIQUE CHECK(length(event_fingerprint)=64),
            document_hash TEXT NOT NULL REFERENCES postfinance_documents(document_hash),
            semantic_reference_hash TEXT NOT NULL CHECK(length(semantic_reference_hash)=64),
            event_type TEXT NOT NULL CHECK(event_type IN ('buy','sell','dividend','interest','fee','internal_transfer','fx','split','corporate_action')),
            account_role TEXT NOT NULL CHECK(account_role IN ('efinance','etrading_depot','etrading_cash')),
            account_id TEXT NOT NULL REFERENCES accounts(account_id),
            occurred_on TEXT NOT NULL,
            settlement_on TEXT,
            direction TEXT NOT NULL CHECK(direction IN ('in','out','neutral')),
            instrument_id TEXT REFERENCES instruments(instrument_id),
            quantity TEXT,
            price_original TEXT,
            gross_original TEXT,
            fee_original TEXT NOT NULL DEFAULT '0',
            tax_original TEXT NOT NULL DEFAULT '0',
            net_original TEXT,
            currency TEXT,
            fx_rate_to_chf TEXT,
            internal_transfer_group TEXT,
            quality_status TEXT NOT NULL CHECK(quality_status IN ('complete','partial')),
            reason_codes_json TEXT NOT NULL CHECK(json_valid(reason_codes_json)),
            created_at TEXT NOT NULL
        );
        CREATE INDEX IF NOT EXISTS idx_postfinance_events_time ON postfinance_ledger_events(occurred_on, event_type);
        CREATE INDEX IF NOT EXISTS idx_postfinance_events_transfer ON postfinance_ledger_events(internal_transfer_group) WHERE internal_transfer_group IS NOT NULL;
        CREATE TABLE IF NOT EXISTS postfinance_event_components (
            component_id TEXT PRIMARY KEY,
            event_id TEXT NOT NULL REFERENCES postfinance_ledger_events(event_id),
            component_type TEXT NOT NULL CHECK(component_type IN ('gross','fee','tax','net','fx_amount')),
            amount_original TEXT NOT NULL,
            currency TEXT NOT NULL,
            provenance_document_hash TEXT NOT NULL REFERENCES postfinance_documents(document_hash),
            created_at TEXT NOT NULL,
            UNIQUE(event_id, component_type, currency)
        );
        CREATE TABLE IF NOT EXISTS postfinance_cost_basis_lots (
            lot_id TEXT PRIMARY KEY,
            event_id TEXT NOT NULL UNIQUE REFERENCES postfinance_ledger_events(event_id),
            instrument_id TEXT NOT NULL REFERENCES instruments(instrument_id),
            acquired_on TEXT NOT NULL,
            quantity_acquired TEXT NOT NULL,
            quantity_remaining TEXT NOT NULL,
            unit_cost_original TEXT NOT NULL,
            fees_original TEXT NOT NULL,


Output:
Chunk ID: f2a627
Wall time: 30.0006 seconds
Process running with session ID 61478
Original token count: 0
Output:


grep -R "class CashPosition" -n src/jarvis_finance/api/schemas/positions.py && sed -n '1,90p' src/jarvis_finance/api/schemas/positions.py


Output:
Chunk ID: f16cde
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 516
Output:
148:class CashPosition(BaseModel):
168:class CashPositionDetail(CashPosition):
from __future__ import annotations

from pydantic import BaseModel

class ActionItem(BaseModel):
    label: str
    enabled: bool
    reason: str | None = None

class PricePoint(BaseModel):
    date: str
    value: str
    currency: str = "CHF"
    provider: str | None = None
    quality_status: str | None = None

class CryptoPosition(BaseModel):
    asset_id: str
    name: str
    symbol: str
    quantity_total: str
    price_chf: str | None = None
    market_value_chf: str | None = None
    portfolio_share_pct: str
    wallet_count: int
    price_status: str
    last_price_update: str | None = None
    coingecko_url: str | None = None

class WalletAllocation(BaseModel):
    wallet_id: str
    wallet: str
    quantity: str
    market_value_chf: str | None = None

class WalletCoin(BaseModel):
    asset_id: str
    name: str
    symbol: str
    quantity: str
    market_value_chf: str | None = None
    status: str

class CoinGeckoInfo(BaseModel):
    market_cap_rank: int | None = None
    market_cap: str | None = None
    volume_24h: str | None = None
    change_24h_pct: str | None = None
    change_7d_pct: str | None = None
    homepage: str | None = None
    image_url: str | None = None

class CryptoPositionDetail(CryptoPosition):
    wallet_allocations: list[WalletAllocation]
    coingecko_info: CoinGeckoInfo | None = None
    available_actions: list[ActionItem] = []
    price_history: list[PricePoint] = []
    read_only_note: str = "Live-Modus später; keine Provider-Abfrage beim Rendern."

class WalletSummary(BaseModel):
    wallet_id: str
    name: str
    wallet_type: str
    provider: str = ""
    coin_count: int
    market_value_chf: str | None = None
    status: str

class WalletDetail(WalletSummary):
    coins: list[WalletCoin]

class EquityPosition(BaseModel):
    position_id: str
    instrument_id: str | None = None
    name: str
    ticker: str = ""
    isin: str = ""
    account: str = ""
    asset_class: str
    quantity: str


sed -n '140,210p' src/jarvis_finance/api/schemas/positions.py


Output:
Chunk ID: 1fb812
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 443
Output:
    balance_date: str
    amount_chf: str
    source: str
    note: str = ""
    difference_to_previous_chf: str | None = None
    audit_hint: str | None = None

class CashPosition(BaseModel):
    id: str
    account_id: str = ""
    platform: str
    account_label: str
    account_type: str = "cash"
    currency: str
    balance_mode: str = "manual"
    amount: str
    amount_chf: str | None = None
    calculated_balance_chf: str = "0.00"
    manual_balance_chf: str | None = None
    csv_anchor_balance_chf: str | None = None
    used_value_chf: str = "0.00"
    difference_chf: str = "0.00"
    last_manual_reconciliation: str | None = None
    last_imported_booking: str | None = None
    status: str

class CashPositionDetail(CashPosition):
    last_change: str | None = None
    history: list[CashSnapshot] = []
    available_actions: list[ActionItem]

class InstrumentSearchCandidate(BaseModel):
    candidate_id: str
    label: str
    asset_class: str
    isin: str = ""
    ticker: str = ""
    exchange: str = ""
    currency: str = ""
    provider: str = ""
    provider_symbol: str = ""
    exchange_name: str = ""
    mic: str = ""
    country: str = ""
    security_type: str = ""
    last_price: str | None = None
    price_currency: str | None = None
    price_date: str | None = None
    confidence_label: str
    review_required: bool

class InstrumentSearchRequest(BaseModel):
    asset_class: str
    query: str
    currency: str | None = None
    exchange: str | None = None
    country: str | None = None
    main_listing_only: bool = True
    hide_cdr_adr_derivatives: bool = True

class ProviderSearchResponse(BaseModel):
    candidates: list[InstrumentSearchCandidate]
    warnings: list[str] = []
    selection_required: bool = True


sed -n '80,118p' src/jarvis_finance/services/equity_service.py


Output:
Chunk ID: d107f5
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 442
Output:
    market_value = row.get("market_value_chf")
    warnings = str(row.get("quality_warnings") or "")
    if market_value not in {None, ""}:
        if "missing_cost_basis" in warnings or "missing_fx" in warnings:
            return "Einstand unvollständig"
        return "Bewertet"
    if str(row.get("price_status") or "") != "ok":
        return "Kurs fehlt"
    if str(row.get("fx_status") or "") == "missing_fx":
        return "FX fehlt für Bewertung"
    return "Bewertung unvollständig"

def _mapping_details(conn: Connection, instrument_id: str) -> dict[str, str | None]:
    row = conn.execute(
        """SELECT provider,provider_symbol,provider_market,upper(COALESCE(trading_currency,currency,'')) currency
             FROM instrument_price_mappings
            WHERE instrument_id=? AND mapping_status='mapped'
            ORDER BY updated_at DESC,mapping_id LIMIT 1""",
        (instrument_id,),
    ).fetchone()
    return dict(row) if row else {"provider": None, "provider_symbol": None, "provider_market": None, "currency": None}

def list_equity_positions(conn: Connection) -> list[EquityPosition]:
    source_rows = [
        row for row in dashboard_data.get_positions(conn)
        if row.get("asset_class", "").lower() in {"stock", "equity", "etf"}
        and row.get("instrument_status", "").lower() != "inactive"
    ]
    analysis, values, missing = _latest_analysis(conn)
    effective_values: dict[tuple[str, str], Decimal | None] = {}
    for row in source_rows:
        key = (str(row.get("account_id") or ""), str(row.get("instrument_id") or ""))
        candidate = values.get(key)
        row_is_audited = row.get("valuation_source") in {
            "postfinance_official_import",
            "audited_market_run",
        }


sed -n '200,290p' src/jarvis_finance/services/portfolio_analytics.py


Output:
Chunk ID: b9d867
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1052
Output:

def confirmed_canonical_positions(conn: Connection, *, as_of: str | None = None) -> list[ConfirmedPosition]:
    """Return only active, confirmed ledger positions. Preview and ingestion staging tables are never read."""

    rows = conn.execute(
        """
        SELECT t.account_id, t.instrument_id, i.isin, i.name, lower(i.asset_class) AS asset_class,
               upper(COALESCE(i.trading_currency, i.currency, '')) AS instrument_currency,
               t.transaction_type, t.quantity
        FROM transactions t
        JOIN instruments i ON i.instrument_id=t.instrument_id
        JOIN accounts a ON a.account_id=t.account_id
        WHERE t.instrument_id IS NOT NULL
          AND COALESCE(t.is_confirmed, 0)=1
          AND COALESCE(t.is_voided, 0)=0
          AND i.is_active=1 AND a.is_active=1
          AND COALESCE(i.instrument_status,'active') NOT IN ('inactive','delisted','suspended','merged')
          AND COALESCE(i.valuation_policy,'')!='exclude_from_auto_price_update'
          AND lower(i.asset_class) IN ('stock','equity','etf')
          AND lower(t.transaction_type) IN ('initial_position_snapshot','buy','sell','partial_sell','full_sell')
          AND t.trade_date<=?
        ORDER BY t.account_id, t.instrument_id, t.trade_date, t.created_at
        """,
        (as_of or datetime.now(timezone.utc).date().isoformat(),),
    ).fetchall()
    grouped: dict[tuple[str, str], dict[str, Any]] = {}
    for row in rows:
        key = (str(row["account_id"]), str(row["instrument_id"]))
        item = grouped.setdefault(key, dict(row) | {"quantity_total": ZERO})
        quantity = _decimal(row["quantity"])
        item["quantity_total"] += -abs(quantity) if str(row["transaction_type"]).lower() in SELL_TYPES else quantity
    official = latest_official_postfinance_positions(conn, as_of=as_of)
    post_snapshot_deltas = post_snapshot_postfinance_quantity_deltas(
        conn,
        official,
        as_of=as_of,
    )
    trading_cash_id = postfinance_account_roles(conn).get("etrading_cash")
    official_instruments = {key[1] for key in official}
    for key in list(grouped):
        if key[0] == trading_cash_id and key[1] in official_instruments:
            grouped.pop(key)
    for key, override in official.items():
        item = grouped.get(key)
        if item is None:
            instrument = conn.execute(
                """SELECT isin,name,lower(asset_class) asset_class,
                          upper(COALESCE(trading_currency,currency,'')) instrument_currency
                   FROM instruments WHERE instrument_id=? AND is_active=1""",
                (override.instrument_id,),
            ).fetchone()
            if not instrument:
                continue
            item = {
                "account_id": override.account_id,
                "instrument_id": override.instrument_id,
                "isin": instrument["isin"],
                "name": instrument["name"],
                "asset_class": instrument["asset_class"],
                "instrument_currency": instrument["instrument_currency"],
            }
            grouped[key] = item
        # The official snapshot is the baseline. Only confirmed trades after that
        # snapshot are replayed, so imported history is not counted twice.
        item["quantity_total"] = override.quantity + post_snapshot_deltas.get(
            override.instrument_id,
            ZERO,
        )
    return [
        ConfirmedPosition(
            account_id=item["account_id"],
            instrument_id=item["instrument_id"],
            isin=item["isin"],
            name=item["name"],
            asset_class=item["asset_class"],
            instrument_currency=item["instrument_currency"],
            quantity=item["quantity_total"],
        )
        for item in grouped.values()
        if item["quantity_total"] > ZERO
    ]

def _mapping(conn: Connection, position: ConfirmedPosition) -> tuple[dict[str, str] | None, str | None]:
    if not position.isin:
        return None, "mapping_required"
    rows = conn.execute(
        """
        SELECT provider, provider_symbol, provider_market,
               upper(COALESCE(trading_currency, currency, '')) AS mapping_currency


grep -n "INSERT INTO transactions" -n src/jarvis_finance/services/postfinance_service.py | head -20 && sed -n '640,760p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 3e0ec0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1491
Output:
484:        f"INSERT INTO transactions({columns}) VALUES({','.join('?' for _ in values)})", values
                    instrument_id,
                    _text(event.quantity),
                    _text(event.price_original),
                    _text(event.gross_original),
                    _text(event.fee_original) or "0",
                    _text(event.tax_original) or "0",
                    _text(event.net_original),
                    event.currency,
                    _text(event.fx_rate_to_chf),
                    event.internal_transfer_group,
                    event.quality_status,
                    json.dumps(event.reason_codes),
                    now,
                ),
            )
            for kind, amount in (
                ("gross", event.gross_original),
                ("fee", event.fee_original),
                ("tax", event.tax_original),
                ("net", event.net_original),
            ):
                if amount is not None and event.currency:
                    conn.execute(
                        "INSERT INTO postfinance_event_components(component_id,event_id,component_type,amount_original,currency,provenance_document_hash,created_at) VALUES(?,?,?,?,?,?,?)",
                        (
                            _id("pfcomponent"),
                            event_id,
                            kind,
                            _text(amount),
                            event.currency,
                            event.document_hash,
                            now,
                        ),
                    )
            _canonical_transaction(conn, event_id, event, account_id, instrument_id, now)
        lots: dict[str, list[dict[str, Any]]] = defaultdict(list)
        for event in sorted(
            bundle.events,
            key=lambda item: (
                item.occurred_on,
                0 if item.event_type == "buy" else 1,
                item.event_fingerprint,
            ),
        ):
            instrument_id = event_instruments[event.event_fingerprint]
            if (
                event.event_type == "buy"
                and instrument_id
                and event.quantity
                and event.price_original
                and event.currency
            ):
                lots[instrument_id].append({"event": event, "remaining": event.quantity})
            elif event.event_type == "sell" and instrument_id and event.quantity:
                to_consume = event.quantity
                for lot in lots[instrument_id]:
                    if to_consume <= 0:
                        break
                    consumed = min(lot["remaining"], to_consume)
                    lot["remaining"] -= consumed
                    to_consume -= consumed
        for instrument_id, instrument_lots in lots.items():
            for lot in instrument_lots:
                event = lot["event"]
                conn.execute(
                    """INSERT INTO postfinance_cost_basis_lots(lot_id,event_id,instrument_id,acquired_on,quantity_acquired,quantity_remaining,unit_cost_original,fees_original,currency,method,provenance_document_hash,created_at) VALUES(?,?,?,?,?,?,?,?,?,'documented_trade_fifo',?,?)""",
                    (
                        _id("pflot"),
                        f"pfevent_{event.event_fingerprint[:24]}",
                        instrument_id,
                        event.occurred_on,
                        _text(event.quantity),
                        _text(lot["remaining"]),
                        _text(event.price_original),
                        _text(event.fee_original) or "0",
                        event.currency,
                        event.document_hash,
                        now,
                    ),
                )
        for position in snapshot.positions:
            instrument_id = position_map[position.row_reference]
            matched_lots = lots.get(instrument_id, [])
            quantity = sum((lot["remaining"] for lot in matched_lots), Decimal("0"))
            complete = (
                bool(matched_lots)
                and quantity == position.quantity
                and len({lot["event"].currency for lot in matched_lots}) == 1
            )
            calculated = (
                sum(
                    (
                        lot["remaining"] * (lot["event"].price_original or 0)
                        + (lot["event"].fee_original + lot["event"].tax_original)
                        * (lot["remaining"] / lot["event"].quantity)
                        for lot in matched_lots
                        if lot["event"].quantity
                    ),
                    Decimal("0"),
                )
                if complete
                else None
            )
            status = "complete" if complete else "partial" if matched_lots else "unavailable"
            conn.execute(
                """INSERT INTO postfinance_snapshot_positions(snapshot_position_id,snapshot_id,source_row_reference,instrument_id,asset_class,quantity,provider_average_cost_original,provider_cost_total_original,price_original,price_currency,value_chf,weight_pct,computed_cost_basis_original,computed_cost_basis_status,provenance_json,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
                (
                    _id("pfposition"),
                    snapshot_id,
                    position.row_reference,
                    instrument_id,
                    position.asset_class,
                    _text(position.quantity),
                    _text(position.provider_average_cost_original),
                    _text(position.provider_cost_total_original),
                    _text(position.market_price_original),
                    position.price_currency,
                    _money(position.market_value_chf),
                    _text(position.weight_pct),
                    _text(calculated),
                    status,


sed -n '440,510p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 03db39
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 667
Output:
        "transaction_id,transaction_type,account_id,instrument_id,trade_date,settlement_date,quantity,"
        "price_original,gross_amount_original,fee_original,tax_original,net_amount_original,currency_original,"
        "fx_rate_to_chf,fx_source,fx_status,gross_amount_chf,fee_chf,tax_chf,net_amount_chf,source_type,source_id,"
        "external_transaction_id,row_hash,is_confirmed,quality_status,notes,created_at,updated_at,is_voided,"
        "activity_kind,booking_date,base_currency,internal_transfer_group_id,source_reference"
    )
    values = (
        event_id,
        tx_type,
        account_id,
        instrument_id,
        event.occurred_on,
        event.settlement_on,
        _text(event.quantity),
        _text(event.price_original),
        _text(event.gross_original),
        _text(event.fee_original) or "0",
        _text(event.tax_original) or "0",
        _text(event.net_original),
        event.currency,
        _text(event.fx_rate_to_chf),
        None,
        "unavailable",
        None,
        None,
        None,
        None,
        "postfinance_official_import",
        event_id,
        event.event_fingerprint,
        event.event_fingerprint,
        1,
        event.quality_status,
        "Verified PostFinance document event",
        now,
        None,
        0,
        activity,
        event.settlement_on or event.occurred_on,
        "CHF",
        event.internal_transfer_group,
        _hash(event.semantic_reference),
    )
    conn.execute(
        f"INSERT INTO transactions({columns}) VALUES({','.join('?' for _ in values)})", values
    )

def confirm_postfinance_import(conn: Connection, request: dict[str, Any]) -> dict[str, Any]:
    if request.get("confirm") is not True:
        raise ValueError("Explicit PostFinance import confirmation is required")
    preview = preview_postfinance_import(conn, request)
    if (
        request.get("preview_id") != preview["preview_id"]
        or request.get("confirmation_id") != preview["confirmation_id"]
    ):
        raise ValueError("PostFinance import preview is stale or changed")
    if preview["conflict"]:
        raise ValueError("PostFinance source conflicts with existing immutable business identity")
    if preview["duplicate"]:
        row = conn.execute(
            "SELECT batch_id,audit_id FROM postfinance_import_batches WHERE bundle_sha256=?",
            (preview["bundle_sha256"],),
        ).fetchone()
        return {
            "status": "confirmed",
            "batch_id": row["batch_id"],
            "audit_id": row["audit_id"],
            "idempotent": True,
        }
    accounts = _resolve_accounts(conn, request)


grep -R "vue_equity_sale" -n src tests | head -40


Output:
Chunk ID: 5fa52b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 400
Output:
grep: src/jarvis_finance/services/__pycache__/cash_service.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/manual_entry_service.cpython-311.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_functional_actions_v2.cpython-311-pytest-9.0.2.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_functional_actions_v2.cpython-311-pytest-9.1.1.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_functional_actions_v2.cpython-311.pyc: binary file matches
src/jarvis_finance/services/manual_entry_service.py:916:        VALUES (?, 'sell', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'vue_equity_sale', 1, ?, ?, ?)
src/jarvis_finance/services/manual_entry_service.py:919:        conn.execute("INSERT INTO cash_balances(cash_balance_id, account_id, balance_date, currency, amount_original, fx_rate_to_chf, amount_chf, source_type, quality_status, notes, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (_uuid("cash"), request.cash_account_id, request.trade_date, request.currency.upper(), _format_decimal(net), fx_rate, net_chf, f"vue_equity_sale:{tx_id}", "ok" if fx_status != "missing" else "missing_fx", request.note, ts))
src/jarvis_finance/services/cash_service.py:228:              AND (source_type LIKE 'vue_equity_sale:%'
src/jarvis_finance/services/cash_service.py:237:            if source_type.startswith("vue_equity_sale:")
tests/unit/test_dashboard_functional_actions_v2.py:102:    assert conn.execute("SELECT COUNT(*) FROM cash_balances WHERE source_type LIKE 'vue_equity_sale:%'").fetchone()[0] == 1


sed -n '880,925p' src/jarvis_finance/services/manual_entry_service.py


Output:
Chunk ID: 5159d3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1023
Output:
    fees = _decimal_non_negative(request.fees_original, "fees_original")
    current = _current_equity_quantity(conn, account_id=account_id, instrument_id=instrument_id)
    if quantity > current:
        raise HTTPException(status_code=422, detail="Verkauf würde Bestand negativ machen")
    gross = quantity * price
    net = gross - fees
    if net < 0:
        raise HTTPException(status_code=422, detail="fees exceed gross proceeds")
    currency = request.currency.upper()
    fx_status, fx_rate, _fx_source, fx_warning = _fx_for_explicit_save(conn, currency=currency, trade_date=request.trade_date)
    amount_chf = _chf_amount(_format_decimal(net), Decimal(fx_rate) if fx_rate else None)
    avg = _weighted_average_cost(conn, account_id=account_id, instrument_id=instrument_id)
    warnings = [fx_warning] if fx_warning else []
    if avg is None:
        warnings.append("Einstand unvollständig: realisierter P&L nur eingeschränkt verfügbar.")
    return PreviewResponse(preview_id=_uuid("preview"), asset_class="equity", summary=f"Verkauf {quantity} · Erlös {currency} {_format_decimal(net)}", amount_chf=amount_chf, fx_status=fx_status, warnings=warnings)

def confirm_equity_sell(conn: Connection, request: EquitySellConfirmRequest) -> ConfirmResponse:
    if not request.confirm:
        raise HTTPException(status_code=400, detail="Explicit confirm required")
    preview = preview_equity_sell(conn, request)
    account_id, instrument_id = _position_ids(request.position_id)
    quantity = _decimal(request.quantity, "quantity")
    price = _decimal(request.price_original, "price_original")
    fees = _decimal_non_negative(request.fees_original, "fees_original")
    gross = quantity * price
    net = gross - fees
    fx_status, fx_rate, fx_source, _ = _fx_for_explicit_save(conn, currency=request.currency, trade_date=request.trade_date)
    gross_chf = _chf_amount(_format_decimal(gross), Decimal(fx_rate) if fx_rate else None)
    fee_chf = _chf_amount(_format_decimal(fees), Decimal(fx_rate) if fx_rate else None)
    net_chf = _chf_amount(_format_decimal(net), Decimal(fx_rate) if fx_rate else None)
    tx_id = _uuid("tx")
    ts = _now()
    conn.execute("""
        INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, price_original, gross_amount_original, fee_original, net_amount_original, currency_original, fx_rate_to_chf, fx_source, fx_status, gross_amount_chf, fee_chf, net_amount_chf, source_type, is_confirmed, quality_status, notes, created_at)
        VALUES (?, 'sell', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'vue_equity_sale', 1, ?, ?, ?)
    """, (tx_id, account_id, instrument_id, request.trade_date, _format_decimal(-quantity), _format_decimal(price), _format_decimal(gross), _format_decimal(fees), _format_decimal(net), request.currency.upper(), fx_rate, fx_source, fx_status, gross_chf, fee_chf, net_chf, "ok" if fx_status != "missing" else "missing_fx", request.note, ts))
    if _cash_account_exists(conn, request.cash_account_id):
        conn.execute("INSERT INTO cash_balances(cash_balance_id, account_id, balance_date, currency, amount_original, fx_rate_to_chf, amount_chf, source_type, quality_status, notes, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (_uuid("cash"), request.cash_account_id, request.trade_date, request.currency.upper(), _format_decimal(net), fx_rate, net_chf, f"vue_equity_sale:{tx_id}", "ok" if fx_status != "missing" else "missing_fx", request.note, ts))
    audit_id = _audit(conn, action="equity_sell_confirm", entity_type="position", entity_id=request.position_id, payload={**request.model_dump(), "net_amount_original": _format_decimal(net), "gross_amount_original": _format_decimal(gross)}, note=request.note, quality_status="ok" if fx_status != "missing" else "missing_fx")
    conn.commit()
    return ConfirmResponse(status="confirmed", entity_id=tx_id, audit_id=audit_id, message="Verkauf bestätigt · Audit geschrieben")

def preview_equity_dividend(conn: Connection, request: EquityDividendPreviewRequest) -> PreviewResponse:


grep -R "calculate_cash_balances" -n src tests | grep -v pyc


Output:
Chunk ID: 73f2ed
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 441
Output:
grep: src/jarvis_finance/ledger/__pycache__/cash.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/cash_service.cpython-311.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_mvp_regressions.cpython-311-pytest-9.0.2.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_mvp_regressions.cpython-311-pytest-9.1.1.pyc: binary file matches
grep: tests/unit/__pycache__/test_dashboard_mvp_regressions.cpython-311.pyc: binary file matches
grep: tests/unit/__pycache__/test_ledger_cash_wac_positions.cpython-311.pyc: binary file matches
grep: tests/unit/__pycache__/test_ledger_cash_wac_positions.cpython-311-pytest-9.1.1.pyc: binary file matches
grep: tests/unit/__pycache__/test_ledger_cash_wac_positions.cpython-311-pytest-9.0.2.pyc: binary file matches
src/jarvis_finance/ledger/cash.py:65:def calculate_cash_balances(
src/jarvis_finance/services/cash_service.py:22:from jarvis_finance.ledger.cash import _signed_cash_delta, calculate_cash_balances
src/jarvis_finance/services/cash_service.py:168:    ledger = calculate_cash_balances(conn, persist_alerts=False)
src/jarvis_finance/services/cash_service.py:270:    ledger = calculate_cash_balances(conn, persist_alerts=False)
tests/unit/test_dashboard_mvp_regressions.py:9:from jarvis_finance.ledger.cash import calculate_cash_balances
tests/unit/test_dashboard_mvp_regressions.py:126:    balances = calculate_cash_balances(conn)
tests/unit/test_ledger_cash_wac_positions.py:5:from jarvis_finance.ledger.cash import apply_manual_cash_correction, calculate_cash_balances
tests/unit/test_ledger_cash_wac_positions.py:52:    result = calculate_cash_balances(conn)
tests/unit/test_ledger_cash_wac_positions.py:65:    result = calculate_cash_balances(conn)


Output:
Chunk ID: 13487a
Wall time: 30.0009 seconds
Process running with session ID 61478
Original token count: 0
Output:


Output:
Chunk ID: 2a7f6f
Wall time: 0.0000 seconds
Process exited with code 1
Original token count: 0
Output:


Output:
Chunk ID: 498685
Wall time: 5.0016 seconds
Process running with session ID 61478
Original token count: 0
Output:


sed -n '1,100p' tests/unit/test_ledger_cash_wac_positions.py && sed -n '100,150p' tests/unit/test_dashboard_mvp_regressions.py


Output:
Chunk ID: e2174f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1844
Output:
from __future__ import annotations

from decimal import Decimal

from jarvis_finance.ledger.cash import apply_manual_cash_correction, calculate_cash_balances
from jarvis_finance.ledger.positions import calculate_positions, save_position_snapshots
from jarvis_finance.storage.database import connect_memory
from jarvis_finance.storage.migrations import apply_migrations

def setup_conn():
    conn = connect_memory()
    apply_migrations(conn)
    conn.execute("INSERT INTO platforms(platform_id,name,platform_type,default_currency,created_at) VALUES('p1','Demo Broker','broker','CHF','now')")
    conn.execute("INSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,created_at) VALUES('a1','p1','Main','brokerage','CHF','now')")
    conn.execute("INSERT INTO instruments(instrument_id,asset_class,name,ticker,isin,currency,created_at) VALUES('i1','equity','Demo AG','DAG','CH0001','CHF','now')")
    conn.execute("INSERT INTO instruments(instrument_id,asset_class,name,ticker,isin,currency,created_at) VALUES('u1','equity','USD Demo Inc','UDI','US0001','USD','now')")
    return conn

def tx(conn, tid, ttype, *, instrument='i1', date='2026-01-01', qty=None, gross=None, fee=0, tax=0, net=None, currency='CHF', fx=1, note='synthetic'):
    conn.execute(
        """INSERT INTO transactions(
            transaction_id, transaction_type, account_id, instrument_id, trade_date,
            quantity, price_original, gross_amount_original, fee_original, tax_original,
            net_amount_original, currency_original, fx_rate_to_chf, fx_status,
            gross_amount_chf, fee_chf, tax_chf, net_amount_chf,
            source_type, is_confirmed, quality_status, notes, created_at
        ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
        (
            tid, ttype, 'a1', instrument, date, str(qty) if qty is not None else None, None,
            str(gross) if gross is not None else None, str(fee), str(tax), str(net) if net is not None else None,
            currency, str(fx) if fx is not None else None, 'ok' if fx is not None else 'missing',
            str(Decimal(str(gross))*Decimal(str(fx))) if gross is not None and fx is not None else None,
            str(Decimal(str(fee))*Decimal(str(fx))) if fx is not None else None,
            str(Decimal(str(tax))*Decimal(str(fx))) if fx is not None else None,
            str(Decimal(str(net))*Decimal(str(fx))) if net is not None and fx is not None else None,
            'synthetic', 1, 'ok' if fx is not None else 'incomplete', note, 'now'
        ),
    )

def test_initial_cash_snapshot_is_start_truth_and_buy_sell_dividend_fee_tax_move_cash() -> None:
    conn = setup_conn()
    tx(conn, 'c0', 'initial_cash_snapshot', instrument=None, gross=1000, net=1000)
    tx(conn, 'b1', 'buy', qty=5, gross=500, fee=5, net=505)
    tx(conn, 's1', 'partial_sell', qty=2, gross=260, fee=2, tax=1, net=257)
    tx(conn, 'd1', 'dividend', qty=None, gross=20, tax=7, net=13)
    tx(conn, 'f1', 'fee', instrument=None, gross=3, net=3)
    tx(conn, 't1', 'tax', instrument=None, gross=4, net=4)

    result = calculate_cash_balances(conn)

    key = ('a1', 'CHF')
    assert result.balances[key].amount_original == Decimal('758')
    assert result.balances[key].amount_chf == Decimal('758')
    assert result.negative_cash_warnings == []

def test_cash_negative_creates_warning_not_correction() -> None:
    conn = setup_conn()
    tx(conn, 'c0', 'initial_cash_snapshot', instrument=None, gross=100, net=100)
    tx(conn, 'b1', 'buy', qty=2, gross=200, fee=0, net=200)

    result = calculate_cash_balances(conn)

    assert result.balances[('a1', 'CHF')].amount_original == Decimal('-100')
    assert result.negative_cash_warnings
    alert = conn.execute("SELECT priority, rule_id FROM alerts WHERE rule_id='negative_cash'").fetchone()
    assert alert['priority'] == 'warnung'

def test_manual_cash_correction_requires_note_and_audit() -> None:
    conn = setup_conn()
    try:
        apply_manual_cash_correction(conn, account_id='a1', currency='CHF', amount=Decimal('10'), note='')
    except ValueError as exc:
        assert 'note' in str(exc)
    else:
        raise AssertionError('expected note validation')

    audit_id = apply_manual_cash_correction(conn, account_id='a1', currency='CHF', amount=Decimal('10'), note='Synthetic reconciliation')
    assert audit_id
    assert conn.execute("SELECT COUNT(*) AS n FROM audit_log WHERE action='manual_cash_correction'").fetchone()['n'] == 1

def test_weighted_average_cost_buy_fee_usd_fx_and_partial_sell_realized_pnl() -> None:
    conn = setup_conn()
    tx(conn, 'b1', 'buy', instrument='u1', date='2026-01-01', qty=10, gross=1000, fee=10, net=1010, currency='USD', fx='0.90')
    tx(conn, 'b2', 'buy', instrument='u1', date='2026-01-02', qty=10, gross=1200, fee=12, net=1212, currency='USD', fx='0.80')
    tx(conn, 's1', 'partial_sell', instrument='u1', date='2026-01-03', qty=5, gross=700, fee=7, net=693, currency='USD', fx='0.85')

    positions = calculate_positions(conn)
    pos = positions.positions[('a1', 'u1')]

    assert pos.quantity == Decimal('15')
    assert pos.cost_basis_original == Decimal('1666.5')
    assert pos.cost_basis_chf == Decimal('1408.95')
    assert pos.average_cost_original == Decimal('111.1')
    assert pos.realized_pnl_chf == Decimal('119.40')
        assert internal not in text
    assert "Automatisch aus Cache/Provider holen" in text

def test_cash_asset_choice_renders_cash_entry_and_writes_audited_snapshot() -> None:
    conn = connect_memory()
    apply_migrations(conn)
    ensure_standard_broker_accounts(conn)
    st = FakeStreamlit(
        button_presses={"Cash speichern"},
        inputs={
            "position_add_asset_choice": "Cash",
            "position_add_cash_account": "Anderes Konto · Manual Portfolio · CHF",
            "position_add_cash_currency": "CHF",
            "position_add_cash_amount": "123.45",
            "position_add_cash_date": "2026-01-31",
            "position_add_cash_note": "synthetic cash balance",
            "position_add_cash_confirm": True,
        },
    )

    page_17_position_add.render(st, conn)

    text = _visible_text(st)
    assert "Cash erfassen" in text
    assert "Cash gespeichert" in text
    balances = calculate_cash_balances(conn)
    assert any(balance.amount_original == Decimal("123.45") and balance.currency == "CHF" for balance in balances.balances.values())

def test_equity_page_refreshes_valuation_from_mapped_provider(monkeypatch) -> None:
    conn, account_id, catalog_id = setup_equity_conn()
    upsert_fx_rate(conn, base_currency="USD", quote_currency="CHF", rate_date="2026-01-15", rate=Decimal("0.90"), provider="mock", rate_type="close")
    add_manual_position_from_catalog(
        conn,
        catalog_entry_id=catalog_id,
        account_id=account_id,
        position_type="initial_snapshot",
        quantity_text="2",
        trade_date="2026-01-15",
        currency="USD",
        cost_basis_original_text="100",
        note="synthetic unvalued position",
        confirm=True,
    )
    monkeypatch.setattr(page_03_equities_etfs, "equity_price_provider_by_name", lambda _name: MockEquityPriceProvider({"SYNV": "50"}, currency="USD"))

    st = FakeStreamlit(button_presses={"Bewertung aktualisieren"})
    page_03_equities_etfs.render(st, conn)

    text = _visible_text(st)


pytest -q tests/unit/test_ledger_cash_wac_positions.py tests/unit/test_dashboard_functional_actions_v2.py


Output:
Chunk ID: e29d9a
Wall time: 30.0020 seconds
Process running with session ID 16366
Original token count: 2
Output:
........


grep -n "def confirm_equity_buy" -A45 src/jarvis_finance/services/manual_entry_service.py


Output:
Chunk ID: 476831
Wall time: 0.0000 seconds
Process exited with code 1
Original token count: 0
Output:


grep -R "vue_equity_buy\|equity_buy" -n src/jarvis_finance/services/manual_entry_service.py | head -40


Output:
Chunk ID: 68c163
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


sed -n '1590,1675p' src/jarvis_finance/services/portfolio_data.py


Output:
Chunk ID: 209d43
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1516
Output:
        differences.append({
            "difference_ref": _safe_ref("difference", f"{account}:{instrument}:{as_of}"),
            "account_ref": _safe_ref("account", account), "account_label": _safe_label(account_map[account]["account_name"]),
            "instrument_ref": _safe_ref("instrument", instrument), "instrument_label": str(instrument_row["name"]) if instrument_row else "Instrument (unbekannt)",
            "quantity": {"ledger": _decimal_text(ledger_qty), "reported": _decimal_text(source_qty), "difference": _decimal_text(quantity_diff), "status": quantity_status},
            "valuation": {"derived": _decimal_text(derived_value), "reported": _decimal_text(reported_value), "difference": _decimal_text(value_diff), "relative_difference": _decimal_text(relative_diff), "status": value_status,
                          "position_as_of": str(source["snapshot_date"]) if source else None, "price_as_of": price_date, "fx_as_of": fx_date, "price_source": price_source, "fx_source": fx_source},
            "reason_codes": sorted(set(reasons)),
        })
    pf_roles = postfinance_account_roles(conn)
    official_pf_cash = latest_official_postfinance_cash(
        conn,
        as_of=as_of,
        data_cutoff=cutoff,
    )
    official_pf_cash_total = sum(
        (component.amount_chf for component in official_pf_cash), Decimal("0")
    )
    official_pf_cash_date = max(
        (component.snapshot_date for component in official_pf_cash), default=None
    )
    account_totals: list[dict[str, Any]] = []
    account_covered = 0
    for account, meta in account_map.items():
        cash = conn.execute(
            """SELECT amount_chf,balance_date,source FROM cash_account_snapshots WHERE account_id=? AND balance_date<=?
               AND datetime(created_at)<=datetime(?)
               ORDER BY balance_date DESC,created_at DESC,snapshot_id DESC LIMIT 1""", (account, as_of, cutoff)
        ).fetchone()
        cash_value = _stored_decimal(cash["amount_chf"], "Cashbestand") if cash else None
        cash_date = str(cash["balance_date"]) if cash else None
        if account == pf_roles.get("etrading_depot") and official_pf_cash:
            # The provider account total spans the distinct depot and trading-cash
            # roles. This is a reconciliation-only join, not an additive holding.
            cash_value = official_pf_cash_total
            cash_date = official_pf_cash_date
        legacy = conn.execute(
            """SELECT total_value_chf,valuation_date,source_type FROM account_value_snapshots
               WHERE account_id=? AND valuation_date<=? AND datetime(created_at)<=datetime(?)
                 AND COALESCE(is_active,1)=1
               ORDER BY valuation_date DESC,
                        CASE source_type WHEN 'truewealth_official_import' THEN 3 WHEN 'truewealth_manual_provisional' THEN 2 ELSE 1 END DESC,
                        COALESCE(valuation_at,created_at) DESC,created_at DESC,snapshot_id DESC LIMIT 1""", (account, as_of, cutoff)
        ).fetchone()
        reported_total = _stored_decimal(legacy["total_value_chf"], "Kontototal") if legacy else None
        total_date = str(legacy["valuation_date"]) if legacy else None
        has_positions = any(key[0] == account for key in reported)
        derived_total = account_position_values[account] + (cash_value or Decimal("0")) if has_positions or cash else None
        reasons: list[str] = []
        total_status = "unavailable"
        diff: Decimal | None = None
        total_value_only = meta["account_type"] in {"robo_advisor", "total_value", "pension", "truewealth"} or (legacy is not None and not any(key[0] == account for key in keys))
        canonical_date: str | None = None
        if total_value_only:
            canonical = conn.execute(
                """SELECT value_original,valuation_at FROM portfolio_valuation_snapshots
                   WHERE scope_kind='account' AND scope_id=? AND substr(valuation_at,1,10)<=?
                     AND datetime(captured_at)<=datetime(?)
                   ORDER BY valuation_at DESC,snapshot_version DESC,captured_at DESC,snapshot_id DESC LIMIT 1""", (account, as_of, cutoff)
            ).fetchone()
            derived_total = _stored_decimal(canonical["value_original"], "Kanonischer Totalwert") if canonical else None
            canonical_date = str(canonical["valuation_at"])[:10] if canonical else None
            if canonical and total_date != canonical_date:
                reasons.append("cutoff_mismatch")
        dates = set(account_position_dates[account]) | ({cash_date} if cash_date else set()) | ({total_date} if total_date else set()) | ({canonical_date} if canonical_date else set())
        if derived_total is None:
            reasons.append("missing_position_snapshot" if not total_value_only else "missing_account_valuation")
        if reported_total is None:
            reasons.append("missing_account_valuation")
        if derived_total is not None and reported_total is not None:
            stale_dates = {item for item in dates if item and item != as_of}
            if len({item for item in dates if item}) > 1 or stale_dates or "cutoff_mismatch" in reasons:
                total_status = "not_comparable"
                if stale_dates:
                    reasons.append("stale_snapshot")
                if "cutoff_mismatch" not in reasons:
                    reasons.append("cutoff_mismatch")
            else:
                diff = derived_total - reported_total
                total_status = _status(diff, reported_total, absolute, relative)
                if total_status == "mismatch":
                    reasons.append("cash_gap" if cash_value is None and not total_value_only else "value_mismatch")
                account_covered += 1
        account_totals.append({
            "account_ref": _safe_ref("account", account), "account_label": _safe_label(meta["account_name"]),
            "total_value_only": total_value_only, "positions_value": None if total_value_only else _decimal_text(account_position_values[account]),


grep -n "positions_snapshot" -n src/jarvis_finance/services/postfinance_service.py | head -20 && sed -n '790,845p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 20250d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 777
Output:
164:        "positions_snapshot",
187:           FROM positions_snapshot p JOIN instruments i ON i.instrument_id=p.instrument_id
327:        "SELECT COUNT(*) FROM positions_snapshot WHERE account_id=? AND snapshot_date=?",
773:                """INSERT INTO positions_snapshot(position_snapshot_id,snapshot_date,account_id,platform_id,instrument_id,quantity,average_cost_original,cost_basis_original,market_price_original,market_value_original,market_fx_rate_to_chf,market_value_chf,portfolio_weight_pct,category,data_quality_status,source_type,source_reference,created_at) SELECT ?,?,?,a.platform_id,?,?,?,?,?,?,?,?,?,?,?,?,?,? FROM accounts a WHERE a.account_id=?""",
                    snapshot_id,
                    now,
                    accounts["etrading_depot"],
                ),
            )
        for cash in snapshot.cash:
            conn.execute(
                "INSERT INTO postfinance_snapshot_cash(snapshot_cash_id,snapshot_id,currency,amount_original,fx_rate_to_chf,value_chf,created_at) VALUES(?,?,?,?,?,?,?)",
                (
                    _id("pfcash"),
                    snapshot_id,
                    cash.currency,
                    _text(cash.amount_original),
                    _text(cash.fx_rate_to_chf),
                    _money(cash.source_value_chf),
                    now,
                ),
            )
            conn.execute(
                "INSERT INTO cash_balances(cash_balance_id,account_id,balance_date,currency,amount_original,fx_rate_to_chf,amount_chf,source_type,quality_status,notes,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)",
                (
                    _id("cash"),
                    accounts["etrading_cash"],
                    snapshot.valuation_at[:10],
                    cash.currency,
                    _text(cash.amount_original),
                    _text(cash.fx_rate_to_chf),
                    _money(cash.source_value_chf),
                    "postfinance_official_import",
                    "verified",
                    "Official PostFinance account overview",
                    now,
                ),
            )
        conn.execute(
            "INSERT INTO account_value_snapshots(snapshot_id,account_id,valuation_date,total_value_chf,currency,source_type,quality_status,notes,created_at,valuation_at,source_reference,is_active) VALUES(?,?,?,?,'CHF','postfinance_official_import','ok','Official PostFinance account overview',?,?,?,1)",
            (
                _id("acctval"),
                accounts["etrading_depot"],
                snapshot.valuation_at[:10],
                _money(snapshot.total_value_chf),
                now,
                snapshot.valuation_at,
                snapshot_id,
            ),
        )
        conn.commit()
    except IntegrityError as exc:
        conn.rollback()
        duplicate = conn.execute(
            "SELECT batch_id,audit_id FROM postfinance_import_batches WHERE bundle_sha256=?",
            (bundle.bundle_hash,),
        ).fetchone()
        if duplicate:
            return {
                "status": "confirmed",


sed -n '750,790p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 27ab50
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 546
Output:
                    instrument_id,
                    position.asset_class,
                    _text(position.quantity),
                    _text(position.provider_average_cost_original),
                    _text(position.provider_cost_total_original),
                    _text(position.market_price_original),
                    position.price_currency,
                    _money(position.market_value_chf),
                    _text(position.weight_pct),
                    _text(calculated),
                    status,
                    json.dumps(
                        {
                            "provider": "official_account_overview",
                            "calculated": "documented_trade_fifo",
                            "estimated": False,
                        },
                        sort_keys=True,
                    ),
                    now,
                ),
            )
            conn.execute(
                """INSERT INTO positions_snapshot(position_snapshot_id,snapshot_date,account_id,platform_id,instrument_id,quantity,average_cost_original,cost_basis_original,market_price_original,market_value_original,market_fx_rate_to_chf,market_value_chf,portfolio_weight_pct,category,data_quality_status,source_type,source_reference,created_at) SELECT ?,?,?,a.platform_id,?,?,?,?,?,?,?,?,?,?,?,?,?,? FROM accounts a WHERE a.account_id=?""",
                (
                    _id("position"),
                    snapshot.valuation_at[:10],
                    accounts["etrading_depot"],
                    instrument_id,
                    _text(position.quantity),
                    _text(position.provider_average_cost_original),
                    _text(position.provider_cost_total_original),
                    _text(position.market_price_original),
                    _text(position.quantity * position.market_price_original),
                    None,
                    _money(position.market_value_chf),
                    _text(position.weight_pct),
                    position.asset_class,
                    "verified",
                    "postfinance_official_import",
                    snapshot_id,


sed -n '1470,1588p' src/jarvis_finance/services/portfolio_data.py