Output:
Chunk ID: 7ac0b8
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 6609
Output:
              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/src/jarvis_finance/services/equity_service.py b/src/jarvis_finance/services/equity_service.py
index 614e76b..acb3fca 100644
--- a/src/jarvis_finance/services/equity_service.py
+++ b/src/jarvis_finance/services/equity_service.py
@@ -108,24 +108,57 @@ def list_equity_positions(conn: Connection) -> list[EquityPosition]:
         and row.get("instrument_status", "").lower() != "inactive"
     ]
     analysis, values, missing = _latest_analysis(conn)
-    use_cache_fallback = analysis is None
-    expected_keys = {(str(row.get("account_id") or ""), str(row.get("instrument_id") or "")) for row in source_rows}
-    complete = bool(analysis and analysis.get("quality_status") == "complete" and set(values) == expected_keys)
-    total = sum((Decimal(str(item.get("value_chf") or "0")) for item in values.values()), Decimal("0"))
+    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",
+        }
+        candidate_is_newer = bool(
+            analysis
+            and candidate
+            and str(analysis.get("as_of") or "") > str(row.get("valuation_as_of") or row.get("price_date") or "")
+            and candidate.get("quality_status") == "fresh"
+        )
+        raw = (
+            candidate.get("value_chf")
+            if candidate_is_newer and candidate
+            else row.get("market_value_chf") if analysis is None or row_is_audited else None
+        )
+        effective_values[key] = Decimal(str(raw)) if raw not in {None, ""} else None
+    complete = bool(source_rows) and all(value is not None for value in effective_values.values())
+    total = sum((value or Decimal("0") for value in effective_values.values()), Decimal("0"))
     positions: list[EquityPosition] = []
     for row in source_rows:
         account_id = str(row.get("account_id") or "")
         instrument_id = str(row.get("instrument_id") or "")
         snapshot_value = values.get((account_id, instrument_id))
-        value = snapshot_value if snapshot_value and snapshot_value.get("quality_status") == "fresh" else None
+        value = (
+            snapshot_value
+            if analysis
+            and snapshot_value
+            and snapshot_value.get("quality_status") == "fresh"
+            and str(analysis.get("as_of") or "") > str(row.get("valuation_as_of") or row.get("price_date") or "")
+            else None
+        )
+        row_fallback_allowed = analysis is None or row.get("valuation_source") in {
+            "postfinance_official_import",
+            "audited_market_run",
+        }
         mapping = _mapping_details(conn, instrument_id)
-        raw_market_value = value.get("value_chf") if value else (row.get("market_value_chf") if use_cache_fallback else None)
-        if use_cache_fallback and Decimal(str(row.get("quantity") or "0")) <= 0:
+        raw_market_value = (
+            value.get("value_chf")
+            if value
+            else row.get("market_value_chf") if row_fallback_allowed else None
+        )
+        if Decimal(str(row.get("quantity") or "0")) <= 0:
             raw_market_value = None
         market_value = Decimal(str(raw_market_value)) if raw_market_value not in {None, ""} else None
         share = (market_value / total * Decimal("100")) if complete and market_value is not None and total > 0 else None
         code = "valued" if market_value is not None else ("stale_price" if snapshot_value else missing.get(instrument_id, "price_missing"))
-        status = "Bewertet" if value else ("Kurs veraltet" if snapshot_value else (_position_status(row) if use_cache_fallback else "Kurs fehlt"))
+        status = "Bewertet" if market_value is not None else ("Kurs veraltet" if snapshot_value else _position_status(row))
         provenance = value.get("price_input_provenance") if value else None
         provenance_provider = provenance.get("provider") if isinstance(provenance, dict) else None
         positions.append(EquityPosition(
@@ -138,11 +171,23 @@ def list_equity_positions(conn: Connection) -> list[EquityPosition]:
             asset_class=_asset_class_label(row.get("asset_class")),
             quantity=optional_decimal_text(row.get("quantity")) or "0",
             currency=str(value.get("currency") if value else mapping.get("currency") or row.get("price_currency") or row.get("currency") or ""),
-            price=optional_decimal_text(value.get("close")) if value else (optional_decimal_text(row.get("market_price_original") or row.get("price")) if use_cache_fallback else None),
+            price=(
+                optional_decimal_text(value.get("close"))
+                if value
+                else optional_decimal_text(row.get("market_price_original") or row.get("price"))
+                if row_fallback_allowed
+                else None
+            ),
             market_value_chf=optional_decimal_text(market_value, 2) if market_value is not None else None,
             portfolio_share_pct=optional_decimal_text(share, 2) if share is not None else None,
-            price_date=str(value.get("as_of")) if value else (str(analysis.get("as_of")) if analysis else None),
-            provider=str((value.get("provider") if value else None) or provenance_provider or mapping.get("provider") or ""),
+            price_date=(
+                str(analysis.get("as_of"))
+                if value and analysis
+                else str(row.get("valuation_as_of") or row.get("price_date") or "") or None
+                if row_fallback_allowed
+                else str(analysis.get("as_of")) if analysis else None
+            ),
+            provider=str((value.get("provider") if value else None) or provenance_provider or row.get("price_provider") or mapping.get("provider") or ""),
             provider_symbol=str(mapping.get("provider_symbol") or ""),
             exchange=str(mapping.get("provider_market") or ""),
             price_currency=str(value.get("currency") if value else mapping.get("currency") or row.get("price_currency") or row.get("currency") or ""),
@@ -161,6 +206,14 @@ def get_equity_summary(conn: Connection) -> EquityPortfolioSummary:
     complete = bool(positions) and len(valued) == len(positions)
     analysis, _, _ = _latest_analysis(conn)
     status = "complete" if complete else ("partial" if positions else "unavailable")
+    effective_as_of = max((item.price_date or "" for item in valued), default="") or None
+    analysis_as_of = str(analysis.get("as_of") or "") if analysis else ""
+    response_as_of = effective_as_of or analysis_as_of or None
+    last_successful = (
+        str(analysis.get("completed_at"))
+        if analysis and (not effective_as_of or analysis_as_of >= str(effective_as_of)[:10])
+        else effective_as_of
+    )
     return EquityPortfolioSummary(
         total_positions=len(positions),
         valued_positions=len(valued),
@@ -169,8 +222,8 @@ def get_equity_summary(conn: Connection) -> EquityPortfolioSummary:
         equity_value_chf=optional_decimal_text(partial, 2) if complete else None,
         valued_partial_chf=optional_decimal_text(partial, 2) or "0.00",
         value_label="Aktien-/ETF-Gesamtwert" if complete else "Bewerteter Teilwert",
-        as_of=str(analysis.get("as_of")) if analysis else None,
-        last_successful_run=str(analysis.get("completed_at")) if analysis else None,
+        as_of=response_as_of,
+        last_successful_run=last_successful,
         status=status,
         status_label=f"{len(valued)}/{len(positions)} bewertet" if positions else "Keine Aktien-/ETF-Positionen",
         unvalued_tickers=[item.ticker for item in positions if item.market_value_chf is None],
diff --git a/src/jarvis_finance/services/portfolio_analytics.py b/src/jarvis_finance/services/portfolio_analytics.py
index f6acbd6..5331de3 100644
--- a/src/jarvis_finance/services/portfolio_analytics.py
+++ b/src/jarvis_finance/services/portfolio_analytics.py
@@ -25,6 +25,11 @@ from jarvis_finance.market_data.prices import (
     exchange_matches,
     store_market_price,
 )
+from jarvis_finance.services.portfolio_aggregation import (
+    latest_official_postfinance_positions,
+    post_snapshot_postfinance_quantity_deltas,
+    postfinance_account_roles,
+)
 from jarvis_finance.services.portfolio_performance import build_portfolio_performance

 ZERO = Decimal("0")
@@ -224,6 +229,43 @@ def confirmed_canonical_positions(conn: Connection, *, as_of: str | None = None)
         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"],
diff --git a/src/jarvis_finance/services/portfolio_data.py b/src/jarvis_finance/services/portfolio_data.py
index 7a5762e..a80d646 100644
--- a/src/jarvis_finance/services/portfolio_data.py
+++ b/src/jarvis_finance/services/portfolio_data.py
@@ -6,27 +6,33 @@ reconciliation are pure database projections. Confirm is the only write boundary

 from __future__ import annotations

-from dataclasses import dataclass
-from datetime import UTC, date, datetime, timedelta
-from decimal import Decimal, InvalidOperation
 import base64
 import binascii
 import hashlib
 import json
 import re
+import uuid
+from dataclasses import dataclass
+from datetime import UTC, date, datetime, timedelta
+from decimal import Decimal, InvalidOperation
 from sqlite3 import Connection, IntegrityError
 from typing import Any
-import uuid

 from jarvis_finance.audit.log import record_audit_event
+from jarvis_finance.imports.common import stable_id
 from jarvis_finance.imports.postfinance_etrading import (
     PostFinanceDocument,
-    decimal_text as postfinance_decimal_text,
     normalize_label,
     parse_postfinance_portfolio,
 )
-from jarvis_finance.imports.common import stable_id
+from jarvis_finance.imports.postfinance_etrading import (
+    decimal_text as postfinance_decimal_text,
+)
 from jarvis_finance.market_data.mappings import confirm_instrument_price_mapping
+from jarvis_finance.services.portfolio_aggregation import (
+    latest_official_postfinance_cash,
+    postfinance_account_roles,
+)

 INGESTION_VERSION = "portfolio_ingestion_v1"
 RECONCILIATION_VERSION = "portfolio_reconciliation_v1"
@@ -1434,7 +1440,8 @@ def _latest_fx(conn: Connection, currency: str, as_of: str, cutoff: str) -> tupl
         return Decimal("1"), as_of, "identity"
     row = conn.execute(
         """SELECT rate, rate_date, provider FROM fx_rates
-           WHERE base_currency=? AND quote_currency='CHF' AND rate_date<=? AND created_at<=?
+           WHERE base_currency=? AND quote_currency='CHF' AND rate_date<=?
+             AND datetime(created_at)<=datetime(?)
              AND rate IS NOT NULL AND quality_status IN ('ok','fresh','complete')
            ORDER BY rate_date DESC, created_at DESC, fx_rate_id DESC LIMIT 1""", (currency, as_of, cutoff)
     ).fetchone()
@@ -1463,7 +1470,8 @@ def build_portfolio_reconciliation(
         return {"as_of": as_of, "data_cutoff": cutoff, "base_currency": "CHF", "status": "unavailable", "reason_codes": ["missing_account_valuation"], "tolerance": {"version": TOLERANCE_VERSION, "absolute": str(absolute), "relative": str(relative)}, "coverage": empty_coverage, "differences": [], "account_totals": [], "input_fingerprint": _hash([as_of, cutoff, []]), "sources": [], "limit": limit, "offset": offset, "total": 0}
     placeholders = ",".join("?" for _ in account_map)
     transaction_rows = conn.execute(
-        f"""SELECT * FROM transactions WHERE account_id IN ({placeholders}) AND trade_date<=? AND created_at<=?
+        f"""SELECT * FROM transactions WHERE account_id IN ({placeholders}) AND trade_date<=?
+            AND datetime(created_at)<=datetime(?)
             AND COALESCE(is_voided,0)=0 AND COALESCE(is_confirmed,1)=1
             ORDER BY trade_date, created_at, transaction_id""", (*account_map, as_of, cutoff)
     ).fetchall()
@@ -1490,7 +1498,8 @@ def build_portfolio_reconciliation(
     reported_rows = conn.execute(
         f"""WITH ranked AS (
               SELECT p.*, ROW_NUMBER() OVER(PARTITION BY account_id,instrument_id ORDER BY snapshot_date DESC,created_at DESC,position_snapshot_id DESC) rn
-              FROM positions_snapshot p WHERE account_id IN ({placeholders}) AND snapshot_date<=? AND created_at<=?
+              FROM positions_snapshot p WHERE account_id IN ({placeholders}) AND snapshot_date<=?
+                AND datetime(created_at)<=datetime(?)
             ) SELECT * FROM ranked WHERE rn=1""", (*account_map, as_of, cutoff)
     ).fetchall()
     reported = {(str(row["account_id"]), str(row["instrument_id"])): row for row in reported_rows}
@@ -1523,7 +1532,8 @@ def build_portfolio_reconciliation(
         derived_value: Decimal | None = None
         reported_value = _stored_decimal(source["market_value_chf"], "Gemeldeter Positionswert") if source and source["market_value_chf"] not in (None, "") else None
         price_row = conn.execute(
-            """SELECT close,currency,price_date,provider FROM market_prices WHERE instrument_id=? AND price_date<=? AND created_at<=?
+            """SELECT close,currency,price_date,provider FROM market_prices WHERE instrument_id=? AND price_date<=?
+               AND datetime(created_at)<=datetime(?)
                AND quality_status IN ('ok','fresh','complete') ORDER BY price_date DESC,created_at DESC,market_price_id DESC LIMIT 1""", (instrument, as_of, cutoff)
         ).fetchone()
         price_date = str(price_row["price_date"]) if price_row else None
@@ -1586,18 +1596,37 @@ def build_portfolio_reconciliation(
                           "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 created_at<=?
+            """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 created_at<=? AND COALESCE(is_active,1)=1
+               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)
@@ -1614,7 +1643,8 @@ def build_portfolio_reconciliation(
         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 captured_at<=?
+                   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
@@ -1651,10 +1681,10 @@ def build_portfolio_reconciliation(
         return {"covered": covered, "total": total, "ratio": _decimal_text(Decimal(covered) / Decimal(total)) if total else None}
     instrument_total = len(keys)
     opening_rows = conn.execute(
-        f"SELECT COUNT(DISTINCT account_id) AS count FROM portfolio_valuation_snapshots WHERE account_id IN ({placeholders}) AND substr(valuation_at,1,10)<? AND captured_at<=?", (*account_map, as_of, cutoff)
+        f"SELECT COUNT(DISTINCT account_id) AS count FROM portfolio_valuation_snapshots WHERE account_id IN ({placeholders}) AND substr(valuation_at,1,10)<? AND datetime(captured_at)<=datetime(?)", (*account_map, as_of, cutoff)
     ).fetchone()
     closing_rows = conn.execute(
-        f"SELECT COUNT(DISTINCT account_id) AS count FROM portfolio_valuation_snapshots WHERE account_id IN ({placeholders}) AND substr(valuation_at,1,10)=? AND captured_at<=?", (*account_map, as_of, cutoff)
+        f"SELECT COUNT(DISTINCT account_id) AS count FROM portfolio_valuation_snapshots WHERE account_id IN ({placeholders}) AND substr(valuation_at,1,10)=? AND datetime(captured_at)<=datetime(?)", (*account_map, as_of, cutoff)
     ).fetchone()
     opening_covered = int(opening_rows["count"] or 0)
     closing_covered = int(closing_rows["count"] or 0)
diff --git a/src/jarvis_finance/services/postfinance_service.py b/src/jarvis_finance/services/postfinance_service.py
index 9ea4ba8..b34d319 100644
--- a/src/jarvis_finance/services/postfinance_service.py
+++ b/src/jarvis_finance/services/postfinance_service.py
@@ -2,12 +2,12 @@ from __future__ import annotations

 import base64
 import binascii
+import json
+import os
 from collections import defaultdict
 from datetime import UTC, datetime
 from decimal import Decimal
 from hashlib import sha256
-import json
-import os
 from pathlib import Path
 from sqlite3 import Connection, IntegrityError
 from typing import Any
@@ -22,6 +22,10 @@ from jarvis_finance.imports.postfinance_documents import (
     normalize_label,
     parse_postfinance_bundle,
 )
+from jarvis_finance.services.portfolio_aggregation import (
+    latest_official_postfinance_cash,
+    latest_official_postfinance_positions,
+)

 TOLERANCE = Decimal("0.05")

@@ -876,6 +880,10 @@ def get_postfinance_summary(conn: Connection) -> dict[str, Any]:
             "event_counts": {},
             "imports": [],
         }
+    official_position_values = {
+        override.instrument_id: override.market_value_chf
+        for override in latest_official_postfinance_positions(conn).values()
+    }
     positions = [
         {
             "row_key": _hash("position", row["instrument_name"], row["quantity"])[:16],
@@ -887,13 +895,13 @@ def get_postfinance_summary(conn: Connection) -> dict[str, Any]:
             "provider_cost_total_original": row["provider_cost_total_original"],
             "price_original": row["price_original"],
             "price_currency": row["price_currency"],
-            "value_chf": row["value_chf"],
+            "value_chf": _money(official_position_values.get(row["instrument_id"], Decimal(str(row["value_chf"])))),
             "weight_pct": row["weight_pct"],
             "computed_cost_basis_original": row["computed_cost_basis_original"],
             "computed_cost_basis_status": row["computed_cost_basis_status"],
         }
         for row in conn.execute(
-            """SELECT p.asset_class,p.quantity,p.provider_average_cost_original,
+            """SELECT p.instrument_id,p.asset_class,p.quantity,p.provider_average_cost_original,
                       p.provider_cost_total_original,p.price_original,p.price_currency,p.value_chf,
                       p.weight_pct,p.computed_cost_basis_original,p.computed_cost_basis_status,
                       i.name AS instrument_name,i.ticker
@@ -905,17 +913,13 @@ def get_postfinance_summary(conn: Connection) -> dict[str, Any]:
     ]
     cash = [
         {
-            "row_key": _hash("cash", row["currency"])[:16],
-            "currency": row["currency"],
-            "amount_original": row["amount_original"],
-            "fx_rate_to_chf": row["fx_rate_to_chf"],
-            "value_chf": row["value_chf"],
+            "row_key": _hash("cash", component.currency)[:16],
+            "currency": component.currency,
+            "amount_original": _text(component.amount_original),
+            "fx_rate_to_chf": _text(component.source_fx_rate_to_chf),
+            "value_chf": _money(component.amount_chf),
         }
-        for row in conn.execute(
-            """SELECT currency,amount_original,fx_rate_to_chf,value_chf
-               FROM postfinance_snapshot_cash WHERE snapshot_id=? ORDER BY currency""",
-            (latest["snapshot_id"],),
-        ).fetchall()
+        for component in latest_official_postfinance_cash(conn)
     ]
     events = {
         str(row["event_type"]): int(row["c"])


grep -R "postfinance_account_roles" -n . | head -50 && grep -R "CREATE TABLE.*postfinance_account_roles\|postfinance_snapshot_positions\|postfinance_snapshot_cash" -n src tests | head -80


Output:
Chunk ID: 5036ec
Wall time: 0.8685 seconds
Process exited with code 0
Original token count: 1863
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:100:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_aggregation.py:153:    roles = postfinance_account_roles(conn)
./src/jarvis_finance/services/portfolio_aggregation.py:223:    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:186:                  SELECT account_id FROM postfinance_account_roles
./tests/test_postfinance_sprint13.py:279:    assert conn.execute("SELECT COUNT(*) FROM postfinance_account_roles").fetchone()[0] == 3
./tests/test_postfinance_sprint13.py:280:    roles = dict(conn.execute("SELECT role,account_id FROM postfinance_account_roles"))
grep: src/jarvis_finance/storage/__pycache__/postfinance_schema.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_aggregation.cpython-311.pyc: binary file matches
grep: src/jarvis_finance/services/__pycache__/portfolio_aggregation.cpython-312.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/storage/postfinance_schema.py:75:        CREATE TABLE IF NOT EXISTS postfinance_snapshot_positions (
src/jarvis_finance/storage/postfinance_schema.py:95:        CREATE TABLE IF NOT EXISTS postfinance_snapshot_cash (
src/jarvis_finance/storage/postfinance_schema.py:176:        CREATE TRIGGER IF NOT EXISTS postfinance_snapshot_positions_immutable BEFORE UPDATE ON postfinance_snapshot_positions
src/jarvis_finance/storage/postfinance_schema.py:178:        CREATE TRIGGER IF NOT EXISTS postfinance_snapshot_positions_no_delete BEFORE DELETE ON postfinance_snapshot_positions
src/jarvis_finance/storage/postfinance_schema.py:180:        CREATE TRIGGER IF NOT EXISTS postfinance_snapshot_cash_immutable BEFORE UPDATE ON postfinance_snapshot_cash
src/jarvis_finance/storage/postfinance_schema.py:182:        CREATE TRIGGER IF NOT EXISTS postfinance_snapshot_cash_no_delete BEFORE DELETE ON postfinance_snapshot_cash
src/jarvis_finance/services/portfolio_aggregation.py:123:           FROM postfinance_snapshot_cash WHERE snapshot_id=? ORDER BY currency""",
src/jarvis_finance/services/portfolio_aggregation.py:176:           FROM postfinance_snapshot_positions
src/jarvis_finance/services/postfinance_service.py:745:                """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(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
src/jarvis_finance/services/postfinance_service.py:797:                "INSERT INTO postfinance_snapshot_cash(snapshot_cash_id,snapshot_id,currency,amount_original,fx_rate_to_chf,value_chf,created_at) VALUES(?,?,?,?,?,?,?)",
src/jarvis_finance/services/postfinance_service.py:908:               FROM postfinance_snapshot_positions p
tests/test_postfinance_sprint13.py:278:    assert conn.execute("SELECT COUNT(*) FROM postfinance_snapshot_positions").fetchone()[0] == 22
tests/test_postfinance_sprint13.py:325:        "SELECT provider_cost_total_original,computed_cost_basis_original,computed_cost_basis_status FROM postfinance_snapshot_positions WHERE computed_cost_basis_original IS NOT NULL"
tests/test_postfinance_sprint13.py:371:        "SELECT computed_cost_basis_original,computed_cost_basis_status FROM postfinance_snapshot_positions WHERE computed_cost_basis_original IS NOT NULL"
tests/test_postfinance_sprint13.py:456:        "postfinance_snapshot_positions": "created_at=created_at",
tests/test_postfinance_sprint13.py:457:        "postfinance_snapshot_cash": "created_at=created_at",
tests/test_postfinance_sprint13.py:680:        """INSERT INTO postfinance_snapshot_positions(
tests/test_postfinance_sprint13.py:690:           FROM postfinance_snapshot_positions WHERE snapshot_id<> 'future-snapshot'"""
tests/test_postfinance_sprint13.py:693:        """INSERT INTO postfinance_snapshot_cash(
tests/test_postfinance_sprint13.py:697:           FROM postfinance_snapshot_cash WHERE snapshot_id<> 'future-snapshot'"""


sed -n '1,130p' src/jarvis_finance/storage/postfinance_schema.py && sed -n '500,570p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: c40e6c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2553
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')),
            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);
        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)
    zip_raw, overview_raw = _source_bytes(request)
    bundle = parse_postfinance_bundle(zip_raw, overview_raw)  # mandatory byte reparse on confirm
    if (
        bundle.bundle_hash != preview["bundle_sha256"]
        or _revision(conn, accounts) != preview["db_revision"]
    ):
        raise ValueError("PostFinance source bytes or database revision changed after preview")
    position_map = _match_instruments(conn, bundle, accounts["etrading_depot"])
    event_instruments = {
        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,
                preview["db_revision"],
                zip_ref,
                bundle.snapshot.valuation_at,
                audit_id,
                now,
            ),
        )
        for document in bundle.documents:
            reference = f"postfinance/archive/{document.document_hash}.pdf"
            ref_hash = _hash(document.semantic_reference)


grep -n "def _latest_analysis" -A80 src/jarvis_finance/services/equity_service.py && sed -n '1,140p' src/jarvis_finance/services/equity_service.py


Output:
Chunk ID: 043b44
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2658
Output:
29:def _latest_analysis(conn: Connection) -> tuple[dict[str, object] | None, dict[tuple[str, str], dict[str, object]], dict[str, str]]:
30-    row = conn.execute(
31-        """SELECT pas.*,mdr.completed_at,mdr.missing_instruments_json
32-             FROM portfolio_analysis_snapshots pas
33-             JOIN market_data_runs mdr ON mdr.run_id=pas.run_id
34-            ORDER BY pas.as_of DESC,pas.created_at DESC LIMIT 1"""
35-    ).fetchone()
36-    if not row:
37-        return None, {}, {}
38-    try:
39-        payload = json.loads(row["summary_json"] or "{}")
40-    except json.JSONDecodeError:
41-        payload = {}
42-    values = {
43-        (str(item.get("account_id") or ""), str(item.get("instrument_id") or "")): item
44-        for item in payload.get("positions", [])
45-        if isinstance(item, dict)
46-    }
47-    try:
48-        missing_rows = json.loads(row["missing_instruments_json"] or "[]")
49-    except json.JSONDecodeError:
50-        missing_rows = []
51-    missing = {
52-        str(item.get("instrument_id") or ""): str(item.get("reason_code") or "price_missing")
53-        for item in missing_rows
54-        if isinstance(item, dict)
55-    }
56-    return dict(row), values, missing
57-
58-
59-def _status_reason(code: str) -> str:
60-    labels = {
61-        "fmp_endpoint_restricted": "Der primäre Provider beschränkt diesen historischen Kurs im aktuellen Tarif.",
62-        "plan_restricted": "Der Provider beschränkt diesen historischen Kurs im aktuellen Tarif.",
63-        "fmp_rate_limited": "Das Provider-Limit wurde erreicht. Der Lauf kann kontrolliert fortgesetzt werden.",
64-        "rate_limited": "Das Provider-Limit wurde erreicht. Der Lauf kann kontrolliert fortgesetzt werden.",
65-        "currency_mismatch": "Die Kurswährung stimmt nicht mit der bestätigten Instrumentwährung überein.",
66-        "exchange_mismatch": "Der Handelsplatz des Provider-Ergebnisses ist nicht bestätigt.",
67-        "future_price_rejected": "Der gelieferte Kurs liegt nach dem zulässigen Börsenstichtag.",
68-        "stale_price": "Der letzte bestätigte Kurs ist für den Börsenstichtag zu alt und wird nicht bewertet.",
69-        "mapping_required": "Die Provider-Zuordnung ist noch nicht eindeutig bestätigt.",
70-        "fx_rate_missing": "Für die CHF-Bewertung fehlt ein bestätigter FX-Kurs.",
71-    }
72-    return labels.get(code, "Für den Börsenstichtag konnte noch kein bestätigter Kurs geladen werden.")
73-
74-
75-def _position_status(row: Mapping[str, object]) -> str:
76-    """Compatibility status when no audited market-analysis snapshot exists yet."""
77-
78-    if "quantity" in row and Decimal(str(row.get("quantity") or "0")) <= 0:
79-        return "Einstand unvollständig"
80-    market_value = row.get("market_value_chf")
81-    warnings = str(row.get("quality_warnings") or "")
82-    if market_value not in {None, ""}:
83-        if "missing_cost_basis" in warnings or "missing_fx" in warnings:
84-            return "Einstand unvollständig"
85-        return "Bewertet"
86-    if str(row.get("price_status") or "") != "ok":
87-        return "Kurs fehlt"
88-    if str(row.get("fx_status") or "") == "missing_fx":
89-        return "FX fehlt für Bewertung"
90-    return "Bewertung unvollständig"
91-
92-
93-def _mapping_details(conn: Connection, instrument_id: str) -> dict[str, str | None]:
94-    row = conn.execute(
95-        """SELECT provider,provider_symbol,provider_market,upper(COALESCE(trading_currency,currency,'')) currency
96-             FROM instrument_price_mappings
97-            WHERE instrument_id=? AND mapping_status='mapped'
98-            ORDER BY updated_at DESC,mapping_id LIMIT 1""",
99-        (instrument_id,),
100-    ).fetchone()
101-    return dict(row) if row else {"provider": None, "provider_symbol": None, "provider_market": None, "currency": None}
102-
103-
104-def list_equity_positions(conn: Connection) -> list[EquityPosition]:
105-    source_rows = [
106-        row for row in dashboard_data.get_positions(conn)
107-        if row.get("asset_class", "").lower() in {"stock", "equity", "etf"}
108-        and row.get("instrument_status", "").lower() != "inactive"
109-    ]
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")
    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",
        }
        candidate_is_newer = bool(
            analysis
            and candidate
            and str(analysis.get("as_of") or "") > str(row.get("valuation_as_of") or row.get("price_date") or "")
            and candidate.get("quality_status") == "fresh"
        )
        raw = (
            candidate.get("value_chf")
            if candidate_is_newer and candidate
            else row.get("market_value_chf") if analysis is None or row_is_audited else None
        )
        effective_values[key] = Decimal(str(raw)) if raw not in {None, ""} else None
    complete = bool(source_rows) and all(value is not None for value in effective_values.values())
    total = sum((value or Decimal("0") for value in effective_values.values()), Decimal("0"))
    positions: list[EquityPosition] = []
    for row in source_rows:
        account_id = str(row.get("account_id") or "")
        instrument_id = str(row.get("instrument_id") or "")
        snapshot_value = values.get((account_id, instrument_id))
        value = (
            snapshot_value
            if analysis


sed -n '1320,1475p' src/jarvis_finance/services/portfolio_data.py


Output:
Chunk ID: 2733c4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2625
Output:
            elif record.record_kind == "valuation" and record.disposition in {"new", "versioned"}:
                target_id = _insert_valuation(conn, record, preview["source_key"], confirmed_at)
                writable += 1
            item_rows.append((record, target_id))
        audit_id = record_audit_event(
            conn, source="portfolio_ingestion_api", action="portfolio_ingestion_confirmed",
            entity_type="portfolio_ingestion_batch", entity_id=batch_id,
            new_values={
                "source_key": preview["source_key"], "written_records": writable,
                "version": INGESTION_VERSION,
                "reason_codes": preview["quality_impact"]["reason_codes"],
            },
            confirmed=True, created_by="user",
        )
        conn.execute(
            """INSERT INTO portfolio_ingestion_batches(
                 batch_id, source_key, scope_kind, scope_id, period_from, period_to, data_cutoff,
                 source_revision, input_fingerprint, preview_id, confirmation_id, payload_hash,
                 status, counts_json, audit_id, confirmed_at, confirmed_by
               ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?, 'confirmed', ?,?,?, 'user')""",
            (batch_id, preview["source_key"], preview["scope_kind"], preview["account_id"],
             preview["period_from"], preview["period_to"], preview["data_cutoff"], preview["source_revision"],
             preview["input_fingerprint"], preview["preview_id"], confirmation_id, payload_hash,
             json.dumps(preview["counts"], sort_keys=True), audit_id, confirmed_at),
        )
        for record, target_id in item_rows:
            conn.execute(
                """INSERT INTO portfolio_ingestion_items(
                     ingestion_item_id, batch_id, source_record_fingerprint, source_record_ref,
                     record_kind, disposition, target_type, target_id, lineage_hash, summary_json, created_at
                   ) VALUES(?,?,?,?,?,?,?,?,?,?,?)""",
                ("ingestion-item-" + uuid.uuid4().hex, batch_id, record.source_record_fingerprint,
                 record.source_record_ref, record.record_kind, record.disposition, record.target_type,
                 target_id, record.lineage_hash, json.dumps(record.summary, sort_keys=True), confirmed_at),
            )
        conn.commit()
        return {"batch_id": batch_id, "audit_id": audit_id, "idempotent": False, "written_records": writable, "payload_hash": payload_hash}
    except IntegrityError as exc:
        conn.rollback()
        existing = conn.execute("SELECT batch_id, payload_hash, audit_id FROM portfolio_ingestion_batches WHERE confirmation_id=?", (confirmation_id,)).fetchone()
        if existing and existing["payload_hash"] == expected_existing_hash and str(request.get("payload_hash") or "") == expected_existing_hash:
            return {"batch_id": existing["batch_id"], "audit_id": existing["audit_id"], "idempotent": True}
        if existing:
            raise ValueError("Bestätigungskennung wurde mit verändertem Inhalt wiederverwendet") from exc
        raise ValueError("Ingestion konnte nicht atomar bestätigt werden") from exc
    except Exception:
        conn.rollback()
        raise

def list_data_sources(conn: Connection) -> dict[str, Any]:
    definitions = [
        ("postfinance_etrading", "PostFinance E-Trading Portfolio", "portfolio_ingestion_batches", True, True, True,
         ["Positionsbestand", "Cash", "FX", "Performance-Baseline"]),
        ("canonical_transactions", "Kanonisches Transaktionsledger", "transactions", True, True, False,
         ["Kauf", "Verkauf", "Dividende", "Gebühr", "Steuer", "Transfer"]),
        ("legacy_account_values", "Bestehende Account-Totalwerte", "account_value_snapshots", True, False, True, ["Account-Totalwert"]),
        ("cash_account_snapshots", "Bestehende Cash-Snapshots", "cash_account_snapshots", True, False, True, ["Cash-Totalwert"]),
        ("reported_positions", "Gespeicherte Positionssnapshots", "positions_snapshot", False, False, False, ["Menge", "Positionswert"]),
        ("market_prices", "Gespeicherte Marktpreise", "market_prices", False, False, False, ["Preis"]),
        ("fx_rates", "Gespeicherte FX-Kurse", "fx_rates", False, False, False, ["FX"]),
    ]
    rows: list[dict[str, Any]] = []
    for key, label, table, ingestible, activities, valuations, capabilities in definitions:
        if key == "postfinance_etrading":
            count = int(conn.execute(
                "SELECT COUNT(*) AS count FROM portfolio_ingestion_batches WHERE source_key=?", (key,)
            ).fetchone()["count"])
        else:
            count = int(conn.execute(f"SELECT COUNT(*) AS count FROM {table}").fetchone()["count"])
        batch = conn.execute("SELECT confirmed_at, status FROM portfolio_ingestion_batches WHERE source_key=? ORDER BY confirmed_at DESC LIMIT 1", (key,)).fetchone()
        attempt = None
        if key == "canonical_transactions":
            attempt = conn.execute("SELECT finished_at, status FROM import_sessions WHERE import_type IN ('transactions','crypto_transactions') ORDER BY COALESCE(finished_at,started_at) DESC LIMIT 1").fetchone()
        elif key == "cash_account_snapshots":
            attempt = conn.execute("SELECT finished_at, status FROM import_sessions WHERE import_type='cash_balances' ORDER BY COALESCE(finished_at,started_at) DESC LIMIT 1").fetchone()
        rows.append({
            "source_key": key, "label": label, "available": count > 0, "configured": True,
            "ingestion_supported": ingestible, "activity_support": activities, "valuation_support": valuations,
            "capabilities": capabilities, "record_count": count,
            "last_successful_confirmed_at": batch["confirmed_at"] if batch else None,
            "last_attempt_at": (attempt["finished_at"] if attempt else None) or (batch["confirmed_at"] if batch else None),
            "last_attempt_status": (attempt["status"] if attempt else None) or (batch["status"] if batch else None),
            "known_gaps": ["Keine neue externe Provider-Abfrage", "Keine automatische Ingestion beim Start"],
        })
    fingerprint = _hash([[row["source_key"], row["record_count"], row["last_successful_confirmed_at"]] for row in rows])
    return {"sources": rows, "data_cutoff": _now().isoformat(), "input_fingerprint": fingerprint}

def ingestion_history(conn: Connection, *, limit: int = 50, offset: int = 0) -> dict[str, Any]:
    if limit < 1 or limit > 100 or offset < 0:
        raise ValueError("Pagination ist ungültig")
    total = int(conn.execute("SELECT COUNT(*) AS count FROM portfolio_ingestion_batches").fetchone()["count"])
    rows = conn.execute(
        """SELECT batch_id, source_key, scope_kind, scope_id, period_from, period_to, data_cutoff,
                  input_fingerprint, status, counts_json, confirmed_at
           FROM portfolio_ingestion_batches ORDER BY confirmed_at DESC LIMIT ? OFFSET ?""", (limit, offset)
    ).fetchall()
    return {
        "items": [{key: value for key, value in {
                    **dict(row), "batch_id": _safe_ref("batch", str(row["batch_id"])),
                    "scope_id": _safe_ref("account", str(row["scope_id"])) if row["scope_id"] else None,
                    "counts": json.loads(row["counts_json"]),
                  }.items() if key != "counts_json"} for row in rows],
        "limit": limit, "offset": offset, "total": total,
    }

def _status(diff: Decimal, base: Decimal | None, absolute: Decimal, relative: Decimal) -> str:
    if diff == 0:
        return "matched"
    if abs(diff) <= absolute:
        return "within_tolerance"
    if base is not None and base != 0 and abs(diff / base) <= relative:
        return "within_tolerance"
    return "mismatch"

def _latest_fx(conn: Connection, currency: str, as_of: str, cutoff: str) -> tuple[Decimal | None, str | None, str | None]:
    if currency == "CHF":
        return Decimal("1"), as_of, "identity"
    row = conn.execute(
        """SELECT rate, rate_date, provider FROM fx_rates
           WHERE base_currency=? AND quote_currency='CHF' AND rate_date<=?
             AND datetime(created_at)<=datetime(?)
             AND rate IS NOT NULL AND quality_status IN ('ok','fresh','complete')
           ORDER BY rate_date DESC, created_at DESC, fx_rate_id DESC LIMIT 1""", (currency, as_of, cutoff)
    ).fetchone()
    if not row:
        return None, None, None
    return _stored_decimal(row["rate"], "FX", positive=True), str(row["rate_date"]), str(row["provider"])

def build_portfolio_reconciliation(
    conn: Connection, *, as_of: str, data_cutoff: str | None = None, account_id: str | None = None,
    base_currency: str = "CHF", absolute_tolerance: str = "0.01", relative_tolerance: str = "0.001",
    limit: int = 200, offset: int = 0,
) -> dict[str, Any]:
    _date(as_of, "Stichtag")
    cutoff = _instant(data_cutoff or _now().isoformat(), "Data-Cutoff").isoformat()
    if base_currency.upper() != "CHF":
        raise ValueError("Reconciliation v1 unterstützt als Basiswährung ausschliesslich CHF")
    absolute = _decimal(absolute_tolerance, "Absolute Toleranz", non_negative=True)
    relative = _decimal(relative_tolerance, "Relative Toleranz", non_negative=True)
    if limit < 1 or limit > 500 or offset < 0:
        raise ValueError("Pagination ist ungültig")
    accounts = _validate_scope(conn, "account" if account_id else "portfolio", account_id)
    account_map = {row["account_id"]: row for row in accounts}
    if not account_map:
        empty_coverage = {key: {"covered": 0, "total": 0, "ratio": None} for key in ("accounts", "instruments", "activities", "opening_valuations", "closing_valuations", "prices", "fx", "cost_basis", "reconciliation")}
        return {"as_of": as_of, "data_cutoff": cutoff, "base_currency": "CHF", "status": "unavailable", "reason_codes": ["missing_account_valuation"], "tolerance": {"version": TOLERANCE_VERSION, "absolute": str(absolute), "relative": str(relative)}, "coverage": empty_coverage, "differences": [], "account_totals": [], "input_fingerprint": _hash([as_of, cutoff, []]), "sources": [], "limit": limit, "offset": offset, "total": 0}
    placeholders = ",".join("?" for _ in account_map)
    transaction_rows = conn.execute(
        f"""SELECT * FROM transactions WHERE account_id IN ({placeholders}) AND trade_date<=?
            AND datetime(created_at)<=datetime(?)
            AND COALESCE(is_voided,0)=0 AND COALESCE(is_confirmed,1)=1


grep -n "def _validate_scope" -A50 src/jarvis_finance/services/portfolio_data.py


Output:
Chunk ID: 2b83fa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 676
Output:
131:def _validate_scope(conn: Connection, scope_kind: str, account_id: str | None) -> list[dict[str, str]]:
132-    if scope_kind not in {"portfolio", "account"}:
133-        raise ValueError("Scope muss portfolio oder account sein")
134-    if scope_kind == "account" and not account_id:
135-        raise ValueError("Für den Account-Scope ist ein Konto erforderlich")
136-    params: tuple[object, ...] = ()
137-    where = "WHERE is_active=1 AND performance_included=1"
138-    if account_id:
139-        where += " AND account_id=?"
140-        params = (account_id,)
141-    rows = conn.execute(f"SELECT account_id, account_name, account_type, currency FROM accounts {where} ORDER BY account_id", params).fetchall()
142-    if scope_kind == "account" and not rows:
143-        raise ValueError("Portfolio-Konto wurde nicht gefunden")
144-    return [dict(row) for row in rows]
145-
146-
147-def _validate_request(conn: Connection, request: dict[str, Any]) -> tuple[list[dict[str, str]], str, str, str]:
148-    source_key = str(request.get("source_key") or "")
149-    if source_key not in SOURCE_KEYS:
150-        raise ValueError("Datenquelle ist nicht vorhanden oder nicht für Ingestion freigegeben")
151-    period_from = str(request.get("period_from") or "")
152-    period_to = str(request.get("period_to") or "")
153-    start, end = _date(period_from, "Von"), _date(period_to, "Bis")
154-    if start > end:
155-        raise ValueError("Zeitraum: 'von' darf nicht nach 'bis' liegen")
156-    cutoff = str(request.get("data_cutoff") or _now().isoformat())
157-    cutoff = _instant(cutoff, "Data-Cutoff").isoformat()
158-    scope_kind = str(request.get("scope_kind") or "portfolio")
159-    account_id = str(request.get("account_id") or "") or None
160-    accounts = _validate_scope(conn, scope_kind, account_id)
161-    return accounts, period_from, period_to, cutoff
162-
163-
164-def _record_ref(source_key: str, raw_id: str) -> str:
165-    return _safe_ref("record", f"{source_key}:{raw_id}")
166-
167-
168-def _existing_lineage(conn: Connection, lineage_hash: str) -> tuple[str, str] | None:
169-    row = conn.execute(
170-        """SELECT target_type, target_id FROM portfolio_ingestion_items
171-           WHERE lineage_hash=? AND disposition IN ('new','versioned','unchanged') AND target_id IS NOT NULL
172-           ORDER BY created_at DESC LIMIT 1""",
173-        (lineage_hash,),
174-    ).fetchone()
175-    return (str(row["target_type"]), str(row["target_id"])) if row else None
176-
177-
178-def _valuation_snapshot_id(source_key: str, lineage_hash: str, version: int) -> str:
179-    return "valuation-" + _hash([source_key, lineage_hash, version])[:24]
180-
181-


grep -n "def _resolve_accounts\|etrading_cash\|etrading_depot" -n src/jarvis_finance/services/postfinance_service.py | head -60 && sed -n '400,500p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 72d85e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1163
Output:
69:def _resolve_accounts(conn: Connection, request: dict[str, Any] | None = None) -> dict[str, str]:
74:        if set(explicit) != {"efinance", "etrading_depot", "etrading_cash"}:
123:            "etrading_depot": str(depot[0]["account_id"]),
124:            "etrading_cash": str(trading_cash[0]["account_id"]),
146:        (accounts["etrading_depot"],),
314:    mapping = _match_instruments(conn, bundle, accounts["etrading_depot"])
328:        (accounts["etrading_depot"], bundle.snapshot.valuation_at[:10]),
333:        (accounts["etrading_cash"], bundle.snapshot.valuation_at[:10]),
518:    position_map = _match_instruments(conn, bundle, accounts["etrading_depot"])
606:                accounts["etrading_depot"],
777:                    accounts["etrading_depot"],
792:                    accounts["etrading_depot"],
812:                    accounts["etrading_cash"],
828:                accounts["etrading_depot"],
        "parser_version": PARSER_VERSION,
        "document_count": len(bundle.documents) + 1,
        "event_count": len(bundle.events),
        "snapshot_at": bundle.snapshot.valuation_at,
    }
    conn.execute(
        """INSERT INTO audit_log(audit_id,timestamp,source,action,entity_type,entity_id,old_values_json,new_values_json,user_text_note,confirmed,confirmation_timestamp,auto_parsed,parse_confidence,created_by,quality_status,created_at)
           VALUES(?,?,'postfinance_sprint13','postfinance_import_confirm','postfinance_import_batch',?,NULL,?,'Verified official source bundle',1,?,0,NULL,'user','ok',?)""",
        (audit_id, now, batch_id, json.dumps(details, sort_keys=True), now, now),
    )
    return audit_id

def _canonical_transaction(
    conn: Connection,
    event_id: str,
    event: PFEvent,
    account_id: str,
    instrument_id: str | None,
    now: str,
) -> None:
    if event.event_type in {"split", "corporate_action"}:
        return
    tx_type = {
        "buy": "buy",
        "sell": "sell",
        "dividend": "dividend",
        "interest": "interest",
        "fee": "fee",
        "internal_transfer": "transfer",
        "fx": "fx",
    }[event.event_type]
    activity = (
        "internal_transfer"
        if event.event_type == "internal_transfer"
        else "external_cashflow"
        if event.event_type in {"dividend", "interest", "fee"}
        else "trade"
    )
    columns = (
        "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(


sed -n '50,150p' src/jarvis_finance/services/postfinance_service.py && sed -n '300,345p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 571cff
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1585
Output:

def _money(value: Decimal) -> str:
    return format(value.quantize(Decimal("0.01")), "f")

def _decode(value: str, label: str) -> bytes:
    try:
        return base64.b64decode(value, validate=True)
    except (binascii.Error, ValueError) as exc:
        raise ValueError(f"PostFinance {label} is not valid base64") from exc

def _source_bytes(request: dict[str, Any]) -> tuple[bytes, bytes]:
    return (
        _decode(str(request.get("zip_content_base64") or ""), "ZIP"),
        _decode(str(request.get("overview_content_base64") or ""), "overview PDF"),
    )

def _resolve_accounts(conn: Connection, request: dict[str, Any] | None = None) -> dict[str, str]:
    request = request or {}
    explicit = request.get("account_roles") or {}
    prospective_efinance = False
    if explicit:
        if set(explicit) != {"efinance", "etrading_depot", "etrading_cash"}:
            raise ValueError("All three PostFinance account roles are required")
        result = {key: str(value) for key, value in explicit.items()}
    else:
        rows = conn.execute(
            """SELECT a.account_id,a.account_name,a.account_type,a.platform_id
               FROM accounts a JOIN platforms p ON p.platform_id=a.platform_id
               WHERE a.is_active=1 AND replace(replace(lower(p.name),' ',''),'-','') LIKE '%postfinance%'
               ORDER BY a.account_id"""
        ).fetchall()
        depot = [
            row
            for row in rows
            if "trading" in str(row["account_name"]).lower()
            and str(row["account_type"]).lower() in {"brokerage", "depot"}
            or str(row["account_type"]).lower() in {"brokerage", "depot"}
        ]
        cash = [
            row
            for row in rows
            if row not in depot
            and (
                "cash" in str(row["account_name"]).lower()
                or "finance" in str(row["account_name"]).lower()
                or str(row["account_type"]).lower() in {"cash", "bank", "checking"}
            )
        ]
        efinance = [
            row
            for row in cash
            if "efinance"
            in str(row["account_name"])
            .lower()
            .replace("postfinance", "")
            .replace("-", "")
            .replace(" ", "")
        ]
        trading_cash = [row for row in cash if row not in efinance]
        if len(depot) != 1 or len(trading_cash) != 1 or len(efinance) > 1:
            raise ValueError(
                "PostFinance E-Finance, E-Trading depot and E-Trading cash cannot be resolved unambiguously"
            )
        if efinance:
            efinance_id = str(efinance[0]["account_id"])
        else:
            efinance_id = f"account_pf_efinance_{_hash(depot[0]['platform_id'])[:16]}"
            prospective_efinance = True
        result = {
            "efinance": efinance_id,
            "etrading_depot": str(depot[0]["account_id"]),
            "etrading_cash": str(trading_cash[0]["account_id"]),
        }
    if len(set(result.values())) != 3:
        raise ValueError("PostFinance account roles must map to three distinct canonical accounts")
    for role, account_id in result.items():
        row = conn.execute(
            "SELECT is_active FROM accounts WHERE account_id=?", (account_id,)
        ).fetchone()
        if not row and role == "efinance" and prospective_efinance:
            continue
        if not row or not row["is_active"]:
            raise ValueError(f"PostFinance account role {role} is unavailable")
    return result

def _ensure_efinance_account(conn: Connection, accounts: dict[str, str], now: str) -> None:
    if conn.execute(
        "SELECT 1 FROM accounts WHERE account_id=?", (accounts["efinance"],)
    ).fetchone():
        return
    depot = conn.execute(
        "SELECT platform_id FROM accounts WHERE account_id=? AND is_active=1",
        (accounts["etrading_depot"],),
    ).fetchone()
    if not depot:
        raise ValueError("PostFinance depot account is unavailable")
    conn.execute(
        "reconciliation_status": "matched" if difference == 0 else "within_tolerance",
        "open_orders": snapshot.open_orders,
        "account_roles_resolved": sorted(accounts),
        "mapped_position_count": len(mapping),
        "warnings": [
            "Calculated cost basis remains partial where no documented acquisition exists in this source bundle"
        ],
    }

def preview_postfinance_import(conn: Connection, request: dict[str, Any]) -> dict[str, Any]:
    accounts = _resolve_accounts(conn, request)
    zip_raw, overview_raw = _source_bytes(request)
    bundle = parse_postfinance_bundle(zip_raw, overview_raw)
    mapping = _match_instruments(conn, bundle, accounts["etrading_depot"])
    payload = _preview_payload(bundle, accounts, mapping)
    revision = _revision(conn, accounts)
    fingerprint = _hash(payload, revision)
    duplicate = conn.execute(
        "SELECT batch_id FROM postfinance_import_batches WHERE bundle_sha256=?",
        (bundle.bundle_hash,),
    ).fetchone()
    conflict = conn.execute(
        "SELECT batch_id FROM postfinance_import_batches WHERE substr(snapshot_at,1,10)=? AND bundle_sha256<>?",
        (bundle.snapshot.valuation_at[:10], bundle.bundle_hash),
    ).fetchone()
    position_collision = conn.execute(
        "SELECT COUNT(*) FROM positions_snapshot WHERE account_id=? AND snapshot_date=?",
        (accounts["etrading_depot"], bundle.snapshot.valuation_at[:10]),
    ).fetchone()[0]
    cash_collision = conn.execute(
        """SELECT COUNT(*) FROM cash_balances
           WHERE account_id=? AND balance_date=? AND source_type='postfinance_official_import'""",
        (accounts["etrading_cash"], bundle.snapshot.valuation_at[:10]),
    ).fetchone()[0]
    if not duplicate and (position_collision or cash_collision):
        conflict = conflict or {"batch_id": "canonical_projection_date_conflict"}
    semantic_conflicts = conn.execute(
        """SELECT COUNT(*) FROM postfinance_documents d
           WHERE EXISTS (SELECT 1 FROM json_each(?) j WHERE j.value=d.semantic_identity)
             AND d.document_hash NOT IN (SELECT value FROM json_each(?))""",
        (
            json.dumps([d.semantic_identity for d in bundle.documents]),
            json.dumps([d.document_hash for d in bundle.documents]),
        ),
    ).fetchone()[0]


Output:
Chunk ID: cbfb64
Wall time: 2.1917 seconds
Process exited with code 0
Original token count: 25
Output:
........                                                                 [100%]
8 passed in 2.01s


nl -ba src/jarvis_finance/services/portfolio_aggregation.py | sed -n '90,260p'; nl -ba src/jarvis_finance/services/postfinance_service.py | sed -n '880,925p'; nl -ba src/jarvis_finance/services/equity_service.py | sed -n '120,190p'


Output:
Chunk ID: bf9f72
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3653
Output:
    90	        raise ValueError("Official portfolio component allocation does not reconcile")
    91	    return allocated
    92
    93
    94	def latest_official_postfinance_cash(
    95	    conn: Connection,
    96	    *,
    97	    as_of: str | None = None,
    98	    data_cutoff: str | None = None,
    99	) -> list[OfficialCashComponent]:
   100	    roles = postfinance_account_roles(conn)
   101	    account_id = roles.get("etrading_cash")
   102	    if not account_id:
   103	        return []
   104	    conditions: list[str] = []
   105	    params: list[str] = []
   106	    if as_of:
   107	        conditions.append("date(snapshot_at)<=date(?)")
   108	        params.append(as_of)
   109	    if data_cutoff:
   110	        conditions.append("datetime(created_at)<=datetime(?)")
   111	        params.append(data_cutoff)
   112	    where = f"WHERE {' AND '.join(conditions)}" if conditions else ""
   113	    snapshot = conn.execute(
   114	        f"""SELECT snapshot_id,snapshot_at,cash_chf
   115	            FROM postfinance_snapshots {where}
   116	            ORDER BY snapshot_at DESC,datetime(created_at) DESC LIMIT 1""",
   117	        params,
   118	    ).fetchone()
   119	    if not snapshot:
   120	        return []
   121	    rows = conn.execute(
   122	        """SELECT currency,amount_original,fx_rate_to_chf
   123	           FROM postfinance_snapshot_cash WHERE snapshot_id=? ORDER BY currency""",
   124	        (snapshot["snapshot_id"],),
   125	    ).fetchall()
   126	    raw_values = [
   127	        _decimal(row["amount_original"]) * _decimal(row["fx_rate_to_chf"])
   128	        for row in rows
   129	    ]
   130	    target = _money(_decimal(snapshot["cash_chf"]))
   131	    allocated = _allocate_pro_rata(raw_values, target)
   132	    valuation_at = str(snapshot["snapshot_at"])
   133	    return [
   134	        OfficialCashComponent(
   135	            account_id=account_id,
   136	            currency=str(row["currency"]),
   137	            amount_original=_decimal(row["amount_original"]),
   138	            source_fx_rate_to_chf=_decimal(row["fx_rate_to_chf"]),
   139	            amount_chf=value,
   140	            snapshot_date=valuation_at[:10],
   141	            valuation_at=valuation_at,
   142	        )
   143	        for row, value in zip(rows, allocated, strict=True)
   144	    ]
   145
   146
   147	def latest_official_postfinance_positions(
   148	    conn: Connection,
   149	    *,
   150	    as_of: str | None = None,
   151	    data_cutoff: str | None = None,
   152	) -> dict[tuple[str, str], OfficialPositionOverride]:
   153	    roles = postfinance_account_roles(conn)
   154	    account_id = roles.get("etrading_depot")
   155	    if not account_id:
   156	        return {}
   157	    conditions: list[str] = []
   158	    params: list[str] = []
   159	    if as_of:
   160	        conditions.append("date(snapshot_at)<=date(?)")
   161	        params.append(as_of)
   162	    if data_cutoff:
   163	        conditions.append("datetime(created_at)<=datetime(?)")
   164	        params.append(data_cutoff)
   165	    where = f"WHERE {' AND '.join(conditions)}" if conditions else ""
   166	    snapshot = conn.execute(
   167	        f"""SELECT snapshot_id,snapshot_at,stocks_chf,etfs_chf
   168	            FROM postfinance_snapshots {where}
   169	            ORDER BY snapshot_at DESC,datetime(created_at) DESC LIMIT 1""",
   170	        params,
   171	    ).fetchone()
   172	    if not snapshot:
   173	        return {}
   174	    rows = conn.execute(
   175	        """SELECT instrument_id,asset_class,quantity,price_original,price_currency,value_chf
   176	           FROM postfinance_snapshot_positions
   177	           WHERE snapshot_id=? ORDER BY asset_class,instrument_id""",
   178	        (snapshot["snapshot_id"],),
   179	    ).fetchall()
   180	    targets = {
   181	        "stock": _money(_decimal(snapshot["stocks_chf"])),
   182	        "etf": _money(_decimal(snapshot["etfs_chf"])),
   183	    }
   184	    allocated_by_instrument: dict[str, Decimal] = {}
   185	    for asset_class, target in targets.items():
   186	        members = [row for row in rows if str(row["asset_class"]).lower() == asset_class]
   187	        allocated = _allocate_pro_rata(
   188	            [_decimal(row["value_chf"]) for row in members], target
   189	        )
   190	        allocated_by_instrument.update(
   191	            {
   192	                str(row["instrument_id"]): value
   193	                for row, value in zip(members, allocated, strict=True)
   194	            }
   195	        )
   196	    valuation_at = str(snapshot["snapshot_at"])
   197	    return {
   198	        (account_id, str(row["instrument_id"])): OfficialPositionOverride(
   199	            account_id=account_id,
   200	            instrument_id=str(row["instrument_id"]),
   201	            asset_class=str(row["asset_class"]).lower(),
   202	            quantity=_decimal(row["quantity"]),
   203	            market_price_original=_decimal(row["price_original"]),
   204	            price_currency=str(row["price_currency"]),
   205	            market_value_chf=allocated_by_instrument[str(row["instrument_id"])],
   206	            snapshot_date=valuation_at[:10],
   207	            valuation_at=valuation_at,
   208	        )
   209	        for row in rows
   210	    }
   211
   212
   213	def post_snapshot_postfinance_quantity_deltas(
   214	    conn: Connection,
   215	    positions: dict[tuple[str, str], OfficialPositionOverride],
   216	    *,
   217	    as_of: str | None = None,
   218	) -> dict[str, Decimal]:
   219	    """Replay confirmed buys/sells after the official snapshot baseline."""
   220
   221	    if not positions:
   222	        return {}
   223	    roles = postfinance_account_roles(conn)
   224	    account_ids = [
   225	        account_id
   226	        for role in ("etrading_depot", "etrading_cash")
   227	        if (account_id := roles.get(role))
   228	    ]
   229	    if not account_ids:
   230	        return {}
   231	    snapshot_date = min(item.snapshot_date for item in positions.values())
   232	    effective_as_of = as_of or "9999-12-31"
   233	    placeholders = ",".join("?" for _ in account_ids)
   234	    rows = conn.execute(
   235	        f"""SELECT instrument_id,lower(transaction_type) transaction_type,quantity
   236	            FROM transactions
   237	            WHERE account_id IN ({placeholders})
   238	              AND instrument_id IS NOT NULL
   239	              AND COALESCE(is_confirmed,0)=1
   240	              AND COALESCE(is_voided,0)=0
   241	              AND lower(transaction_type) IN ('buy','sell','partial_sell','full_sell')
   242	              AND trade_date>? AND trade_date<=?""",
   243	        (*account_ids, snapshot_date, effective_as_of),
   244	    ).fetchall()
   245	    deltas: dict[str, Decimal] = {}
   246	    for row in rows:
   247	        instrument_id = str(row["instrument_id"])
   248	        quantity = abs(_decimal(row["quantity"]))
   249	        if str(row["transaction_type"]) in {"sell", "partial_sell", "full_sell"}:
   250	            quantity = -quantity
   251	        deltas[instrument_id] = deltas.get(instrument_id, Decimal("0")) + quantity
   252	    return deltas
   253
   254
   255	def latest_audited_market_values(
   256	    conn: Connection,
   257	) -> dict[tuple[str, str], AuditedMarketValue]:
   258	    """Return the latest immutable market-analysis values without writing on GET."""
   259
   260	    row = conn.execute(
   880	            "event_counts": {},
   881	            "imports": [],
   882	        }
   883	    official_position_values = {
   884	        override.instrument_id: override.market_value_chf
   885	        for override in latest_official_postfinance_positions(conn).values()
   886	    }
   887	    positions = [
   888	        {
   889	            "row_key": _hash("position", row["instrument_name"], row["quantity"])[:16],
   890	            "instrument_name": row["instrument_name"],
   891	            "ticker": row["ticker"],
   892	            "asset_class": row["asset_class"],
   893	            "quantity": row["quantity"],
   894	            "provider_average_cost_original": row["provider_average_cost_original"],
   895	            "provider_cost_total_original": row["provider_cost_total_original"],
   896	            "price_original": row["price_original"],
   897	            "price_currency": row["price_currency"],
   898	            "value_chf": _money(official_position_values.get(row["instrument_id"], Decimal(str(row["value_chf"])))),
   899	            "weight_pct": row["weight_pct"],
   900	            "computed_cost_basis_original": row["computed_cost_basis_original"],
   901	            "computed_cost_basis_status": row["computed_cost_basis_status"],
   902	        }
   903	        for row in conn.execute(
   904	            """SELECT p.instrument_id,p.asset_class,p.quantity,p.provider_average_cost_original,
   905	                      p.provider_cost_total_original,p.price_original,p.price_currency,p.value_chf,
   906	                      p.weight_pct,p.computed_cost_basis_original,p.computed_cost_basis_status,
   907	                      i.name AS instrument_name,i.ticker
   908	               FROM postfinance_snapshot_positions p
   909	               JOIN instruments i ON i.instrument_id=p.instrument_id
   910	               WHERE p.snapshot_id=? ORDER BY CAST(p.value_chf AS REAL) DESC""",
   911	            (latest["snapshot_id"],),
   912	        ).fetchall()
   913	    ]
   914	    cash = [
   915	        {
   916	            "row_key": _hash("cash", component.currency)[:16],
   917	            "currency": component.currency,
   918	            "amount_original": _text(component.amount_original),
   919	            "fx_rate_to_chf": _text(component.source_fx_rate_to_chf),
   920	            "value_chf": _money(component.amount_chf),
   921	        }
   922	        for component in latest_official_postfinance_cash(conn)
   923	    ]
   924	    events = {
   925	        str(row["event_type"]): int(row["c"])
   120	            analysis
   121	            and candidate
   122	            and str(analysis.get("as_of") or "") > str(row.get("valuation_as_of") or row.get("price_date") or "")
   123	            and candidate.get("quality_status") == "fresh"
   124	        )
   125	        raw = (
   126	            candidate.get("value_chf")
   127	            if candidate_is_newer and candidate
   128	            else row.get("market_value_chf") if analysis is None or row_is_audited else None
   129	        )
   130	        effective_values[key] = Decimal(str(raw)) if raw not in {None, ""} else None
   131	    complete = bool(source_rows) and all(value is not None for value in effective_values.values())
   132	    total = sum((value or Decimal("0") for value in effective_values.values()), Decimal("0"))
   133	    positions: list[EquityPosition] = []
   134	    for row in source_rows:
   135	        account_id = str(row.get("account_id") or "")
   136	        instrument_id = str(row.get("instrument_id") or "")
   137	        snapshot_value = values.get((account_id, instrument_id))
   138	        value = (
   139	            snapshot_value
   140	            if analysis
   141	            and snapshot_value
   142	            and snapshot_value.get("quality_status") == "fresh"
   143	            and str(analysis.get("as_of") or "") > str(row.get("valuation_as_of") or row.get("price_date") or "")
   144	            else None
   145	        )
   146	        row_fallback_allowed = analysis is None or row.get("valuation_source") in {
   147	            "postfinance_official_import",
   148	            "audited_market_run",
   149	        }
   150	        mapping = _mapping_details(conn, instrument_id)
   151	        raw_market_value = (
   152	            value.get("value_chf")
   153	            if value
   154	            else row.get("market_value_chf") if row_fallback_allowed else None
   155	        )
   156	        if Decimal(str(row.get("quantity") or "0")) <= 0:
   157	            raw_market_value = None
   158	        market_value = Decimal(str(raw_market_value)) if raw_market_value not in {None, ""} else None
   159	        share = (market_value / total * Decimal("100")) if complete and market_value is not None and total > 0 else None
   160	        code = "valued" if market_value is not None else ("stale_price" if snapshot_value else missing.get(instrument_id, "price_missing"))
   161	        status = "Bewertet" if market_value is not None else ("Kurs veraltet" if snapshot_value else _position_status(row))
   162	        provenance = value.get("price_input_provenance") if value else None
   163	        provenance_provider = provenance.get("provider") if isinstance(provenance, dict) else None
   164	        positions.append(EquityPosition(
   165	            position_id=f"{account_id}:{instrument_id}",
   166	            instrument_id=instrument_id,
   167	            name=str(row.get("name") or ""),
   168	            ticker=str(row.get("ticker") or ""),
   169	            isin=str(row.get("isin") or ""),
   170	            account=_account_label(row),
   171	            asset_class=_asset_class_label(row.get("asset_class")),
   172	            quantity=optional_decimal_text(row.get("quantity")) or "0",
   173	            currency=str(value.get("currency") if value else mapping.get("currency") or row.get("price_currency") or row.get("currency") or ""),
   174	            price=(
   175	                optional_decimal_text(value.get("close"))
   176	                if value
   177	                else optional_decimal_text(row.get("market_price_original") or row.get("price"))
   178	                if row_fallback_allowed
   179	                else None
   180	            ),
   181	            market_value_chf=optional_decimal_text(market_value, 2) if market_value is not None else None,
   182	            portfolio_share_pct=optional_decimal_text(share, 2) if share is not None else None,
   183	            price_date=(
   184	                str(analysis.get("as_of"))
   185	                if value and analysis
   186	                else str(row.get("valuation_as_of") or row.get("price_date") or "") or None
   187	                if row_fallback_allowed
   188	                else str(analysis.get("as_of")) if analysis else None
   189	            ),
   190	            provider=str((value.get("provider") if value else None) or provenance_provider or row.get("price_provider") or mapping.get("provider") or ""),


sed -n '175,275p' src/jarvis_finance/services/cash_service.py && grep -R "get_cash_position_detail\|position_id" -n src/jarvis_finance | head -80