Metadata-Version: 2.4
Name: ibor-audit-tool
Version: 0.1.10
Summary: IBOR估值核对工具
Requires-Python: >=3.12
Requires-Dist: psycopg2-binary>=2.9
Requires-Dist: sqlalchemy>=2.0
Description-Content-Type: text/markdown

# xaudit 用法

## 命令

```bash
xaudit CONFIG_PATH
```

读取单个 `.sql` 或 `.txt` 配置文件，生成 HTML 报告。默认输出到当前目录，文件名为 `<配置文件名>.html`。

```bash
xaudit CONFIG_PATH --output report.html
xaudit CONFIG_PATH -o report.html
```

读取单个配置文件，并把报告写入指定路径。`--output` 只能和单个配置文件一起使用，不能用于目录扫描。

```bash
xaudit DIRECTORY
```

按文件名顺序扫描目录第一层的 `.sql` 和 `.txt` 配置文件，并在该目录下分别生成 `<配置文件名>.html`。

```bash
xaudit
```

扫描当前目录第一层的 `.sql` 和 `.txt` 配置文件。

```bash
xaudit --version
```

查看版本号。

## 配置文件格式

配置文件使用 `.sql` 或 `.txt` 后缀。每个配置块之间用 `----` 分隔。

- 必须定义两个 `-- connection:` 块；第一个连接用于每个对比的第一段 SQL，第二个连接用于第二段 SQL。
- `-- url:` 必须是完整的字面量数据库 URL，不能写环境变量。
- 每个 `-- compare:` 块必须包含两个以分号结束的 SQL 语句。
- `-- tolerance:` 可作为全局容差，也可写在单个 `-- compare:` 块中覆盖全局容差。
- `-- keys:` 可作为全局主键列，也可写在单个 `-- compare:` 块中覆盖全局主键列；多个列用逗号分隔。未配置时默认使用查询结果第一列作为主键列。
- `-- param:` 支持固定值列表或查询结果；参数名只能使用大写字母、数字和下划线。
- SQL 中使用 `{{PARAM_NAME}}` 引用参数；多个参数会按笛卡尔积展开为多个对比。
- `-- rule:` 格式为 `<expression> => <result>`，结果支持字符串、`IGNORE`、`NONE`。

### rule 表达式示例

`rule` 使用 Python 表达式语法，布尔与/或需要写成小写 `and` / `or`。

```sql
-- rule: FA['id'] == IBOR['id'] and abs(FA['amount'] - IBOR['amount']) < 1 => IGNORE
-- rule: FA['status'] == 'CANCELLED' or IBOR['status'] == 'CANCELLED' => "cancelled record"
-- rule: (FA['id'] == IBOR['id']) and (FA['amount'] != IBOR['amount']) => "same id amount diff"
```

## 最简范例

保存为 `amount_check.sql`：

```sql
-- connection: FA
-- url: postgresql://user:password@localhost:5432/source_db
----
-- connection: IBOR
-- url: postgresql://user:password@localhost:5432/target_db
----
-- compare: amount_check
select id, amount
from source_amount;

select id, amount
from target_amount;
```

运行：

```bash
xaudit amount_check.sql --output amount_check.html
```

## 全功能范例

保存为 `full_check.sql`：

```sql
-- connection: FA
-- url: postgresql://ibor_user:ibor_user@localhost:5432/ibor-demo
----
-- connection: IBOR
-- url: postgresql://ibor_user:ibor_user@localhost:5432/ibor-demo
----
-- tolerance: 0.01
----
-- keys: trade_date, portfolio_id, secu_code
----
-- param: TRADE_DATE
-- values: 20260604,20260605
----
-- param: PORTFOLIO_ID
-- connection: IBOR
select distinct portfolio_id
from irmp.ibor_bond_position
where trade_date in (20260604, 20260605)
  and secu_code like '%HK'
  and calc_basis = '1'
  and invest_type = '1';
----
-- compare: total_pnl
-- tolerance: 0.001
-- keys: trade_date, portfolio_id, secu_code
-- rule: abs(FA['ytd_total_pnl'] - IBOR['ytd_total_pnl']) < 1 => "rounding difference"
-- rule: FA['trade_date'] == IBOR['trade_date'] => IGNORE
select
  cast(replace(enddate, '-', '') as int) as trade_date,
  concat(t1.stkid, '.', 'HK') as secu_code,
  'XIR_' || book as portfolio_id,
  reportpl as ytd_total_pnl
from ods_faas.bd_ods_faas_glhs_bond_rpt_nxt_his t1
where cast(replace(enddate, '-', '') as int) = {{TRADE_DATE}}
  and 'XIR_' || book = {{PORTFOLIO_ID}};

select
  trade_date,
  portfolio_id,
  secu_code,
  ytd_total_pnl
from irmp.ibor_bond_position
where secu_code like '%HK'
  and trade_date = {{TRADE_DATE}}
  and portfolio_id = {{PORTFOLIO_ID}}
  and calc_basis = '1'
  and invest_type = '1';
```

运行：

```bash
xaudit full_check.sql --output full_check.html
```
