Output:
Chunk ID: b4f8b7
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2845
Output:
                _money(snapshot.total_value_chf),
                now,
                snapshot.valuation_at,
                snapshot_id,
            ),
        )
        conn.commit()
    except IntegrityError as exc:
        conn.rollback()
        duplicate = conn.execute(
            "SELECT batch_id,audit_id FROM postfinance_import_batches WHERE bundle_sha256=?",
            (bundle.bundle_hash,),
        ).fetchone()
        if duplicate:
            return {
                "status": "confirmed",
                "batch_id": duplicate["batch_id"],
                "audit_id": duplicate["audit_id"],
                "idempotent": True,
            }
        for ref, created in archive_refs:
            if created:
                _remove_archive(ref)
        raise ValueError("PostFinance import conflicted with immutable data") from exc
    except Exception:
        conn.rollback()
        for ref, created in archive_refs:
            if created:
                _remove_archive(ref)
        raise
    return {
        "status": "confirmed",
        "batch_id": batch_id,
        "snapshot_id": snapshot_id,
        "audit_id": audit_id,
        "idempotent": False,
    }

def get_postfinance_summary(conn: Connection) -> dict[str, Any]:
    latest = conn.execute(
        """SELECT snapshot_id,snapshot_at,total_chf,securities_chf,cash_chf,stocks_chf,etfs_chf,
                  position_count,cash_count,open_orders,difference_chf,reconciliation_status,created_at
           FROM postfinance_snapshots ORDER BY snapshot_at DESC,created_at DESC LIMIT 1"""
    ).fetchone()
    if not latest:
        return {
            "latest_snapshot": None,
            "positions": [],
            "cash": [],
            "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],
            "instrument_name": row["instrument_name"],
            "ticker": row["ticker"],
            "asset_class": row["asset_class"],
            "quantity": row["quantity"],
            "provider_average_cost_original": row["provider_average_cost_original"],
            "provider_cost_total_original": row["provider_cost_total_original"],
            "price_original": row["price_original"],
            "price_currency": row["price_currency"],
            "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.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
               FROM postfinance_snapshot_positions p
               JOIN instruments i ON i.instrument_id=p.instrument_id
               WHERE p.snapshot_id=? ORDER BY CAST(p.value_chf AS REAL) DESC""",
            (latest["snapshot_id"],),
        ).fetchall()
    ]
    cash = [
        {
            "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 component in latest_official_postfinance_cash(conn)
    ]
    events = {
        str(row["event_type"]): int(row["c"])
        for row in conn.execute(
            "SELECT event_type,COUNT(*) c FROM postfinance_ledger_events GROUP BY event_type ORDER BY event_type"
        ).fetchall()
    }
    imports = [
        dict(row)
        for row in conn.execute(
            """SELECT b.snapshot_at,b.parser_id,b.parser_version,b.confirmed_at,b.status,
                      s.total_chf,s.securities_chf,s.cash_chf,s.position_count,s.cash_count,
                      s.difference_chf,s.reconciliation_status,
                      (SELECT COUNT(*) FROM postfinance_batch_documents d WHERE d.batch_id=b.batch_id) AS document_count
               FROM postfinance_import_batches b JOIN postfinance_snapshots s ON s.batch_id=b.batch_id
               ORDER BY b.snapshot_at DESC,b.confirmed_at DESC"""
        ).fetchall()
    ]
    safe_latest = {key: latest[key] for key in latest.keys() if key != "snapshot_id"}
    return {
        "latest_snapshot": safe_latest,
        "positions": positions,
        "cash": cash,
        "event_counts": events,
        "imports": imports,
    }
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',


sed -n '260,330p' src/jarvis_finance/services/portfolio_analytics.py


Output:
Chunk ID: f9c6d7
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 727
Output:
                "instrument_currency": instrument["instrument_currency"],
            }
            grouped[key] = item
        # The official snapshot is the baseline. Only confirmed trades after that
        # snapshot are replayed, so imported history is not counted twice.
        item["quantity_total"] = override.quantity + post_snapshot_deltas.get(
            override.instrument_id,
            ZERO,
        )
    return [
        ConfirmedPosition(
            account_id=item["account_id"],
            instrument_id=item["instrument_id"],
            isin=item["isin"],
            name=item["name"],
            asset_class=item["asset_class"],
            instrument_currency=item["instrument_currency"],
            quantity=item["quantity_total"],
        )
        for item in grouped.values()
        if item["quantity_total"] > ZERO
    ]

def _mapping(conn: Connection, position: ConfirmedPosition) -> tuple[dict[str, str] | None, str | None]:
    if not position.isin:
        return None, "mapping_required"
    rows = conn.execute(
        """
        SELECT provider, provider_symbol, provider_market,
               upper(COALESCE(trading_currency, currency, '')) AS mapping_currency
        FROM instrument_price_mappings
        WHERE instrument_id=? AND mapping_status='mapped'
          AND provider_symbol IS NOT NULL AND trim(provider_symbol)!=''
        ORDER BY updated_at DESC, mapping_id
        """,
        (position.instrument_id,),
    ).fetchall()
    if len(rows) != 1:
        return None, "mapping_required"
    row = dict(rows[0])
    if row["mapping_currency"] and position.instrument_currency and row["mapping_currency"] != position.instrument_currency:
        return None, "currency_mismatch"
    return {key: str(value or "") for key, value in row.items()}, None

def _active_policy(conn: Connection) -> dict[str, Any] | None:
    row = conn.execute("SELECT * FROM portfolio_policies WHERE is_active=1 ORDER BY version DESC LIMIT 1").fetchone()
    if not row:
        return None
    result = dict(row)
    try:
        result["benchmarks"] = json.loads(result.get("benchmarks_json") or "[]")
    except json.JSONDecodeError:
        result["benchmarks"] = []
    try:
        result["restrictions"] = json.loads(result.get("restrictions_json") or "[]")
    except json.JSONDecodeError:
        result["restrictions"] = []
    return result

def _benchmark_mapping(conn: Connection, policy: dict[str, Any] | None) -> tuple[dict[str, Any] | None, str | None]:
    if not policy or not policy.get("benchmarks"):
        return None, "benchmark_not_configured"
    benchmarks = policy["benchmarks"]
    if len(benchmarks) != 1 or not isinstance(benchmarks[0], dict):
        return None, "benchmark_mapping_required"
    reference = str(benchmarks[0].get("reference") or "").strip()
    if not reference:
        return None, "benchmark_mapping_required"


sed -n '680,735p' src/jarvis_finance/dashboard/data.py && sed -n '1160,1185p' src/jarvis_finance/dashboard/data.py


Output:
Chunk ID: e717bd
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1151
Output:
            continue
        rows.append({
            "name": row.get("name", ""),
            "ticker": row.get("ticker", ""),
            "isin": row.get("isin", ""),
            "depot": row.get("account_name", ""),
            "assettyp": "ETF" if row.get("asset_class", "").lower() == "etf" else "Aktie",
            "menge": row.get("quantity", ""),
            "kurs": row.get("market_price_original") or "Preis noch nicht verfügbar",
            "kurswaehrung": row.get("price_currency", ""),
            "marktwert_chf": chf_text(row.get("market_value_chf")) if row.get("market_value_chf") else "nicht bewertet",
            "einstand_chf": chf_text(row.get("cost_basis_chf")) if row.get("cost_basis_chf") else "unvollständig",
            "p_l_chf": chf_text(row.get("total_return_chf")) if row.get("total_return_chf") else "nicht berechenbar",
            "status": translate_status(row.get("price_status") or row.get("data_quality_status")),
        })
    return rows

def get_portfolio_asset_class_chart(conn: Connection) -> list[dict[str, str]]:
    summary = get_command_center_summary(conn)
    return [
        {"label": "Crypto", "value_chf": summary["crypto_total_chf"]},
        {"label": "Aktien/ETF", "value_chf": summary["equity_etf_total_chf"]},
        {"label": "Cash", "value_chf": summary["cash_total_chf"]},
    ]

def get_platform_value_chart(conn: Connection) -> list[dict[str, str]]:
    totals: dict[str, Decimal] = {}
    for row in get_cash_overview(conn):
        totals[row["platform"]] = totals.get(row["platform"], Decimal("0")) + d(row.get("amount_chf"))
    for row in get_positions(conn):
        totals[row["platform"]] = totals.get(row["platform"], Decimal("0")) + d(row.get("market_value_chf"))
    crypto_total = d(get_crypto_summary_cards(conn)["total_value_chf"])
    if crypto_total:
        totals["Crypto Wallets"] = totals.get("Crypto Wallets", Decimal("0")) + crypto_total
    return [{"label": k, "value_chf": dec_text(v, "0.01")} for k, v in sorted(totals.items(), key=lambda item: item[1], reverse=True)]

def get_ledger_transactions(conn: Connection, limit: int = 200) -> list[dict[str, str]]:
    return rowdicts(conn.execute(
        """
        SELECT t.trade_date, p.name AS platform, a.account_name, t.transaction_type,
               i.name AS instrument, i.ticker, t.quantity, t.gross_amount_original,
               t.net_amount_original, t.currency_original, t.fx_status, t.quality_status,
               t.source_type, t.source_id
        FROM transactions t
        LEFT JOIN accounts a ON a.account_id=t.account_id
        LEFT JOIN platforms p ON p.platform_id=a.platform_id
        LEFT JOIN instruments i ON i.instrument_id=t.instrument_id
        ORDER BY t.trade_date DESC, t.created_at DESC LIMIT ?
        """, (limit,)
    ).fetchall())

def get_watchlist(conn: Connection) -> list[dict[str, str]]:
    ordered = sorted(rows, key=lambda row: d(row.get("value_chf")), reverse=True)
    if len(ordered) <= limit:
        return ordered
    head = ordered[:limit]
    other = sum((d(row.get("value_chf")) for row in ordered[limit:]), Decimal("0"))
    if other > 0:
        head.append({"label": "Andere", "value_chf": dec_text(other, "0.01")})
    return head

def get_command_center_summary(conn: Connection) -> dict[str, str]:
    cash_rows = get_cash_overview(conn)
    crypto_summary = get_crypto_summary_cards(conn)
    positions = [r for r in get_positions(conn) if r.get("asset_class", "").lower() in {"stock", "equity", "etf"} and r.get("instrument_status", "").lower() != "inactive"]
    cash_total = sum(d(r["amount_chf"]) for r in cash_rows if r["amount_chf"])
    crypto_total = d(crypto_summary["total_value_chf"])
    stock_rows = [r for r in positions if r.get("asset_class", "").lower() in {"stock", "equity"}]
    etf_rows = [r for r in positions if r.get("asset_class", "").lower() == "etf"]
    stock_total = sum(d(r["market_value_chf"]) for r in stock_rows if r.get("market_value_chf"))
    etf_total = sum(d(r["market_value_chf"]) for r in etf_rows if r.get("market_value_chf"))
    equity_total = stock_total + etf_total
    missing_price_count = sum(1 for r in positions if not r.get("market_price_original"))
    missing_fx_count = sum(1 for r in positions if r.get("fx_status") == "missing_fx")
    incomplete_cost_count = sum(1 for r in positions if "cost_basis_uncertain" in (r.get("quality_warnings") or "") or not r.get("cost_basis_chf"))
    unvalued_count = missing_price_count + missing_fx_count
    latest_equity_price = max((r.get("price_date") or "" for r in positions), default="")


Output:
Chunk ID: 8cd77d
Wall time: 30.0010 seconds
Process running with session ID 27426
Original token count: 7
Output:
...........................


Output:
Chunk ID: 24e836
Wall time: 30.0008 seconds
Process running with session ID 27426
Original token count: 0
Output:


Output:
Chunk ID: ed95e7
Wall time: 30.0021 seconds
Process running with session ID 27426
Original token count: 0
Output:


Output:
Chunk ID: 600615
Wall time: 30.0005 seconds
Process running with session ID 27426
Original token count: 0
Output:


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


nl -ba src/jarvis_finance/services/cash_service.py | sed -n '265,330p'


Output:
Chunk ID: 95738b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 869
Output:
   265	                )
   266	                positions.append(
   267	                    CashPosition(
   268	                        id=f"{account_id}:{currency}",
   269	                        account_id=account_id,
   270	                        platform=row["platform"],
   271	                        account_label=row["account_name"],
   272	                        account_type=row["account_type"],
   273	                        currency=currency,
   274	                        balance_mode="official_components",
   275	                        amount=decimal_text(amount_original, 2),
   276	                        amount_chf=decimal_text(amount_chf, 2),
   277	                        calculated_balance_chf=decimal_text(amount_chf, 2),
   278	                        manual_balance_chf=None,
   279	                        csv_anchor_balance_chf=None,
   280	                        used_value_chf=decimal_text(amount_chf, 2),
   281	                        difference_chf="0.00",
   282	                        last_manual_reconciliation=snapshot_date,
   283	                        last_imported_booking=_last_imported_booking(conn, account_id),
   284	                        status=status,
   285	                    )
   286	                )
   287	            continue
   288	        manual = _latest_snapshot(conn, account_id, "manual_balance")
   289	        anchor = _latest_snapshot(conn, account_id, "csv_anchor_balance")
   290	        mode = row["balance_mode"] or "manual"
   291	        default_currency = str(row["currency"])
   292	        ledger_currencies = {
   293	            currency
   294	            for ledger_account_id, currency in ledger.balances
   295	            if ledger_account_id == account_id
   296	        }
   297	        # Manual balances and CSV anchors are account-level CHF controls. They must
   298	        # not be added to per-currency ledger rows from the same account.
   299	        currencies = (
   300	            {default_currency}
   301	            if manual or anchor
   302	            else set(ledger_currencies) or {default_currency}
   303	        )
   304	        for currency in sorted(currencies):
   305	            ledger_balance = ledger.balances.get((account_id, currency))
   306	            if ledger_balance is not None:
   307	                calculated = ledger_balance.amount_chf or Decimal("0")
   308	                amount_original = ledger_balance.amount_original
   309	            else:
   310	                calculated = _calculated_balance(conn, account_id)
   311	                amount_original = (
   312	                    calculated if currency.upper() == "CHF" else Decimal("0")
   313	                )
   314	            manual_amount = (
   315	                Decimal(str(manual["amount_chf"]))
   316	                if manual and currency == default_currency
   317	                else None
   318	            )
   319	            used = (
   320	                manual_amount
   321	                if mode == "manual" and manual_amount is not None
   322	                else calculated
   323	            )
   324	            difference = (
   325	                manual_amount - calculated
   326	                if manual_amount is not None
   327	                else Decimal("0")
   328	            )
   329	            status = "Abgleich offen" if manual_amount is not None and difference != 0 else "Aktuell"
   330	            positions.append(


sed -n '540,690p' src/jarvis_finance/imports/postfinance_documents.py


Output:
Chunk ID: 15f2c4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1598
Output:
                ("interest_breakdown_source_preserved",),
            )
        )
    if len(events) != 3:
        raise ValueError("PostFinance interest statement must contain three currency components")
    return tuple(events)

def _parse_snapshot(raw: bytes) -> PFSnapshot:
    text, page_count = _pdf_text(raw)
    timestamp = re.search(r"(\d{1,2}/\d{1,2}/\d{4})\s+(\d{1,2}:\d{2}:\d{2})", text)
    if not timestamp:
        raise ValueError("PostFinance account overview lacks an exact valuation timestamp")
    date = _date(timestamp.group(1))
    assert date is not None
    valuation_at = f"{date}T{timestamp.group(2)}"
    positions: list[PFSnapshotPosition] = []
    cash: list[PFSnapshotCash] = []
    section: str | None = None
    in_positions = False
    cash_total = securities_total = total = stock_total = etf_total = None
    open_orders = None
    for line in text.splitlines():
        stripped = line.strip()
        if stripped == "Aktien":
            section = "stock"
            continue
        if stripped == "ETFs":
            section = "etf"
            continue
        if "Produkt" in stripped and "Anzahl" in stripped and "Einstandskurs" in stripped:
            in_positions = True
            continue
        cols = [item.strip() for item in re.split(r"\s{2,}", stripped) if item.strip()]
        if len(cols) == 7 and cols[0] in CURRENCIES and re.search(r"\d", cols[1]):
            fx = _number(cols[1], required=True)
            amount = _number(cols[2], required=True)
            value = _number(cols[5], required=True)
            assert fx is not None and amount is not None and value is not None
            cash.append(PFSnapshotCash(cols[0], amount, fx, value))
            continue
        if (
            in_positions
            and section
            and len(cols) == 9
            and re.search(r"\d", cols[1])
            and re.search(r"[A-Z]{3}", cols[5])
        ):
            quantity = _number(cols[1], required=True)
            average = _number(cols[2])
            provider_total = _number(cols[3])
            pm = re.search(r"([+\-−]?[0-9][0-9'’., ]*)\s*([A-Z]{3})", cols[5])
            if not pm:
                raise ValueError("PostFinance overview position lacks price/currency")
            price = _number(pm.group(1), required=True)
            currency = pm.group(2)
            value = _number(cols[7], required=True)
            weight = _number(cols[8])
            assert quantity is not None and price is not None and value is not None
            label = cols[0]
            positions.append(
                PFSnapshotPosition(
                    _hash("snapshot-row", len(positions) + 1, normalize_label(label))[:32],
                    label,
                    normalize_label(label),
                    section,
                    quantity,
                    average,
                    provider_total,
                    price,
                    currency,
                    value,
                    weight,
                )
            )
            continue
        if stripped.startswith("Gesamt CHF") and not in_positions:
            values = [
                _number(value, required=True)
                for value in re.findall(r"[+\-−]?[0-9][0-9'’.,]*", stripped)
            ]
            if len(values) >= 3:
                cash_total, securities_total, total = values[0], values[1], values[2]
            continue
        if stripped.startswith("Zwischensumme Aktien in CHF"):
            values = [
                _number(value, required=True)
                for value in re.findall(r"[+\-−]?[0-9][0-9'’.,]*", stripped)
            ]
            if len(values) >= 3:
                stock_total = values[2]
            continue
        if stripped.startswith("Zwischensumme ETFs in CHF"):
            values = [
                _number(value, required=True)
                for value in re.findall(r"[+\-−]?[0-9][0-9'’.,]*", stripped)
            ]
            if len(values) >= 3:
                etf_total = values[2]
            continue
        m = re.search(r"Offene Aufträge\s+([0-9]+)", stripped)
        if m:
            open_orders = int(m.group(1))
        m = re.search(r"Wert der Wertschriften\s+([0-9][0-9'’.,]*(?: [0-9]{3})*)", stripped)
        if m:
            securities_total = _number(m.group(1), required=True)
        m = re.search(r"Barguthaben\s+([0-9][0-9'’.,]*(?: [0-9]{3})*)", stripped)
        if m:
            cash_total = _number(m.group(1), required=True)
        m = re.search(r"Totalwert\s+([0-9][0-9'’.,]*(?: [0-9]{3})*)", stripped)
        if m and total is None:
            total = _number(m.group(1), required=True)
        m = re.search(r"Zwischensumme Aktien in CHF\s+([0-9][0-9'’.,]*(?: [0-9]{3})*)", stripped)
        if m:
            stock_total = _number(m.group(1), required=True)
        m = re.search(r"Zwischensumme ETFs in CHF\s+([0-9][0-9'’.,]*(?: [0-9]{3})*)", stripped)
        if m:
            etf_total = _number(m.group(1), required=True)
    if len(positions) != 22 or len(cash) != 2:
        raise ValueError(
            "PostFinance account overview does not contain the expected complete snapshot"
        )
    if None in (cash_total, securities_total, total, stock_total, etf_total, open_orders):
        raise ValueError("PostFinance account overview lacks required totals")
    assert (
        cash_total is not None
        and securities_total is not None
        and total is not None
        and stock_total is not None
        and etf_total is not None
        and open_orders is not None
    )
    if abs(sum((p.market_value_chf for p in positions), Decimal("0")) - securities_total) > Decimal(
        "0.05"
    ):
        raise ValueError("PostFinance position sum does not reconcile")
    if abs(securities_total + cash_total - total) > Decimal("0.05"):
        raise ValueError("PostFinance account total does not reconcile")
    if abs(stock_total + etf_total - securities_total) > Decimal("0.05"):
        raise ValueError("PostFinance asset-class totals do not reconcile")
    cash = _reconcile_cash_components(cash, cash_total)
    return PFSnapshot(
        sha256(raw).hexdigest(),
        page_count,
        valuation_at,
        tuple(positions),
        tuple(cash),
        securities_total,
        cash_total,
        total,
        stock_total,


sed -n '1450,1625p' src/jarvis_finance/services/portfolio_data.py


Output:
Chunk ID: dbefc3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2687
Output:
    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
            ORDER BY trade_date, created_at, transaction_id""", (*account_map, as_of, cutoff)
    ).fetchall()
    quantities: dict[tuple[str, str], Decimal] = {}
    activity_supported = 0
    cost_basis_keys: set[tuple[str, str]] = set()
    for row in transaction_rows:
        kind = str(row["activity_kind"] or row["transaction_type"] or "").lower()
        if kind in SUPPORTED_ACTIVITIES:
            activity_supported += 1
        if not row["instrument_id"] or row["quantity"] in (None, ""):
            continue
        key = (str(row["account_id"]), str(row["instrument_id"]))
        try:
            quantity = _stored_decimal(row["quantity"], "Menge", non_negative=True)
        except ValueError:
            continue
        if kind in {"buy", "initial_position_snapshot"}:
            quantities[key] = quantities.get(key, Decimal("0")) + quantity
            if row["gross_amount_original"] not in (None, ""):
                cost_basis_keys.add(key)
        elif kind in {"partial_sell", "full_sell", "sell"}:
            quantities[key] = quantities.get(key, Decimal("0")) - quantity
    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 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}
    keys = sorted(set(quantities) | set(reported))
    differences: list[dict[str, Any]] = []
    price_covered = fx_covered = recon_covered = 0
    account_position_values: dict[str, Decimal] = {key: Decimal("0") for key in account_map}
    account_position_dates: dict[str, set[str]] = {key: set() for key in account_map}
    for account, instrument in keys:
        ledger_qty = quantities.get((account, instrument))
        source = reported.get((account, instrument))
        source_qty = _stored_decimal(source["quantity"], "Gemeldete Menge") if source and source["quantity"] not in (None, "") else None
        reasons: list[str] = []
        if source and str(source["snapshot_date"]) != as_of:
            reasons.append("stale_snapshot")
        if source and str(source["data_quality_status"] or "").lower() not in {"ok", "fresh", "complete"}:
            reasons.append("source_error")
        quantity_status = "unavailable"
        quantity_diff: Decimal | None = None
        if ledger_qty is None or source_qty is None:
            reasons.append("missing_position_snapshot")
        else:
            quantity_diff = ledger_qty - source_qty
            if source and str(source["snapshot_date"]) != as_of:
                quantity_status = "not_comparable"
            else:
                quantity_status = _status(quantity_diff, source_qty, absolute, relative)
                if quantity_status == "mismatch":
                    reasons.append("quantity_mismatch")
        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 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
        price_source = str(price_row["provider"]) if price_row else None
        fx_date = fx_source = None
        if source and price_row and str(source["snapshot_date"]) != price_date:
            reasons.append("cutoff_mismatch")
        if ledger_qty is None:
            reasons.append("missing_position_snapshot")
        elif not price_row:
            reasons.append("missing_price")
        else:
            if price_date != as_of:
                reasons.append("stale_price")
            else:
                price_covered += 1
            price = _stored_decimal(price_row["close"], "Marktpreis", non_negative=True)
            fx, fx_date, fx_source = _latest_fx(conn, str(price_row["currency"]).upper(), as_of, cutoff)
            if fx is None:
                reasons.append("missing_fx")
            else:
                if fx_date != as_of:
                    reasons.append("stale_fx")
                else:
                    fx_covered += 1
                derived_value = ledger_qty * price * fx
        value_status = "unavailable"
        value_diff: Decimal | None = None
        relative_diff: Decimal | None = None
        if derived_value is not None and reported_value is not None:
            if source and (
                "cutoff_mismatch" in reasons
                or "stale_snapshot" in reasons
                or "stale_price" in reasons
                or "stale_fx" in reasons
                or (fx_date and fx_date != price_date)
            ):
                value_status = "not_comparable"
                if "cutoff_mismatch" not in reasons:
                    reasons.append("cutoff_mismatch")
            else:
                value_diff = derived_value - reported_value
                relative_diff = value_diff / reported_value if reported_value != 0 else None
                value_status = _status(value_diff, reported_value, absolute, relative)
                if value_status == "mismatch":
                    reasons.append("value_mismatch")
                recon_covered += 1
        elif reported_value is None:
            reasons.append("missing_position_snapshot")
        if source and reported_value is not None:
            account_position_values[account] += reported_value
            account_position_dates[account].add(str(source["snapshot_date"]))
        instrument_row = conn.execute("SELECT name FROM instruments WHERE instrument_id=?", (instrument,)).fetchone()
        differences.append({
            "difference_ref": _safe_ref("difference", f"{account}:{instrument}:{as_of}"),
            "account_ref": _safe_ref("account", account), "account_label": _safe_label(account_map[account]["account_name"]),
            "instrument_ref": _safe_ref("instrument", instrument), "instrument_label": str(instrument_row["name"]) if instrument_row else "Instrument (unbekannt)",
            "quantity": {"ledger": _decimal_text(ledger_qty), "reported": _decimal_text(source_qty), "difference": _decimal_text(quantity_diff), "status": quantity_status},
            "valuation": {"derived": _decimal_text(derived_value), "reported": _decimal_text(reported_value), "difference": _decimal_text(value_diff), "relative_difference": _decimal_text(relative_diff), "status": value_status,
                          "position_as_of": str(source["snapshot_date"]) if source else None, "price_as_of": price_date, "fx_as_of": fx_date, "price_source": price_source, "fx_source": fx_source},
            "reason_codes": sorted(set(reasons)),
        })
    pf_roles = postfinance_account_roles(conn)
    official_pf_cash = latest_official_postfinance_cash(
        conn,
        as_of=as_of,
        data_cutoff=cutoff,
    )
    official_pf_cash_total = sum(
        (component.amount_chf for component in official_pf_cash), Decimal("0")
    )
    official_pf_cash_date = max(
        (component.snapshot_date for component in official_pf_cash), default=None
    )
    account_totals: list[dict[str, Any]] = []
    account_covered = 0
    for account, meta in account_map.items():
        cash = conn.execute(
            """SELECT amount_chf,balance_date,source FROM cash_account_snapshots WHERE account_id=? AND balance_date<=?
               AND datetime(created_at)<=datetime(?)
               ORDER BY balance_date DESC,created_at DESC,snapshot_id DESC LIMIT 1""", (account, as_of, cutoff)
        ).fetchone()
        cash_value = _stored_decimal(cash["amount_chf"], "Cashbestand") if cash else None
        cash_date = str(cash["balance_date"]) if cash else None
        if account == pf_roles.get("etrading_depot") and official_pf_cash:
            # The provider account total spans the distinct depot and trading-cash
            # roles. This is a reconciliation-only join, not an additive holding.
            cash_value = official_pf_cash_total
            cash_date = official_pf_cash_date


Output:
Chunk ID: 1e7b0b
Wall time: 5.0017 seconds
Process running with session ID 27426
Original token count: 0
Output:


grep -n "postfinance_account_roles\|INSERT INTO transactions" -n src/jarvis_finance/services/postfinance_service.py | head -30 && sed -n '520,760p' src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 829d93
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3106
Output:
484:        f"INSERT INTO transactions({columns}) VALUES({','.join('?' for _ in values)})", values
541:                "INSERT OR IGNORE INTO postfinance_account_roles(role,account_id,source_reference_hash,created_at) VALUES(?,?,NULL,?)",
545:                "SELECT account_id FROM postfinance_account_roles WHERE role=?", (role,)
        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)
            existing = conn.execute(
                "SELECT document_hash FROM postfinance_documents WHERE semantic_identity=?",
                (document.semantic_identity,),
            ).fetchone()
            if existing and existing["document_hash"] != document.document_hash:
                raise ValueError("PostFinance semantic document conflict")
            conn.execute(
                """INSERT OR IGNORE INTO postfinance_documents(document_hash,filename_hash,semantic_identity,semantic_reference_hash,document_type,document_date,account_reference_hash,account_role,page_count,archive_reference,parser_version,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)""",
                (
                    document.document_hash,
                    document.filename_hash,
                    document.semantic_identity,
                    ref_hash,
                    document.document_type,
                    document.document_date,
                    document.account_reference_hash,
                    document.account_role,
                    document.page_count,
                    reference,
                    PARSER_VERSION,
                    now,
                ),
            )
            conn.execute(
                "INSERT INTO postfinance_batch_documents(batch_id,document_hash) VALUES(?,?)",
                (batch_id, document.document_hash),
            )
        snapshot = bundle.snapshot
        component_total = snapshot.securities_total_chf + snapshot.cash_total_chf
        difference = snapshot.total_value_chf - component_total
        conn.execute(
            """INSERT INTO postfinance_snapshots(snapshot_id,batch_id,account_id,snapshot_at,total_chf,securities_chf,cash_chf,stocks_chf,etfs_chf,component_total_chf,difference_chf,tolerance_chf,position_count,cash_count,open_orders,reconciliation_status,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,? ,?,?,?,?,?)""",
            (
                snapshot_id,
                batch_id,
                accounts["etrading_depot"],
                snapshot.valuation_at,
                _money(snapshot.total_value_chf),
                _money(snapshot.securities_total_chf),
                _money(snapshot.cash_total_chf),
                _money(snapshot.stock_total_chf),
                _money(snapshot.etf_total_chf),
                _money(component_total),
                _money(difference),
                _money(TOLERANCE),
                len(snapshot.positions),
                len(snapshot.cash),
                snapshot.open_orders,
                "matched" if difference == 0 else "within_tolerance",
                now,
            ),
        )
        for event in bundle.events:
            instrument_id = event_instruments[event.event_fingerprint]
            event_id = f"pfevent_{event.event_fingerprint[:24]}"
            account_id = accounts[event.account_role]
            conn.execute(
                """INSERT INTO postfinance_ledger_events(event_id,event_fingerprint,document_hash,semantic_reference_hash,event_type,account_role,account_id,occurred_on,settlement_on,direction,instrument_id,quantity,price_original,gross_original,fee_original,tax_original,net_original,currency,fx_rate_to_chf,internal_transfer_group,quality_status,reason_codes_json,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
                (
                    event_id,
                    event.event_fingerprint,
                    event.document_hash,
                    _hash(event.semantic_reference),
                    event.event_type,
                    event.account_role,
                    account_id,
                    event.occurred_on,
                    event.settlement_on,
                    event.direction or "neutral",
                    instrument_id,
                    _text(event.quantity),
                    _text(event.price_original),
                    _text(event.gross_original),
                    _text(event.fee_original) or "0",
                    _text(event.tax_original) or "0",
                    _text(event.net_original),
                    event.currency,
                    _text(event.fx_rate_to_chf),
                    event.internal_transfer_group,
                    event.quality_status,
                    json.dumps(event.reason_codes),
                    now,
                ),
            )
            for kind, amount in (
                ("gross", event.gross_original),
                ("fee", event.fee_original),
                ("tax", event.tax_original),
                ("net", event.net_original),
            ):
                if amount is not None and event.currency:
                    conn.execute(
                        "INSERT INTO postfinance_event_components(component_id,event_id,component_type,amount_original,currency,provenance_document_hash,created_at) VALUES(?,?,?,?,?,?,?)",
                        (
                            _id("pfcomponent"),
                            event_id,
                            kind,
                            _text(amount),
                            event.currency,
                            event.document_hash,
                            now,
                        ),
                    )
            _canonical_transaction(conn, event_id, event, account_id, instrument_id, now)
        lots: dict[str, list[dict[str, Any]]] = defaultdict(list)
        for event in sorted(
            bundle.events,
            key=lambda item: (
                item.occurred_on,
                0 if item.event_type == "buy" else 1,
                item.event_fingerprint,
            ),
        ):
            instrument_id = event_instruments[event.event_fingerprint]
            if (
                event.event_type == "buy"
                and instrument_id
                and event.quantity
                and event.price_original
                and event.currency
            ):
                lots[instrument_id].append({"event": event, "remaining": event.quantity})
            elif event.event_type == "sell" and instrument_id and event.quantity:
                to_consume = event.quantity
                for lot in lots[instrument_id]:
                    if to_consume <= 0:
                        break
                    consumed = min(lot["remaining"], to_consume)
                    lot["remaining"] -= consumed
                    to_consume -= consumed
        for instrument_id, instrument_lots in lots.items():
            for lot in instrument_lots:
                event = lot["event"]
                conn.execute(
                    """INSERT INTO postfinance_cost_basis_lots(lot_id,event_id,instrument_id,acquired_on,quantity_acquired,quantity_remaining,unit_cost_original,fees_original,currency,method,provenance_document_hash,created_at) VALUES(?,?,?,?,?,?,?,?,?,'documented_trade_fifo',?,?)""",
                    (
                        _id("pflot"),
                        f"pfevent_{event.event_fingerprint[:24]}",
                        instrument_id,
                        event.occurred_on,
                        _text(event.quantity),
                        _text(lot["remaining"]),
                        _text(event.price_original),
                        _text(event.fee_original) or "0",
                        event.currency,
                        event.document_hash,
                        now,
                    ),
                )
        for position in snapshot.positions:
            instrument_id = position_map[position.row_reference]
            matched_lots = lots.get(instrument_id, [])
            quantity = sum((lot["remaining"] for lot in matched_lots), Decimal("0"))
            complete = (
                bool(matched_lots)
                and quantity == position.quantity
                and len({lot["event"].currency for lot in matched_lots}) == 1
            )
            calculated = (
                sum(
                    (
                        lot["remaining"] * (lot["event"].price_original or 0)
                        + (lot["event"].fee_original + lot["event"].tax_original)
                        * (lot["remaining"] / lot["event"].quantity)
                        for lot in matched_lots
                        if lot["event"].quantity
                    ),
                    Decimal("0"),
                )
                if complete
                else None
            )
            status = "complete" if complete else "partial" if matched_lots else "unavailable"
            conn.execute(
                """INSERT INTO postfinance_snapshot_positions(snapshot_position_id,snapshot_id,source_row_reference,instrument_id,asset_class,quantity,provider_average_cost_original,provider_cost_total_original,price_original,price_currency,value_chf,weight_pct,computed_cost_basis_original,computed_cost_basis_status,provenance_json,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
                (
                    _id("pfposition"),
                    snapshot_id,
                    position.row_reference,
                    instrument_id,
                    position.asset_class,
                    _text(position.quantity),
                    _text(position.provider_average_cost_original),
                    _text(position.provider_cost_total_original),
                    _text(position.market_price_original),
                    position.price_currency,
                    _money(position.market_value_chf),
                    _text(position.weight_pct),
                    _text(calculated),
                    status,


sed -n '440,505p' src/jarvis_finance/services/postfinance_service.py && sed -n '760,830p' src/jarvis_finance/services/postfinance_service.py


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

def confirm_postfinance_import(conn: Connection, request: dict[str, Any]) -> dict[str, Any]:
    if request.get("confirm") is not True:
        raise ValueError("Explicit PostFinance import confirmation is required")
    preview = preview_postfinance_import(conn, request)
    if (
        request.get("preview_id") != preview["preview_id"]
        or request.get("confirmation_id") != preview["confirmation_id"]
    ):
        raise ValueError("PostFinance import preview is stale or changed")
    if preview["conflict"]:
        raise ValueError("PostFinance source conflicts with existing immutable business identity")
    if preview["duplicate"]:
        row = conn.execute(
            "SELECT batch_id,audit_id FROM postfinance_import_batches WHERE bundle_sha256=?",
            (preview["bundle_sha256"],),
        ).fetchone()
        return {
            "status": "confirmed",
                    status,
                    json.dumps(
                        {
                            "provider": "official_account_overview",
                            "calculated": "documented_trade_fifo",
                            "estimated": False,
                        },
                        sort_keys=True,
                    ),
                    now,
                ),
            )
            conn.execute(
                """INSERT INTO positions_snapshot(position_snapshot_id,snapshot_date,account_id,platform_id,instrument_id,quantity,average_cost_original,cost_basis_original,market_price_original,market_value_original,market_fx_rate_to_chf,market_value_chf,portfolio_weight_pct,category,data_quality_status,source_type,source_reference,created_at) SELECT ?,?,?,a.platform_id,?,?,?,?,?,?,?,?,?,?,?,?,?,? FROM accounts a WHERE a.account_id=?""",
                (
                    _id("position"),
                    snapshot.valuation_at[:10],
                    accounts["etrading_depot"],
                    instrument_id,
                    _text(position.quantity),
                    _text(position.provider_average_cost_original),
                    _text(position.provider_cost_total_original),
                    _text(position.market_price_original),
                    _text(position.quantity * position.market_price_original),
                    None,
                    _money(position.market_value_chf),
                    _text(position.weight_pct),
                    position.asset_class,
                    "verified",
                    "postfinance_official_import",
                    snapshot_id,
                    now,
                    accounts["etrading_depot"],
                ),
            )
        for cash in snapshot.cash:
            conn.execute(
                "INSERT INTO postfinance_snapshot_cash(snapshot_cash_id,snapshot_id,currency,amount_original,fx_rate_to_chf,value_chf,created_at) VALUES(?,?,?,?,?,?,?)",
                (
                    _id("pfcash"),
                    snapshot_id,
                    cash.currency,
                    _text(cash.amount_original),
                    _text(cash.fx_rate_to_chf),
                    _money(cash.source_value_chf),
                    now,
                ),
            )
            conn.execute(
                "INSERT INTO cash_balances(cash_balance_id,account_id,balance_date,currency,amount_original,fx_rate_to_chf,amount_chf,source_type,quality_status,notes,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)",
                (
                    _id("cash"),
                    accounts["etrading_cash"],
                    snapshot.valuation_at[:10],
                    cash.currency,
                    _text(cash.amount_original),
                    _text(cash.fx_rate_to_chf),
                    _money(cash.source_value_chf),
                    "postfinance_official_import",
                    "verified",
                    "Official PostFinance account overview",
                    now,
                ),
            )
        conn.execute(
            "INSERT INTO account_value_snapshots(snapshot_id,account_id,valuation_date,total_value_chf,currency,source_type,quality_status,notes,created_at,valuation_at,source_reference,is_active) VALUES(?,?,?,?,'CHF','postfinance_official_import','ok','Official PostFinance account overview',?,?,?,1)",
            (
                _id("acctval"),
                accounts["etrading_depot"],
                snapshot.valuation_at[:10],
                _money(snapshot.total_value_chf),


grep -n "def _money\|def _text" -n src/jarvis_finance/services/postfinance_service.py


Output:
Chunk ID: 95a40c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 23
Output:
47:def _text(value: Decimal | None) -> str | None:
51:def _money(value: Decimal) -> str:


sed -n '40,55p' src/jarvis_finance/services/postfinance_service.py


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

def _hash(*values: object) -> str:
    return sha256(
        json.dumps(values, sort_keys=True, separators=(",", ":"), default=str).encode()
    ).hexdigest()

def _text(value: Decimal | None) -> str | None:
    return format(value, "f") if value is not None else None

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

def _decode(value: str, label: str) -> bytes:


Output:
Chunk ID: 6ecbc1
Wall time: 5.0018 seconds
Process running with session ID 27426
Original token count: 0
Output:


[P2] Use account-level balance when snapshots exist

When an account has a manual balance or CSV anchor, the code collapses output to the default currency, but this branch still prefers the ledger balance for that single currency. If such an account also has a default-currency ledger row, `calculated` becomes only that currency's ledger amount, ignoring the CSV anchor and any other currency movements; for manual accounts the displayed difference/status can also be wrong. Snapshot-controlled accounts should use the account-level `_calculated_balance(...)` instead of a per-currency ledger row.

The cash read model can understate snapshot-controlled accounts when a default-currency ledger row exists, which breaks portfolio totals and reconciliation status for those inputs.