@dazitech/cli 3.0.7 → 3.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/dist/clis/dazi-app.js +1 -1
  3. package/dist/clis/dazi-flow.js +1 -1
  4. package/dist/clis/dazi-onto.js +73 -22
  5. package/dist/clis/dazi.js +266 -171
  6. package/dist/docs/flow/flow-project-guide.md +1 -1
  7. package/dist/docs/guides/quickstart.md +18 -4
  8. package/dist/docs/guides/troubleshooting.md +12 -1
  9. package/dist/docs/guides/workspace-v3.md +43 -23
  10. package/dist/docs/index.json +28 -3
  11. package/dist/docs/onto/action-guide.md +3 -3
  12. package/dist/docs/onto/dazi_script_sdk_reference.md +244 -174
  13. package/dist/docs/onto/dazi_script_seed_data_guide.md +158 -155
  14. package/dist/docs/onto/function-guide.md +82 -27
  15. package/dist/docs/onto/space-management.md +3 -1
  16. package/dist/docs/onto//346/234/254/344/275/223/345/210/206/347/261/273/350/247/204/345/210/222/344/270/216SDK/346/211/251/345/261/225/346/226/271/346/241/210.md +168 -0
  17. package/dist/docs/onto//346/234/254/344/275/223/345/221/275/345/220/215/350/247/204/350/214/203_/347/211/251/347/220/206/350/241/250Cube/344/270/216/345/257/271/350/261/241.md +402 -0
  18. package/dist/docs/onto//346/234/254/344/275/223/350/204/232/346/234/254/347/274/226/345/206/231/346/214/207/345/215/227.md +200 -34
  19. package/dist/docs/onto//346/234/254/344/275/223/350/247/204/345/210/222/346/214/207/345/215/227.md +188 -38
  20. package/dist/docs/onto//350/204/232/346/234/254/350/277/220/350/241/214/347/272/240/351/224/231_/345/225/206/345/212/241/346/210/220/346/234/254/346/226/271/346/241/210/345/274/200/345/217/221/350/277/207/347/250/213.md +213 -0
  21. package/dist/docs/onto//350/247/204/345/210/222/347/244/272/344/276/213_/344/272/247/345/223/201/351/224/200/345/224/256/346/234/254/344/275/223/350/247/204/345/210/222/346/226/271/346/241/210.md +620 -0
  22. package/dist/docs/onto//350/247/204/345/210/222/347/244/272/344/276/213_/345/210/251/346/266/246/345/210/206/346/236/220/346/234/254/344/275/223/346/226/271/346/241/210.md +680 -541
  23. package/dist/examples/index.json +208 -22
  24. package/dist/examples/onto/README.md +51 -0
  25. package/dist/examples/onto/_templates/ontology_function_template.py +50 -0
  26. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_account_breakdown.py +62 -0
  27. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_budget_vs_actual.py +69 -0
  28. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_cost_center_profit.py +64 -0
  29. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_get_summary.py +61 -0
  30. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_mom_analysis.py +82 -0
  31. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_top_accounts.py +61 -0
  32. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_yoy_analysis.py +79 -0
  33. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/save_test_arguments.ps1 +38 -0
  34. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.account_breakdown.json +1 -0
  35. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.budget_vs_actual.json +1 -0
  36. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.cost_center_profit.json +1 -0
  37. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.get_summary.json +1 -0
  38. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.mom_analysis.json +1 -0
  39. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.top_accounts.json +1 -0
  40. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.yoy_analysis.json +1 -0
  41. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_ontology_init.py +679 -0
  42. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_seed_data.py +216 -0
  43. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_channel_mix.py +89 -0
  44. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_customer_segmentation.py +121 -0
  45. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_get_summary.py +78 -0
  46. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_mom_analysis.py +89 -0
  47. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_region_breakdown.py +84 -0
  48. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_top_products.py +98 -0
  49. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_yoy_analysis.py +87 -0
  50. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/save_test_arguments.ps1 +38 -0
  51. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.channel_mix.json +5 -0
  52. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.customer_segmentation.json +5 -0
  53. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.get_summary.json +5 -0
  54. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.mom_analysis.json +5 -0
  55. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.region_breakdown.json +5 -0
  56. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.top_products.json +5 -0
  57. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.yoy_analysis.json +5 -0
  58. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_ontology_init.py +539 -0
  59. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_seed_data.py +163 -0
  60. package/dist/prompts/index.json +2 -2
  61. package/dist/prompts/onto/action-design.md +4 -1
  62. package/dist/prompts/onto/function-design.md +46 -19
  63. package/dist/prompts/onto/rule-seed.md +5 -1
  64. package/dist/prompts/onto/script-publish-run.md +87 -25
  65. package/package.json +1 -1
  66. package/dist/examples/onto/function/profit_fn_customer_segmentation.py +0 -117
  67. package/dist/examples/onto/function/profit_fn_mom_analysis.py +0 -89
  68. package/dist/examples/onto/function/profit_fn_top_products.py +0 -89
  69. package/dist/examples/onto/function/profit_fn_yoy_analysis.py +0 -89
  70. package/dist/examples/onto/setup/profit_ontology_init.py +0 -388
@@ -0,0 +1,84 @@
1
+ """区域销售分布 sales.fn.region_breakdown
2
+
3
+ 参数:start_date, end_date
4
+ 返回:各区域销售额、销量、订单数及占比
5
+
6
+ 发布:
7
+ dazi onto script publish 项目/DAZI_TEST/本体/ontos/销售本体示例/functions/sales_fn_region_breakdown.py \
8
+ --space space__misc_01 --register-function-id sales.fn.region_breakdown
9
+ """
10
+
11
+ TEST_ARGUMENTS = {
12
+ "v": 1,
13
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
14
+ "object_type_code": "SalesAnalysis",
15
+ }
16
+
17
+
18
+ def _build_where(start_date, end_date):
19
+ clauses = ["order_status IN ('已完成', '已发货')"]
20
+ if start_date and end_date:
21
+ clauses.append(f"order_date >= '{start_date}' AND order_date <= '{end_date}'")
22
+ return "WHERE " + " AND ".join(clauses)
23
+
24
+
25
+ def _ontology_fn_body(p):
26
+ params = dict(p.get_params() or {})
27
+ start_date = params.get("start_date", "")
28
+ end_date = params.get("end_date", "")
29
+ where_clause = _build_where(start_date, end_date)
30
+
31
+ sql = f"""
32
+ SELECT
33
+ customer_region,
34
+ sum(sales_amount) AS sales_amount,
35
+ sum(quantity) AS quantity,
36
+ uniq(order_id) AS order_count
37
+ FROM fact_sales_order_line
38
+ {where_clause}
39
+ GROUP BY customer_region
40
+ ORDER BY sales_amount DESC
41
+ """
42
+
43
+ result = p.sql.query(sql)
44
+ if not result:
45
+ return p.function_result(
46
+ columns=["customer_region", "sales_amount", "quantity", "order_count", "share_pct"],
47
+ data=[],
48
+ row_count=0,
49
+ )
50
+
51
+ total = sum(float(r.get("sales_amount", 0) or 0) for r in result)
52
+
53
+ data = []
54
+ for row in result:
55
+ sales_amount = float(row.get("sales_amount", 0) or 0)
56
+ share_pct = sales_amount / total if total > 0 else 0.0
57
+ data.append({
58
+ "customer_region": str(row.get("customer_region", "")),
59
+ "sales_amount": round(sales_amount, 2),
60
+ "quantity": int(row.get("quantity", 0) or 0),
61
+ "order_count": int(row.get("order_count", 0) or 0),
62
+ "share_pct": round(share_pct, 4),
63
+ })
64
+
65
+ return p.function_result(
66
+ columns=["customer_region", "sales_amount", "quantity", "order_count", "share_pct"],
67
+ data=data,
68
+ row_count=len(data),
69
+ )
70
+
71
+
72
+ def main():
73
+ s = space.get(ctx.space_id or "")
74
+ _Ports = type(
75
+ "_Ports",
76
+ (),
77
+ {
78
+ "get_params": lambda self: dict(ctx.params or {}),
79
+ "function_result": lambda self, **kw: onto.function_result(**kw),
80
+ },
81
+ )
82
+ p = _Ports()
83
+ p.sql = s.sql
84
+ return _ontology_fn_body(p)
@@ -0,0 +1,98 @@
1
+ """产品销量/销售额排行 sales.fn.top_products
2
+
3
+ 参数:limit, metric(sales_amount|quantity), start_date, end_date
4
+ 返回:产品排行及销售占比
5
+
6
+ 发布:
7
+ dazi onto script publish 项目/DAZI_TEST/本体/ontos/销售本体示例/functions/sales_fn_top_products.py \
8
+ --space space__misc_01 --register-function-id sales.fn.top_products
9
+ """
10
+
11
+ TEST_ARGUMENTS = {
12
+ "v": 1,
13
+ "arguments": {
14
+ "limit": 5,
15
+ "metric": "sales_amount",
16
+ "start_date": "2025-01-01",
17
+ "end_date": "2026-06-30",
18
+ },
19
+ "object_type_code": "Product",
20
+ }
21
+
22
+
23
+ def _build_where(start_date, end_date):
24
+ clauses = ["f.order_status IN ('已完成', '已发货')"]
25
+ if start_date and end_date:
26
+ clauses.append(f"f.order_date >= '{start_date}' AND f.order_date <= '{end_date}'")
27
+ return "WHERE " + " AND ".join(clauses)
28
+
29
+
30
+ def _ontology_fn_body(p):
31
+ params = dict(p.get_params() or {})
32
+ limit = int(params.get("limit", 10) or 10)
33
+ metric = params.get("metric", "sales_amount")
34
+ start_date = params.get("start_date", "")
35
+ end_date = params.get("end_date", "")
36
+ where_clause = _build_where(start_date, end_date)
37
+ order_by = "quantity DESC" if metric == "quantity" else "sales_amount DESC"
38
+
39
+ sql = f"""
40
+ SELECT
41
+ f.product_id,
42
+ any(dp.product_name) AS product_name,
43
+ f.product_category,
44
+ sum(f.sales_amount) AS sales_amount,
45
+ sum(f.quantity) AS quantity
46
+ FROM fact_sales_order_line AS f
47
+ LEFT JOIN dim_product AS dp ON f.product_id = dp.product_id
48
+ {where_clause}
49
+ GROUP BY f.product_id, f.product_category
50
+ ORDER BY {order_by}
51
+ LIMIT {limit}
52
+ """
53
+
54
+ result = p.sql.query(sql)
55
+ if not result:
56
+ return p.function_result(
57
+ columns=["rank", "product_id", "product_name", "product_category", "sales_amount", "quantity", "share_pct"],
58
+ data=[],
59
+ row_count=0,
60
+ )
61
+
62
+ total_key = "quantity" if metric == "quantity" else "sales_amount"
63
+ total = sum(float(r.get(total_key, 0) or 0) for r in result)
64
+
65
+ data = []
66
+ for rank, row in enumerate(result, start=1):
67
+ val = float(row.get(total_key, 0) or 0)
68
+ share_pct = val / total if total > 0 else 0.0
69
+ data.append({
70
+ "rank": rank,
71
+ "product_id": str(row.get("product_id", "")),
72
+ "product_name": str(row.get("product_name", "")),
73
+ "product_category": str(row.get("product_category", "")),
74
+ "sales_amount": round(float(row.get("sales_amount", 0) or 0), 2),
75
+ "quantity": int(row.get("quantity", 0) or 0),
76
+ "share_pct": round(share_pct, 4),
77
+ })
78
+
79
+ return p.function_result(
80
+ columns=["rank", "product_id", "product_name", "product_category", "sales_amount", "quantity", "share_pct"],
81
+ data=data,
82
+ row_count=len(data),
83
+ )
84
+
85
+
86
+ def main():
87
+ s = space.get(ctx.space_id or "")
88
+ _Ports = type(
89
+ "_Ports",
90
+ (),
91
+ {
92
+ "get_params": lambda self: dict(ctx.params or {}),
93
+ "function_result": lambda self, **kw: onto.function_result(**kw),
94
+ },
95
+ )
96
+ p = _Ports()
97
+ p.sql = s.sql
98
+ return _ontology_fn_body(p)
@@ -0,0 +1,87 @@
1
+ """年度同比分析 sales.fn.yoy_analysis
2
+
3
+ 参数:start_date, end_date
4
+ 返回:年度销售额、销量、订单数及同比增长率
5
+
6
+ 发布:
7
+ dazi onto script publish 项目/DAZI_TEST/本体/ontos/销售本体示例/functions/sales_fn_yoy_analysis.py \
8
+ --space space__misc_01 --register-function-id sales.fn.yoy_analysis
9
+ """
10
+
11
+ TEST_ARGUMENTS = {
12
+ "v": 1,
13
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
14
+ "object_type_code": "SalesAnalysis",
15
+ }
16
+
17
+
18
+ def _build_where(start_date, end_date):
19
+ clauses = ["order_status IN ('已完成', '已发货')"]
20
+ if start_date and end_date:
21
+ clauses.append(f"order_date >= '{start_date}' AND order_date <= '{end_date}'")
22
+ return "WHERE " + " AND ".join(clauses)
23
+
24
+
25
+ def _ontology_fn_body(p):
26
+ params = dict(p.get_params() or {})
27
+ start_date = params.get("start_date", "")
28
+ end_date = params.get("end_date", "")
29
+ where_clause = _build_where(start_date, end_date)
30
+
31
+ sql = f"""
32
+ SELECT
33
+ toYear(order_date) AS year,
34
+ sum(sales_amount) AS sales_amount,
35
+ sum(quantity) AS quantity,
36
+ uniq(order_id) AS order_count
37
+ FROM fact_sales_order_line
38
+ {where_clause}
39
+ GROUP BY toYear(order_date)
40
+ ORDER BY year
41
+ """
42
+
43
+ result = p.sql.query(sql)
44
+ if not result:
45
+ return p.function_result(
46
+ columns=["year", "sales_amount", "quantity", "order_count", "yoy_growth"],
47
+ data=[],
48
+ row_count=0,
49
+ )
50
+
51
+ data = []
52
+ prev_sales = None
53
+ for row in result:
54
+ sales_amount = float(row.get("sales_amount", 0) or 0)
55
+ if prev_sales is not None and prev_sales != 0:
56
+ yoy_growth = (sales_amount - prev_sales) / prev_sales
57
+ else:
58
+ yoy_growth = 0.0
59
+ data.append({
60
+ "year": int(row.get("year", 0)),
61
+ "sales_amount": round(sales_amount, 2),
62
+ "quantity": int(row.get("quantity", 0) or 0),
63
+ "order_count": int(row.get("order_count", 0) or 0),
64
+ "yoy_growth": round(yoy_growth, 4),
65
+ })
66
+ prev_sales = sales_amount
67
+
68
+ return p.function_result(
69
+ columns=["year", "sales_amount", "quantity", "order_count", "yoy_growth"],
70
+ data=data,
71
+ row_count=len(data),
72
+ )
73
+
74
+
75
+ def main():
76
+ s = space.get(ctx.space_id or "")
77
+ _Ports = type(
78
+ "_Ports",
79
+ (),
80
+ {
81
+ "get_params": lambda self: dict(ctx.params or {}),
82
+ "function_result": lambda self, **kw: onto.function_result(**kw),
83
+ },
84
+ )
85
+ p = _Ports()
86
+ p.sql = s.sql
87
+ return _ontology_fn_body(p)
@@ -0,0 +1,38 @@
1
+ # save_test_arguments.ps1
2
+ # 批量保存各函数的 test_arguments
3
+ # 用法:在 dazi-work 根目录执行 .\项目\DAZI_TEST\本体\ontos\销售本体示例\functions\save_test_arguments.ps1
4
+
5
+ $spaceId = "space__misc_01"
6
+ $itemPath = "项目/DAZI_TEST/本体/ontos/销售本体示例/functions"
7
+
8
+ $functions = @(
9
+ @{fn_id="sales.fn.get_summary"; file="sales.fn.get_summary.json"},
10
+ @{fn_id="sales.fn.yoy_analysis"; file="sales.fn.yoy_analysis.json"},
11
+ @{fn_id="sales.fn.mom_analysis"; file="sales.fn.mom_analysis.json"},
12
+ @{fn_id="sales.fn.top_products"; file="sales.fn.top_products.json"},
13
+ @{fn_id="sales.fn.customer_segmentation"; file="sales.fn.customer_segmentation.json"},
14
+ @{fn_id="sales.fn.region_breakdown"; file="sales.fn.region_breakdown.json"},
15
+ @{fn_id="sales.fn.channel_mix"; file="sales.fn.channel_mix.json"}
16
+ )
17
+
18
+ # 先获取 function list 获取 ofn_xxx 内部 id
19
+ Write-Host "获取函数列表..."
20
+ $fnList = & dazi onto function list --space $spaceId --output json 2>$null | ConvertFrom-Json
21
+
22
+ foreach ($fn in $functions) {
23
+ $fnId = $fn.fn_id
24
+ $fileName = $fn.file
25
+ $jsonPath = "$PSScriptRoot/test_arguments/$fileName"
26
+
27
+ # 查找 ofn_xxx 内部 id
28
+ $fnInfo = $fnList | Where-Object { $_.function_id -eq $fnId }
29
+ if ($fnInfo) {
30
+ $ofnId = $fnInfo.id
31
+ Write-Host "保存 $fnId (ofnId=$ofnId)..."
32
+ & dazi onto function save-test-arguments $ofnId --space $spaceId --arguments-json-file $jsonPath
33
+ } else {
34
+ Write-Host "函数 $fnId 未找到,请先发布函数"
35
+ }
36
+ }
37
+
38
+ Write-Host "完成"
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "SalesAnalysis"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"metric": "sales_amount", "method": "quartile", "start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "Customer"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "SalesAnalysis"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "SalesAnalysis"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "SalesAnalysis"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"limit": 5, "metric": "sales_amount", "start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "Product"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "v": 1,
3
+ "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30"},
4
+ "object_type_code": "SalesAnalysis"
5
+ }