#!/usr/bin/env python3 """Seed controlled synthetic Saudi-oriented demo finance data — explicit, never at import time. Creates clearly-fictional (simulation_only) institutions and merchants, and — in synthetic mode — optional synthetic customer/operator users with opening balances posted through balanced journals. Requires --confirm-d3. No real participant data. Example: python scripts/d3_seed_demo_finance.py --db-path /tmp/amanpay-d2/amanpay.db --tenant event \ --confirm-d3 --customers 2 --allow-unknown-fs --json """ from __future__ import annotations import argparse import sys from amanpay.finance.cli import (add_common_args, build_runtime_for_cli, emit, resolve_tenant_id) from amanpay.finance.seed import seed_customer, seed_institutions, seed_merchants from amanpay.identity.handles import normalize_handle def _ensure_tenant(rt, tenant: str): tid = resolve_tenant_id(rt, tenant) if tid is not None: return tid t = rt.identity.repo.create_tenant(slug=tenant, name_en="Demo Event", name_ar="فعالية تجريبية") return t.id def _synthetic_user(rt, tid, handle, role="customer"): existing = rt.identity.repo.find_user_by_handle(tid, normalize_handle(handle)) if existing is not None: return existing u = rt.identity.repo.create_user( tenant_id=tid, webauthn_user_handle=f"syn-{handle}", public_handle=handle, public_handle_norm=normalize_handle(handle), display_alias=handle.title(), preferred_language="en", role=role, status="enrollment_pending") rt.identity.repo.set_user_status(u.id, "active") return rt.identity.repo.get_user(u.id) def main(argv=None) -> int: p = argparse.ArgumentParser(description="Seed synthetic D3 demo finance data.") add_common_args(p, tenant_required=True) p.add_argument("--confirm-d3", action="store_true", required=True) p.add_argument("--customers", type=int, default=0, help="create N synthetic customer users with opening balances (synthetic mode)") p.add_argument("--opening-minor", type=int, default=100000) args = p.parse_args(argv) rt = build_runtime_for_cli(args.db_path, allow_unknown_fs=args.allow_unknown_fs) tid = _ensure_tenant(rt, args.tenant) operator = _synthetic_user(rt, tid, "demo_operator", role="operator") if args.customers else None institutions = seed_institutions(rt, tid) merchants = seed_merchants(rt, tid, operator_user_id=(operator.id if operator else None)) customers = [] for i in range(max(0, args.customers)): u = _synthetic_user(rt, tid, f"demo_customer_{i+1}") accts = seed_customer(rt, tid, u.id, opening_minor=args.opening_minor) customers.append({"user_id": u.id, "handle": u.public_handle, **accts}) emit({"ok": True, "tenant_id": tid, "institutions": len(institutions), "merchants": len(merchants), "customers": len(customers)}, as_json=args.json) rt.close() return 0 if __name__ == "__main__": sys.exit(main())