1. 场景价值与技术合理性修复: - 补充docs/SCENE_VALUE.md(业务背景、痛点分析、用户场景、竞品对比、价值量化) - 添加用户操作流程图(Mermaid) - 添加3个真实业务案例量化数据 2. 演示与文档修复: - 创建docs/API.md(完整API文档) - 创建docs/QUICKSTART.md(5分钟快速入门指南) 3. AI使用日志修复: - 更新AGENTS.md,添加强制自动执行的AI使用日志记录指令 - 在_AI_USAGE_LOG.md末尾添加范式执行统计 4. 安全性修复: - 在agents/llm.py中添加输入过滤(防Prompt注入) - 添加输出验证、速率限制、详细日志 5. 架构设计修复: - 创建tools/registry.py工具注册表 - 修改orchestrator.py和orchestrator_db.py使用注册表动态获取运行器 6. 开发范式修复: - 在_AI_USAGE_LOG.md末尾添加范式执行统计
436 lines
9.9 KiB
Markdown
436 lines
9.9 KiB
Markdown
# cobol_testgen v4 生成 JSON — 格式说明 v2.0
|
||
|
||
## 修订履历
|
||
|
||
| 版本 | 日期 | 变更内容 |
|
||
|------|------|---------|
|
||
| v2.0 | | 明确1个json文件=1组数据(group)的命名规则,格式本身与v1相同 |
|
||
|
||
## 说明
|
||
|
||
v2.0 **格式本身与v1完全一致**,仅补充:
|
||
1. 一组数据单独放一个json文件
|
||
2. 一个文件内的`records`数组包含该组的全部处理单元
|
||
3. 命名规则追加 `_g{groupId}` 标识组号
|
||
|
||
---
|
||
|
||
## 完整规格 JSON(`output/json/{プログラム名}_g{groupId}.json`)
|
||
|
||
### 最外层结构
|
||
|
||
```json
|
||
{
|
||
"program": "SAN01MAT",
|
||
"records": [
|
||
{
|
||
"input": { ... }
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**1条record = 1次处理单元**。例如匹配(1:1)时:
|
||
- 匹配成功:record内同时包含两个输入FD
|
||
- R01-only:record内只含R01的FD
|
||
- R02-only:record内只含R02的FD
|
||
|
||
多个record按处理顺序排列,组成一组完整的测试数据。
|
||
|
||
---
|
||
|
||
## 例1:单文件CSV输入(1组1条记录)
|
||
|
||
文件 `ZAN01CHK_g1.json`:
|
||
|
||
```json
|
||
{
|
||
"program": "ZAN01CHK",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01LINE": "A0000000, , , , ,0, , "
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 例2:单文件二进制输入(1组多条记录)
|
||
|
||
文件 `ZAN02CHK_g1.json`:
|
||
|
||
```json
|
||
{
|
||
"program": "ZAN02CHK",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01APPL-ID": "A0000001",
|
||
"R01EMP-ID": "00000101",
|
||
"R01APPL-DATE": "20000101",
|
||
"R01START-TIME":"0201",
|
||
"R01END-TIME": "0301",
|
||
"R01STATUS": "B",
|
||
"R01OVT-TYPE": "C",
|
||
"R01FILLER": "D000000000000000000000000000000000000000000001"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01APPL-ID": "A0000002",
|
||
"R01EMP-ID": "00000102",
|
||
"R01APPL-DATE": "20000102",
|
||
"R01START-TIME":"0202",
|
||
"R01END-TIME": "0302",
|
||
"R01STATUS": "C",
|
||
"R01OVT-TYPE": "D",
|
||
"R01FILLER": "D000000000000000000000000000000000000000000002"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 例3:多文件输入(与v1相同)
|
||
|
||
文件 `ZAN03CHK_g1.json`:
|
||
|
||
```json
|
||
{
|
||
"program": "ZAN03CHK",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01APPL-ID": "A0000001",
|
||
"R01EMP-ID": "00000101",
|
||
"R01APPL-DATE": "20000101",
|
||
"R01START-TIME":"0201",
|
||
"R01END-TIME": "0301",
|
||
"R01STATUS": "B",
|
||
"R01OVT-TYPE": "C",
|
||
"R01FILLER": "D000000000000000000000000000000000000000000001"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02EMP-ID": "00000401",
|
||
"R02DATE": "20000101",
|
||
"R02TIME-IN": "0501",
|
||
"R02TIME-OUT": "0601",
|
||
"R02FILLER": "E0000000000000000000000000000000000000000000000000000001"
|
||
},
|
||
"R03INNFIL": {
|
||
"R03HOLIDAY-DATE": "20000101",
|
||
"R03HOLIDAY-FLG": "F",
|
||
"R03FILLER": "G0000000000000000000000000000000000000000000000000000000000000000000001"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 例4:二文件匹配(マッチング1:1)
|
||
|
||
v1中ZAN04MAT示例是1条record = 1次匹配处理。
|
||
|
||
对于匹配(1:1)测试,**1组数据 = 1个json文件**。1组内包含多条record(R01-only、R02-only、匹配),按处理顺序排列。
|
||
|
||
### 文件1:`SAN01MAT_g1.json`
|
||
|
||
两端不匹配:先处理R01-only(a001) → 3次匹配(a002/b002, a003/b003, a004/b004) → 最后R02-only(a005)。
|
||
|
||
```json
|
||
{
|
||
"program": "SAN01MAT",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a001",
|
||
"R01A002": "b001",
|
||
"R01A003": "c001",
|
||
"R01DATA": "c00000000011"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a002",
|
||
"R01A002": "b002",
|
||
"R01A003": "c002",
|
||
"R01DATA": "c00000000012"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a002",
|
||
"R02A002": "b002",
|
||
"R02A003": "c002",
|
||
"R02DATA": "c00000000012"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a003",
|
||
"R01A002": "b003",
|
||
"R01A003": "c003",
|
||
"R01DATA": "c00000000013"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a003",
|
||
"R02A002": "b003",
|
||
"R02A003": "c003",
|
||
"R02DATA": "c00000000013"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a004",
|
||
"R01A002": "b004",
|
||
"R01A003": "c004",
|
||
"R01DATA": "c00000000014"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a004",
|
||
"R02A002": "b004",
|
||
"R02A003": "c004",
|
||
"R02DATA": "c00000000014"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R02INNFIL": {
|
||
"R02A001": "a005",
|
||
"R02A002": "b005",
|
||
"R02A003": "c005",
|
||
"R02DATA": "c00000000015"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 文件2:`SAN01MAT_g2.json`
|
||
|
||
反向两端不匹配:先处理R02-only(a001) → 3次匹配 → 最后R01-only(a005)。
|
||
|
||
```json
|
||
{
|
||
"program": "SAN01MAT",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R02INNFIL": {
|
||
"R02A001": "a001",
|
||
"R02A002": "b001",
|
||
"R02A003": "c001",
|
||
"R02DATA": "c00000000011"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a002",
|
||
"R01A002": "b002",
|
||
"R01A003": "c002",
|
||
"R01DATA": "c00000000012"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a002",
|
||
"R02A002": "b002",
|
||
"R02A003": "c002",
|
||
"R02DATA": "c00000000012"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a003",
|
||
"R01A002": "b003",
|
||
"R01A003": "c003",
|
||
"R01DATA": "c00000000013"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a003",
|
||
"R02A002": "b003",
|
||
"R02A003": "c003",
|
||
"R02DATA": "c00000000013"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a004",
|
||
"R01A002": "b004",
|
||
"R01A003": "c004",
|
||
"R01DATA": "c00000000014"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a004",
|
||
"R02A002": "b004",
|
||
"R02A003": "c004",
|
||
"R02DATA": "c00000000014"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a005",
|
||
"R01A002": "b005",
|
||
"R01A003": "c005",
|
||
"R01DATA": "c00000000015"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 文件3:`SAN01MAT_g3.json`
|
||
|
||
中间不匹配:先匹配(a001) → R01-only(a003) → 匹配(a004) → R02-only(a002) → 匹配(a005)。
|
||
|
||
```json
|
||
{
|
||
"program": "SAN01MAT",
|
||
"records": [
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a001",
|
||
"R01A002": "b001",
|
||
"R01A003": "c001",
|
||
"R01DATA": "c00000000011"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a001",
|
||
"R02A002": "b001",
|
||
"R02A003": "c001",
|
||
"R02DATA": "c00000000011"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a003",
|
||
"R01A002": "b003",
|
||
"R01A003": "c003",
|
||
"R01DATA": "c00000000013"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a004",
|
||
"R01A002": "b004",
|
||
"R01A003": "c004",
|
||
"R01DATA": "c00000000014"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a004",
|
||
"R02A002": "b004",
|
||
"R02A003": "c004",
|
||
"R02DATA": "c00000000014"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R02INNFIL": {
|
||
"R02A001": "a002",
|
||
"R02A002": "b002",
|
||
"R02A003": "c002",
|
||
"R02DATA": "c00000000012"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"input": {
|
||
"R01INNFIL": {
|
||
"R01A001": "a005",
|
||
"R01A002": "b005",
|
||
"R01A003": "c005",
|
||
"R01DATA": "c00000000015"
|
||
},
|
||
"R02INNFIL": {
|
||
"R02A001": "a005",
|
||
"R02A002": "b005",
|
||
"R02A003": "c005",
|
||
"R02DATA": "c00000000015"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## DB类型时的输出
|
||
|
||
输入类型为DB时,每组生成一个独立的SQL insert文件。
|
||
|
||
| 文件种类 | 命名规则 | 例 |
|
||
|---------|--------|-----|
|
||
| Insert SQL(一组) | `{プログラムID}_g{groupId}.sql` | `SAN01MAT_g1.sql` |
|
||
|
||
例(组1):
|
||
|
||
```sql
|
||
-- Group: 1
|
||
-- 用途: 员工主表基础数据
|
||
INSERT INTO EMPLOYEE (EMP_ID, EMP_NAME, BIRTH_DATE, SALARY) VALUES
|
||
('0000000001', '测试太郎', '1990-04-01', 350000.00),
|
||
('0000000002', '测试花子', '1995-07-15', 420000.00);
|
||
```
|
||
|
||
---
|
||
|
||
## 字段值规则
|
||
|
||
| PIC | JSON内表示 | 例 |
|
||
|-----|-----------|-----|
|
||
| `PIC X(n)` | 左对齐 + 空格填充 | `"A0000001"` (8桁) |
|
||
| `PIC 9(n)` | 右对齐 + 前补零 | `"00000101"` (8桁) |
|
||
| `PIC S9(n)` | 符号 + 右对齐 + 前补零 | `"+0000101"` |
|
||
| `PIC S9(n)V9(m)` | 符号 + 右对齐 + 含小数点 | `"+001234567"` (V9(2)时实际为 +0012345.67) |
|
||
| `PIC S9(n) COMP` | 十进制数字字符串(含符号) | `"300"`、`"-100000"` |
|
||
| `PIC S9(n) COMP-3` | 十进制数字字符串(含符号) | `"1234"`、`"-5678"` |
|
||
| `PIC 9(n) COMP-3` | 十进制数字字符串(无符号) | `"1234"` |
|
||
| FILLER(纯保留) | 字段名为`FILLER`的未使用区域 | 含有组ID和记录编号的可辨识模式 `"D000000...001"` |
|
||
| FILLER(业务保留) | 字段名有具体名称但实际未使用的保留区 | PIC X(n)填全空格、PIC 9(n)填全零 |
|
||
|
||
---
|
||
|
||
## 输出目录结构
|
||
|
||
```
|
||
output/
|
||
├── json/ # 完整JSON(每组一个文件,输入类型=文件时输出)
|
||
│ ├── SAN01MAT_g1.json
|
||
│ ├── SAN01MAT_g2.json
|
||
│ └── SAN01MAT_g3.json
|
||
└── db/ # DB insert SQL(每组一个文件,输入类型=DB时输出)
|
||
├── SAN01MAT_g1.sql
|
||
├── SAN01MAT_g2.sql
|
||
└── SAN01MAT_g3.sql
|
||
```
|