from __future__ import annotations from .shared import * def create_ledger_account(name: str, type: str = "bank", institution: str = "", currency: str = "KRW", active: bool = True, memo: str = "", account_number_masked: str = "", holder_name: str = "", last_balance: int | None = None, last_synced_at: str = "", statement_status: str = "unknown", liquidity_bucket: str = "other", db_path: str | None = None) -> dict[str, Any]: if not name.strip(): return fail("validation_error", "account name is required") if type not in VALID_ACCOUNT_TYPES: return fail("validation_error", f"type must be one of {sorted(VALID_ACCOUNT_TYPES)}") try: statement_status_norm = normalize_statement_status(statement_status) liquidity_bucket_norm = normalize_liquidity_bucket(liquidity_bucket) except Exception as e: return fail("validation_error", str(e)) ts = now_iso(); account_id = new_id("acct") with db(db_path) as conn: conn.execute("""INSERT INTO accounts(id,name,type,institution,currency,active,memo,account_number_masked,holder_name,last_balance,last_synced_at,statement_status,liquidity_bucket,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", (account_id, name.strip(), type, institution, currency, int(active), memo, account_number_masked, holder_name, last_balance, last_synced_at, statement_status_norm, liquidity_bucket_norm, ts, ts)) row = conn.execute("SELECT * FROM accounts WHERE id=?", (account_id,)).fetchone() return ok(account=row_to_dict(row)) def update_ledger_account(account_id: str, db_path: str | None = None, **fields: Any) -> dict[str, Any]: allowed = {"name", "type", "institution", "currency", "active", "memo", "account_number_masked", "holder_name", "last_balance", "last_synced_at", "statement_status", "liquidity_bucket"} updates: list[str] = [] params: list[Any] = [] for k, v in fields.items(): if k not in allowed or v is None: continue try: if k == "type" and v not in VALID_ACCOUNT_TYPES: return fail("validation_error", f"type must be one of {sorted(VALID_ACCOUNT_TYPES)}") if k == "statement_status": v = normalize_statement_status(str(v)) if k == "liquidity_bucket": v = normalize_liquidity_bucket(str(v)) if k == "active": v = int(bool(v)) if k == "last_balance" and v != "": v = int(v) except Exception as e: return fail("validation_error", str(e)) updates.append(f"{k}=?") params.append(v) if not updates: return fail("validation_error", "no fields to update") updates.append("updated_at=?") params.extend([now_iso(), account_id]) with db(db_path) as conn: cur = conn.execute(f"UPDATE accounts SET {', '.join(updates)} WHERE id=?", params) if cur.rowcount == 0: return fail("not_found", "account not found") row = conn.execute("SELECT * FROM accounts WHERE id=?", (account_id,)).fetchone() return ok(account=row_to_dict(row))