docs(contract): 为所有 API 的 input/output 添加 OpenAPI examples,便于厂商测试

This commit is contained in:
2026-03-06 14:37:50 +08:00
parent 86754f73c1
commit ec41a4cfc7
2 changed files with 132 additions and 32 deletions

View File

@@ -1,10 +1,23 @@
import { oc } from '@orpc/contract' import { oc } from '@orpc/contract'
import { z } from 'zod' import { z } from 'zod'
const configOutput = z.object({ const configOutput = z
licence: z.string().nullable().describe('当前本地 licence未设置时为 null'), .object({
fingerprint: z.string().describe('UX 本机计算得到的 fingerprint'), licence: z.string().nullable().describe('当前本地 licence未设置时为 null'),
}) fingerprint: z.string().describe('UX 本机计算得到的设备特征码SHA-256'),
})
.meta({
examples: [
{
licence: 'LIC-8F2A-XXXX',
fingerprint: '9a3b7c1d2e4f5a6b8c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b',
},
{
licence: null,
fingerprint: '9a3b7c1d2e4f5a6b8c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b',
},
],
})
export const get = oc export const get = oc
.route({ .route({
@@ -30,8 +43,12 @@ export const setLicence = oc
tags: ['Config'], tags: ['Config'],
}) })
.input( .input(
z.object({ z
licence: z.string().min(1).describe('本地持久化的 licence'), .object({
}), licence: z.string().min(1).describe('本地持久化的 licence'),
})
.meta({
examples: [{ licence: 'LIC-8F2A-XXXX' }],
}),
) )
.output(configOutput) .output(configOutput)

View File

@@ -12,14 +12,31 @@ export const encryptDeviceInfo = oc
tags: ['Crypto'], tags: ['Crypto'],
}) })
.input( .input(
z.object({ z
platformPublicKey: z.string().min(1).describe('平台公钥Base64SPKI DER'), .object({
}), platformPublicKey: z.string().min(1).describe('平台公钥Base64SPKI DER'),
})
.meta({
examples: [
{
platformPublicKey:
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzDlZvMDVaL+fjl05Hi182JOAUAaN4gh9rOF+1NhKfO4J6e0HLy8lBuylp3A4xoTiyUejNm22h0dqAgDSPnY/xZR76POFTD1soHr2LaFCN8JAbQ96P8gE7wC9qpoTssVvIVRH7QbVd260J6eD0Szwcx9cg591RSN69pMpe5IVRi8T99Hhql6/wnZHORPr18eESLOY93jRskLzc0q18r68RRoTJiQf+9YC8ub5iKp7rCjVnPi1UbIYmXmL08tk5mksYA0NqWQAa1ofKxx/9tQtB9uTjhTxuTu94XU9jlGU87qaHZs+kpqa8CAbYYJFbSP1xHwoZzpU2jpw2aF22HBYxwIDAQAB',
},
],
}),
) )
.output( .output(
z.object({ z
encrypted: z.string().describe('Base64 密文(用于设备授权二维码)'), .object({
}), encrypted: z.string().describe('Base64 密文(用于设备授权二维码)'),
})
.meta({
examples: [
{
encrypted: 'dGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIFJTQS1PQUVQIGVuY3J5cHRlZCBkZXZpY2UgaW5mby4uLg==',
},
],
}),
) )
export const decryptTask = oc export const decryptTask = oc
@@ -33,14 +50,31 @@ export const decryptTask = oc
tags: ['Crypto'], tags: ['Crypto'],
}) })
.input( .input(
z.object({ z
encryptedData: z.string().min(1).describe('Base64 密文'), .object({
}), encryptedData: z.string().min(1).describe('Base64 编码的 AES-256-GCM 密文(来自任务二维码扫描结果)'),
})
.meta({
examples: [
{
encryptedData: 'uWUcAmp6UQd0w3G3crdsd4613QCxGLoEgslgXJ4G2hQhpQdjtghtQjCBUZwB/JO+NRgH1vSTr8dqBJRq7Qh4nug==',
},
],
}),
) )
.output( .output(
z.object({ z
decrypted: z.string().describe('解密后的 UTF-8 明文字符串'), .object({
}), decrypted: z.string().describe('解密后的任务信息 JSON 字符串'),
})
.meta({
examples: [
{
decrypted:
'{"taskId":"TASK-20260115-4875","enterpriseId":"1173040813421105152","orgName":"超艺科技有限公司","inspectionId":"702286470691215417","inspectionPerson":"警务通","issuedAt":1734571234567}',
},
],
}),
) )
export const encryptSummary = oc export const encryptSummary = oc
@@ -54,15 +88,33 @@ export const encryptSummary = oc
tags: ['Crypto'], tags: ['Crypto'],
}) })
.input( .input(
z.object({ z
salt: z.string().min(1).describe('HKDF salt例如 taskId'), .object({
plaintext: z.string().min(1).describe('待加密明文'), salt: z.string().min(1).describe('HKDF salt即 taskId从任务二维码中获取'),
}), plaintext: z.string().min(1).describe('待加密的摘要信息 JSON 明文'),
})
.meta({
examples: [
{
salt: 'TASK-20260115-4875',
plaintext:
'{"enterpriseId":"1173040813421105152","inspectionId":"702286470691215417","summary":"检查摘要信息发现3个高危漏洞5个中危漏洞","timestamp":1734571234567}',
},
],
}),
) )
.output( .output(
z.object({ z
encrypted: z.string().describe('Base64 密文'), .object({
}), encrypted: z.string().describe('Base64 密文(用于摘要信息二维码)'),
})
.meta({
examples: [
{
encrypted: 'uWUcAmp6UQd0w3G3crdsd4613QCxGLoEgslgXJ4G2hQhpQdjtghtQjCBUZwB/JO+NRgH1vSTr8dqBJRq7Qh4nug==',
},
],
}),
) )
export const signAndPackReport = oc export const signAndPackReport = oc
@@ -77,14 +129,45 @@ export const signAndPackReport = oc
}) })
.input( .input(
z.object({ z.object({
pgpPrivateKey: z.string().min(1).describe('OpenPGP 私钥ASCII armored'), pgpPrivateKey: z
signingContext: z.string().min(1).describe('签名上下文字符串(由调用方定义)'), .string()
summaryJson: z.string().min(1).describe('summary.json 的完整 JSON 文本'), .min(1)
outputFileName: z.string().min(1).optional().describe('返回 ZIP 文件名(可选'), .describe('OpenPGP 私钥ASCII armored')
.meta({
examples: ['-----BEGIN PGP PRIVATE KEY BLOCK-----\n\nxcMGBGd...\n-----END PGP PRIVATE KEY BLOCK-----'],
}),
signingContext: z
.string()
.min(1)
.describe('签名上下文字符串(通常为 taskId + inspectionId 拼接)')
.meta({
examples: ['TASK-20260115-4875702286470691215417'],
}),
summaryJson: z
.string()
.min(1)
.describe('summary.json 的完整 JSON 文本(包含 orgId、checkId、taskId 等业务字段)')
.meta({
examples: [
'{"orgId":1173040813421105152,"checkId":702286470691215417,"taskId":"TASK-20260115-4875","summary":"检查摘要信息"}',
],
}),
outputFileName: z
.string()
.min(1)
.optional()
.describe('返回 ZIP 文件名(可选,默认 signed-report.zip')
.meta({ examples: ['signed-report.zip'] }),
rawZip: z rawZip: z
.file() .file()
.mime(['application/zip', 'application/x-zip-compressed']) .mime(['application/zip', 'application/x-zip-compressed'])
.describe('原始报告 ZIP 文件multipart/form-data 字段)'), .describe(
'原始报告 ZIP 文件multipart/form-data 字段,应包含 assets.json、vulnerabilities.json、weakPasswords.json、漏洞评估报告.html',
),
}), }),
) )
.output(z.file().describe('签名后报告 ZIP 文件(二进制响应)')) .output(
z
.file()
.describe('签名后报告 ZIP 文件(二进制响应,包含 summary.json、META-INF/manifest.json、META-INF/signature.asc'),
)