@liuhange/dsh-gov-data-inspector 3.1.0
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.
- package/README.md +22 -0
- package/lib/index.js +123 -0
- package/lib/policyBasis.js +17 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @liuhange/dsh-gov-data-inspector
|
|
2
|
+
|
|
3
|
+
## 功能说明
|
|
4
|
+
|
|
5
|
+
Government data inspection plugin: service guide quality check and public data asset classification
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
dsh plugin --profile web add @liuhange/dsh-gov-data-inspector
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 用法
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { apply } from '@liuhange/dsh-gov-data-inspector';
|
|
17
|
+
apply(ctx); // 注册工具: inspect_gov_data
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
MIT
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export const name = '@liuhange/dsh-gov-data-inspector';
|
|
2
|
+
export const inject = ['tools'];
|
|
3
|
+
import { loadJsonConfig } from '@liuhange/dsh-data-asset-shared';
|
|
4
|
+
import { resolvePolicyBasis } from './policyBasis.js';
|
|
5
|
+
export function apply(ctx) {
|
|
6
|
+
ctx.tools.register({
|
|
7
|
+
name: 'inspect_gov_data',
|
|
8
|
+
description: '政务数据专项巡检,含办事指南质量检查和公共数据资产分类',
|
|
9
|
+
parameters: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
dataSource: { type: 'string', description: '政务数据文件路径' },
|
|
13
|
+
inspectionMode: { type: 'string', enum: ['guide', 'classification', 'full'] },
|
|
14
|
+
},
|
|
15
|
+
required: ['dataSource'],
|
|
16
|
+
},
|
|
17
|
+
async execute(args) {
|
|
18
|
+
try {
|
|
19
|
+
if (!args?.dataSource || typeof args.dataSource !== 'string') {
|
|
20
|
+
return JSON.stringify({ error: 'GOV_DATA_INPUT_INVALID', message: 'dataSource is required' });
|
|
21
|
+
}
|
|
22
|
+
let rulesConfig;
|
|
23
|
+
try {
|
|
24
|
+
rulesConfig = loadJsonConfig('BUSINESS_RULES_PATH', 'config/business-rules.json', '@liuhange/dsh-data-asset-shared/config/business-rules.json');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return JSON.stringify({ error: 'GOV_DATA_RULES_MISSING', message: '无法加载business-rules.json' });
|
|
28
|
+
}
|
|
29
|
+
const govConfig = rulesConfig.govDataInspection;
|
|
30
|
+
if (!govConfig) {
|
|
31
|
+
return JSON.stringify({ error: 'GOV_DATA_RULES_MISSING', message: 'govDataInspection配置段缺失' });
|
|
32
|
+
}
|
|
33
|
+
let data;
|
|
34
|
+
try {
|
|
35
|
+
const { readFileSync } = await import('node:fs');
|
|
36
|
+
const raw = readFileSync(args.dataSource, 'utf-8');
|
|
37
|
+
data = JSON.parse(raw);
|
|
38
|
+
if (!Array.isArray(data))
|
|
39
|
+
data = [data];
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return JSON.stringify({ error: 'GOV_DATA_INPUT_INVALID', message: `无法加载数据: ${args.dataSource}` });
|
|
43
|
+
}
|
|
44
|
+
const mode = args.inspectionMode ?? 'full';
|
|
45
|
+
const policyBasis = resolvePolicyBasis('GOV_DATA_INSPECTION');
|
|
46
|
+
const result = {
|
|
47
|
+
dataSource: args.dataSource,
|
|
48
|
+
inspectionMode: mode,
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
policyBasis,
|
|
51
|
+
};
|
|
52
|
+
if (mode === 'guide' || mode === 'full') {
|
|
53
|
+
result.guideInspection = inspectGuides(data, govConfig.guideRequiredElements, govConfig.convenienceWeights);
|
|
54
|
+
}
|
|
55
|
+
if (mode === 'classification' || mode === 'full') {
|
|
56
|
+
result.classification = classifyGovData(data, govConfig.gbt47949Mapping);
|
|
57
|
+
}
|
|
58
|
+
return JSON.stringify(result, null, 2);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return JSON.stringify({ error: 'UNKNOWN_ERROR', message: e.message });
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function inspectGuides(data, requiredElements, weights) {
|
|
67
|
+
let completeCount = 0;
|
|
68
|
+
let semanticErrors = 0;
|
|
69
|
+
let logicalErrors = 0;
|
|
70
|
+
let serviceConvenience = 0;
|
|
71
|
+
for (const row of data) {
|
|
72
|
+
if (typeof row === 'object' && row !== null) {
|
|
73
|
+
const obj = row;
|
|
74
|
+
let hasAllElements = true;
|
|
75
|
+
for (const elem of requiredElements) {
|
|
76
|
+
if (!obj[elem]) {
|
|
77
|
+
hasAllElements = false;
|
|
78
|
+
semanticErrors++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (hasAllElements)
|
|
82
|
+
completeCount++;
|
|
83
|
+
if (obj.timeLimit && typeof obj.timeLimit === 'string' && obj.timeLimit.includes('工作日')) {
|
|
84
|
+
serviceConvenience += weights.timeLimit ?? 0.3;
|
|
85
|
+
}
|
|
86
|
+
if (obj.onlineCapable === true) {
|
|
87
|
+
serviceConvenience += weights.onlineCapable ?? 0.4;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
completeness: data.length > 0 ? Math.round((completeCount / data.length) * 100) : 0,
|
|
93
|
+
semanticErrors,
|
|
94
|
+
logicalErrors,
|
|
95
|
+
serviceConvenience: Math.round(serviceConvenience * 100) / 100,
|
|
96
|
+
totalGuidesChecked: data.length,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function classifyGovData(data, gbtMapping) {
|
|
100
|
+
let structured = 0, semiStructured = 0, unstructured = 0;
|
|
101
|
+
for (const row of data) {
|
|
102
|
+
if (Array.isArray(row) || (typeof row === 'object' && row !== null)) {
|
|
103
|
+
const keys = Object.keys(row);
|
|
104
|
+
if (keys.every((k) => /^[a-zA-Z_]+$/.test(k)))
|
|
105
|
+
structured++;
|
|
106
|
+
else if (keys.length > 0)
|
|
107
|
+
semiStructured++;
|
|
108
|
+
else
|
|
109
|
+
unstructured++;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
unstructured++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const dominant = structured >= semiStructured && structured >= unstructured ? 'structured' : semiStructured >= unstructured ? 'semi-structured' : 'unstructured';
|
|
116
|
+
const codeKey = dominant === 'structured' ? 'structured' : dominant === 'semi-structured' ? 'semiStructured' : 'unstructured';
|
|
117
|
+
return {
|
|
118
|
+
dataAssetCode: gbtMapping[codeKey] ?? 'A00',
|
|
119
|
+
categoryLevel: dominant,
|
|
120
|
+
specificType: '政务数据',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { loadJsonConfig } from '@liuhange/dsh-data-asset-shared';
|
|
2
|
+
export function resolvePolicyBasis(stage) {
|
|
3
|
+
try {
|
|
4
|
+
const config = loadJsonConfig('POLICY_REFS_PATH', 'config/policy-references.json', '@liuhange/dsh-data-asset-shared/config/policy-references.json');
|
|
5
|
+
const refs = config.policyReferences;
|
|
6
|
+
const stageEntry = refs?.find((s) => s.stage === stage);
|
|
7
|
+
if (!stageEntry) {
|
|
8
|
+
console.warn(`Policy stage "${stage}" not configured`);
|
|
9
|
+
return [`依据:政策依据未配置(stage=${stage})`];
|
|
10
|
+
}
|
|
11
|
+
return stageEntry.documents.map((d) => `依据:《${d.name}》(${d.docNumber})—${d.coreRequirement}`);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return ['依据:政策依据配置加载失败'];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=policyBasis.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liuhange/dsh-gov-data-inspector",
|
|
3
|
+
"description": "Government data inspection plugin: service guide quality check and public data asset classification",
|
|
4
|
+
"version": "3.1.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/liuhange789/data-asset-inspector.git",
|
|
11
|
+
"directory": "packages/data-asset/gov-data-inspector"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./src/*": "./src/*",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"lib/**/*.js",
|
|
26
|
+
"lib/types/**/*.d.ts"
|
|
27
|
+
],
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"build": "tsc"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@deepseek-ai/cordis": "^4.0.0",
|
|
36
|
+
"@deepseek-ai/dsh-tools": "0.0.1-rc.1",
|
|
37
|
+
"@liuhange/dsh-data-asset-shared": "^3.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dsh": {
|
|
40
|
+
"bundle": {
|
|
41
|
+
"patch": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"deepseek-harness",
|
|
46
|
+
"dsh-plugin",
|
|
47
|
+
"data-asset",
|
|
48
|
+
"data-asset-inspector",
|
|
49
|
+
"shujintong",
|
|
50
|
+
"数据资产",
|
|
51
|
+
"gov-data",
|
|
52
|
+
"public-data",
|
|
53
|
+
"service-guide",
|
|
54
|
+
"gbt-47949",
|
|
55
|
+
"政务数据",
|
|
56
|
+
"公共数据",
|
|
57
|
+
"办事指南"
|
|
58
|
+
],
|
|
59
|
+
"homepage": "https://github.com/liuhange789/data-asset-inspector#readme"
|
|
60
|
+
}
|