@h-ai/api-contract 0.1.0-alpha.67 → 0.1.0-alpha.69
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.en.md +30 -0
- package/README.ja.md +30 -0
- package/README.md +30 -0
- package/dist/ai/index.d.ts +981 -200
- package/dist/ai/index.js +2 -2
- package/dist/{chunk-RVSGP2GF.js → chunk-5XQIW67A.js} +6 -18
- package/dist/chunk-5XQIW67A.js.map +1 -0
- package/dist/chunk-CCCPHO6X.js +19 -0
- package/dist/chunk-CCCPHO6X.js.map +1 -0
- package/dist/{chunk-VSPYX4DD.js → chunk-G55ATYDA.js} +64 -39
- package/dist/chunk-G55ATYDA.js.map +1 -0
- package/dist/{chunk-3QSKWVLP.js → chunk-IVZVAWEF.js} +30 -17
- package/dist/chunk-IVZVAWEF.js.map +1 -0
- package/dist/{chunk-CUU2F6YD.js → chunk-JKPLID6E.js} +2 -2
- package/dist/chunk-JKPLID6E.js.map +1 -0
- package/dist/chunk-OQG36ECJ.js +140 -0
- package/dist/chunk-OQG36ECJ.js.map +1 -0
- package/dist/{chunk-JIQINMLG.js → chunk-R5GDWFYC.js} +7 -7
- package/dist/chunk-R5GDWFYC.js.map +1 -0
- package/dist/feedback/index.d.ts +1504 -0
- package/dist/feedback/index.js +5 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/iam/index.d.ts +845 -32
- package/dist/iam/index.js +3 -2
- package/dist/index.d.ts +855 -90
- package/dist/index.js +17 -11
- package/dist/index.js.map +1 -1
- package/dist/payment/index.d.ts +220 -30
- package/dist/payment/index.js +2 -2
- package/dist/storage/index.d.ts +414 -161
- package/dist/storage/index.js +2 -2
- package/package.json +8 -3
- package/dist/chunk-3QSKWVLP.js.map +0 -1
- package/dist/chunk-CUU2F6YD.js.map +0 -1
- package/dist/chunk-JIQINMLG.js.map +0 -1
- package/dist/chunk-RVSGP2GF.js.map +0 -1
- package/dist/chunk-VSPYX4DD.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/storage/storage-schemas.ts","../src/storage/storage-contract.ts"],"names":["z"],"mappings":"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","file":"chunk-IVZVAWEF.js","sourcesContent":["/**\n * @h-ai/api-contract — Storage 领域 Schema\n *\n * 包含文件元数据、预签名 URL、文件列表与删除相关的 input/output Zod Schema。\n * 仅保留跨接口、跨层复用的数据结构;一次性输出包装在 contract 中内联。\n * @module storage-schemas\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { StorageDeleteKeysSchema, StorageKeySchema, StoragePrefixSchema, StoragePresignExpiresInSchema } from '@h-ai/storage/schemas'\nimport { z } from 'zod'\n\n/**\n * 文件元数据 Schema。\n * @example\n * ```ts\n * import { StorageFileMetadataSchema } from '@h-ai/api-contract'\n *\n * const value = StorageFileMetadataSchema.parse({\n * key: 'examples/readme.txt',\n * size: 0,\n * contentType: 'example',\n * lastModified: null\n * })\n * void value\n * ```\n */\nexport const StorageFileMetadataSchema = z.object({\n key: z.string(),\n size: z.number(),\n contentType: z.string(),\n lastModified: z.coerce.date(),\n etag: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n})\n\n/**\n * 获取下载签名 URL 入参 Schema。\n * @example\n * ```ts\n * import { StoragePresignDownloadInputSchema } from '@h-ai/api-contract'\n *\n * const value = StoragePresignDownloadInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport const StoragePresignDownloadInputSchema = z.strictObject({\n key: StorageKeySchema,\n expiresIn: StoragePresignExpiresInSchema.optional(),\n})\n\n/**\n * 获取上传签名 URL 入参 Schema。\n * @example\n * ```ts\n * import { StoragePresignUploadInputSchema } from '@h-ai/api-contract'\n *\n * const value = StoragePresignUploadInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport const StoragePresignUploadInputSchema = z.strictObject({\n key: StorageKeySchema,\n contentType: z.string().optional(),\n expiresIn: StoragePresignExpiresInSchema.optional(),\n})\n\n/**\n * 签名 URL 业务数据 Schema。\n * @example\n * ```ts\n * import { StoragePresignedUrlSchema } from '@h-ai/api-contract'\n *\n * const value = StoragePresignedUrlSchema.parse({\n * url: 'https://example.com/resource',\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport const StoragePresignedUrlSchema = z.object({\n url: z.string(),\n key: z.string(),\n expiresAt: z.coerce.date().optional(),\n})\n\n/**\n * 文件列表查询入参 Schema。\n * @example\n * ```ts\n * import { StorageListFilesInputSchema } from '@h-ai/api-contract'\n *\n * const value = StorageListFilesInputSchema.parse({})\n * void value\n * ```\n */\nexport const StorageListFilesInputSchema = z.object({\n prefix: StoragePrefixSchema.optional(),\n maxKeys: z.coerce.number().int().min(1).max(1000).optional(),\n continuationToken: z.string().optional(),\n delimiter: z.string().optional(),\n})\n\n/**\n * 文件列表业务数据 Schema。\n * @example\n * ```ts\n * import { StorageListFilesDataSchema } from '@h-ai/api-contract'\n *\n * const value = StorageListFilesDataSchema.parse({\n * files: [\n * {\n * key: 'examples/readme.txt',\n * size: 0,\n * contentType: 'example',\n * lastModified: null\n * }\n * ],\n * commonPrefixes: [\n * 'example'\n * ],\n * isTruncated: true\n * })\n * void value\n * ```\n */\nexport const StorageListFilesDataSchema = z.object({\n files: z.array(StorageFileMetadataSchema),\n commonPrefixes: z.array(z.string()),\n nextContinuationToken: z.string().optional(),\n isTruncated: z.boolean(),\n})\n\n/**\n * 单文件操作入参 Schema。\n * @example\n * ```ts\n * import { StorageFileKeyInputSchema } from '@h-ai/api-contract'\n *\n * const value = StorageFileKeyInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport const StorageFileKeyInputSchema = z.object({\n key: StorageKeySchema,\n})\n\n/**\n * 批量删除文件入参 Schema。\n * @example\n * ```ts\n * import { StorageDeleteFilesInputSchema } from '@h-ai/api-contract'\n *\n * const value = StorageDeleteFilesInputSchema.parse({\n * keys: [\n * 'example'\n * ]\n * })\n * void value\n * ```\n */\nexport const StorageDeleteFilesInputSchema = z.object({\n keys: StorageDeleteKeysSchema,\n})\n\n/**\n * 批量删除的安全进度;响应失败时通过 error.ext.deleteMany 返回同一结构。\n * @example\n * ```ts\n * import { StorageDeleteSummarySchema } from '@h-ai/api-contract'\n *\n * const value = StorageDeleteSummarySchema.parse({\n * deletedKeys: [\n * 'example'\n * ],\n * failures: [\n * {\n * key: 'examples/readme.txt',\n * code: 'example-1',\n * retryable: true,\n * outcome: 'failed'\n * }\n * ]\n * })\n * void value\n * ```\n */\nexport const StorageDeleteSummarySchema = z.object({\n deletedKeys: z.array(z.string()),\n failures: z.array(z.object({\n key: z.string(),\n code: z.string(),\n retryable: z.boolean(),\n outcome: z.enum(['failed', 'unknown', 'notAttempted']),\n })),\n})\n\n/**\n * 为对象生成下载地址的请求。\n * @example\n * ```ts\n * import type { StoragePresignDownloadInput } from '@h-ai/api-contract'\n * import { StoragePresignDownloadInputSchema } from '@h-ai/api-contract'\n *\n * const value: StoragePresignDownloadInput = StoragePresignDownloadInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport type StoragePresignDownloadInput = z.infer<typeof StoragePresignDownloadInputSchema>\n/**\n * 为对象生成上传地址的请求。\n * @example\n * ```ts\n * import type { StoragePresignUploadInput } from '@h-ai/api-contract'\n * import { StoragePresignUploadInputSchema } from '@h-ai/api-contract'\n *\n * const value: StoragePresignUploadInput = StoragePresignUploadInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport type StoragePresignUploadInput = z.infer<typeof StoragePresignUploadInputSchema>\n/**\n * 以 HaiResult 区分成功业务数据和公共错误的 StoragePresignedUrlOutput 响应。\n * @example\n * ```ts\n * import type { StoragePresignedUrlOutput } from '@h-ai/api-contract'\n * import { StoragePresignedUrlSchema } from '@h-ai/api-contract'\n * import { ok } from '@h-ai/core'\n *\n * const response: StoragePresignedUrlOutput = ok(StoragePresignedUrlSchema.parse({\n * url: 'https://example.com/resource',\n * key: 'examples/readme.txt'\n * }))\n * if (response.success) void response.data\n * ```\n */\nexport type StoragePresignedUrlOutput = HaiResult<z.infer<typeof StoragePresignedUrlSchema>>\n/**\n * 按前缀和游标列出对象的请求。\n * @example\n * ```ts\n * import type { StorageListFilesInput } from '@h-ai/api-contract'\n * import { StorageListFilesInputSchema } from '@h-ai/api-contract'\n *\n * const value: StorageListFilesInput = StorageListFilesInputSchema.parse({})\n * void value\n * ```\n */\nexport type StorageListFilesInput = z.infer<typeof StorageListFilesInputSchema>\n/**\n * 以对象 key 定位文件的请求。\n * @example\n * ```ts\n * import type { StorageFileKeyInput } from '@h-ai/api-contract'\n * import { StorageFileKeyInputSchema } from '@h-ai/api-contract'\n *\n * const value: StorageFileKeyInput = StorageFileKeyInputSchema.parse({\n * key: 'examples/readme.txt'\n * })\n * void value\n * ```\n */\nexport type StorageFileKeyInput = z.infer<typeof StorageFileKeyInputSchema>\n/**\n * 批量删除指定对象 key 的请求。\n * @example\n * ```ts\n * import type { StorageDeleteFilesInput } from '@h-ai/api-contract'\n * import { StorageDeleteFilesInputSchema } from '@h-ai/api-contract'\n *\n * const value: StorageDeleteFilesInput = StorageDeleteFilesInputSchema.parse({\n * keys: [\n * 'example'\n * ]\n * })\n * void value\n * ```\n */\nexport type StorageDeleteFilesInput = z.infer<typeof StorageDeleteFilesInputSchema>\n","/**\n * @h-ai/api-contract — Storage 领域 contract\n *\n * 定义文件存储相关 API 的接口边界:预签名 URL 生成与文件管理。\n * 所有接口均需 Bearer Token 认证(由 `@h-ai/serv` 的 feature 层强制)。\n * 资源访问还须通过应用注入的 authorize 策略;认证不等同于拥有任意 key 的访问权。\n * @module storage-contract\n */\n\nimport { z } from 'zod'\nimport { HaiErrorSchema, haiResultSchema, HaiVoidResultSchema } from '../common/result-schemas.js'\nimport { route } from '../common/route.js'\nimport {\n StorageDeleteFilesInputSchema,\n StorageDeleteSummarySchema,\n StorageFileKeyInputSchema,\n StorageFileMetadataSchema,\n StorageListFilesDataSchema,\n StorageListFilesInputSchema,\n StoragePresignDownloadInputSchema,\n StoragePresignedUrlSchema,\n StoragePresignUploadInputSchema,\n} from './storage-schemas.js'\n\n// 下载与上传接口共享同一响应结构,仅在本 contract 内复用。\nconst presignedUrlOutputSchema = haiResultSchema(StoragePresignedUrlSchema)\n\n/**\n * Storage 领域 oRPC contract。\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const contract = apiContract.storage\n * void contract\n * ```\n */\nexport const storageContract = {\n presignedUrls: {\n createDownload: route({ method: 'POST', path: '/storage/presigned-urls/download', operationId: 'storage.presignedUrls.createDownload', summary: 'Create presigned download URL', tags: ['storage'] })\n .input(StoragePresignDownloadInputSchema)\n .output(presignedUrlOutputSchema),\n createUpload: route({ method: 'POST', path: '/storage/presigned-urls/upload', operationId: 'storage.presignedUrls.createUpload', summary: 'Create presigned upload URL', tags: ['storage'] })\n .input(StoragePresignUploadInputSchema)\n .output(presignedUrlOutputSchema),\n },\n files: {\n list: route({ method: 'GET', path: '/storage/files', operationId: 'storage.files.list', summary: 'List files', tags: ['storage'] })\n .input(StorageListFilesInputSchema)\n .output(haiResultSchema(StorageListFilesDataSchema)),\n getMetadata: route({ method: 'POST', path: '/storage/files/metadata', operationId: 'storage.files.getMetadata', summary: 'Get file metadata', tags: ['storage'] })\n .input(StorageFileKeyInputSchema)\n .output(haiResultSchema(StorageFileMetadataSchema)),\n delete: route({ method: 'DELETE', path: '/storage/files', operationId: 'storage.files.delete', summary: 'Delete file', tags: ['storage'] })\n .input(StorageFileKeyInputSchema)\n .output(HaiVoidResultSchema),\n deleteMany: route({ method: 'POST', path: '/storage/files/delete-many', operationId: 'storage.files.deleteMany', summary: 'Delete files', tags: ['storage'] })\n .input(StorageDeleteFilesInputSchema)\n .output(z.discriminatedUnion('success', [\n z.object({ success: z.literal(true), data: StorageDeleteSummarySchema }),\n z.object({\n success: z.literal(false),\n error: HaiErrorSchema.extend({ ext: z.object({ deleteMany: StorageDeleteSummarySchema.optional() }).catchall(z.unknown()).optional() }),\n }),\n ])),\n },\n}\n\n/**\n * storage 领域公开 procedure 契约的完整类型。\n * @example\n * ```ts\n * import type { StorageContract } from '@h-ai/api-contract'\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const contract: StorageContract = apiContract.storage\n * void contract\n * ```\n */\nexport type StorageContract = typeof storageContract\n"]}
|
|
@@ -34,5 +34,5 @@ function pathOf(procedure) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export { HaiErrorSchema, HaiVoidResultSchema, haiResultSchema, pathOf, route };
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
38
|
-
//# sourceMappingURL=chunk-
|
|
37
|
+
//# sourceMappingURL=chunk-JKPLID6E.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-JKPLID6E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/common/result-schemas.ts","../src/common/route.ts"],"names":[],"mappings":";;;;AA0BO,IAAM,cAAA,GAAiB,EAAE,MAAA,CAAO;AAAA,EACrC,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,QAAO,EAAG,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA;AAAA,EACtC,OAAA,EAAS,EAAE,MAAA,EAAO;AAAA,EAClB,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAChC,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC5B,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC5B,KAAA,EAAO,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC5B,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAChC,GAAA,EAAK,CAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA;AACzC,CAAC;AAiBM,SAAS,gBAAqC,UAAA,EAAe;AAClE,EAAA,OAAO,CAAA,CAAE,mBAAmB,SAAA,EAAW;AAAA,IACrC,EAAE,MAAA,CAAO;AAAA,MACP,OAAA,EAAS,CAAA,CAAE,OAAA,CAAQ,IAAI,CAAA;AAAA,MACvB,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,IACD,EAAE,MAAA,CAAO;AAAA,MACP,OAAA,EAAS,CAAA,CAAE,OAAA,CAAQ,KAAK,CAAA;AAAA,MACxB,KAAA,EAAO;AAAA,KACR;AAAA,GACF,CAAA;AACH;AAYO,IAAM,mBAAA,GAAsB,eAAA,CAAgB,CAAA,CAAE,IAAA,EAAM;ACrDpD,IAAM,QAAyB,CAAA,GAAI,IAAA,KAAS,EAAA,CAAG,KAAA,CAAM,GAAG,IAAI;AAkB5D,SAAS,OAAO,SAAA,EAA+C;AACpE,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,OAAO,CAAA,CAAE,KAAA,CAAM,IAAA;AACtC,EAAA,IAAI,CAAC,IAAA;AACH,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAC/D,EAAA,OAAO,IAAA;AACT","file":"chunk-JKPLID6E.js","sourcesContent":["/**\n * @h-ai/api-contract — HaiResult Schema\n *\n * 提供与 `@h-ai/core` HaiResult<T> 结构一致的 Zod Schema 工厂,\n * 用于 oRPC contract 的 output 定义和客户端响应校验。\n * @module result-schemas\n */\n\nimport { z } from 'zod'\n\n/**\n * HaiError 的跨端 JSON Schema。\n *\n * 仅描述公共错误字段,不暴露内部异常对象结构。\n * @example\n * ```ts\n * import { HaiErrorSchema } from '@h-ai/api-contract'\n *\n * const value = HaiErrorSchema.parse({\n * code: 'app:orders:001',\n * message: 'Order not found',\n * httpStatus: 404\n * })\n * void value\n * ```\n */\nexport const HaiErrorSchema = z.object({\n code: z.union([z.string(), z.number()]),\n message: z.string(),\n httpStatus: z.number().optional(),\n system: z.string().optional(),\n module: z.string().optional(),\n cause: z.unknown().optional(),\n suggestion: z.string().optional(),\n ext: z.record(z.string(), z.unknown()).optional(),\n})\n\n/**\n * 创建与 @h-ai/core HaiResult<T> 一致的响应 Schema。\n *\n * @param dataSchema - 成功分支 data 字段 Schema\n * @returns HaiResult<T> 的 Zod Schema\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n * import { z } from 'zod'\n *\n * const result = apiContract.haiResultSchema(z.object({ id: z.string() }))\n * .parse({ success: true, data: { id: 'order_1' } })\n * if (result.success) void result.data.id\n * ```\n */\nexport function haiResultSchema<T extends z.ZodType>(dataSchema: T) {\n return z.discriminatedUnion('success', [\n z.object({\n success: z.literal(true),\n data: dataSchema,\n }),\n z.object({\n success: z.literal(false),\n error: HaiErrorSchema,\n }),\n ])\n}\n\n/**\n * 无内容成功响应 Schema。\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const result = apiContract.voidResultSchema.parse({ success: true, data: undefined })\n * if (!result.success) throw new Error(result.error.message)\n * ```\n */\nexport const HaiVoidResultSchema = haiResultSchema(z.void())\n","/**\n * @h-ai/api-contract — route builder\n *\n * 统一封装 oRPC 的 route builder。应用与契约包通过 `apiContract.route(...)`\n * 定义 HTTP 路由元数据,不需要直接依赖 `@orpc/contract` 或 `@h-ai/serv`。\n */\n\nimport type { AnyContractProcedure } from '@orpc/contract'\nimport { oc } from '@orpc/contract'\n\n/**\n * 创建 oRPC contract 路由节点。\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n * import { z } from 'zod'\n *\n * const health = apiContract.route({ method: 'GET', path: '/health' })\n * .output(z.object({ healthy: z.boolean() }))\n * void health\n * ```\n */\nexport const route: typeof oc.route = (...args) => oc.route(...args)\n\n/**\n * 读取 contract procedure 中声明的业务路径。\n *\n * 路径只在对应 `*-contract.ts` 的 route 定义中维护;transport、client 与\n * middleware 通过本函数读取,避免再维护一份路由常量。\n *\n * @param procedure - 已声明 HTTP route 的 oRPC contract procedure\n * @returns contract 中的绝对业务路径\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const path = apiContract.pathOf(apiContract.iam.auth.login)\n * void path\n * ```\n */\nexport function pathOf(procedure: AnyContractProcedure): `/${string}` {\n const path = procedure['~orpc'].route.path\n if (!path)\n throw new Error('Contract procedure must define an HTTP path')\n return path\n}\n"]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { PaginationQuerySchema, paginatedSchema } from './chunk-CCCPHO6X.js';
|
|
2
|
+
import { route, haiResultSchema, HaiVoidResultSchema } from './chunk-JKPLID6E.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
var id = z.string().min(1).max(128);
|
|
6
|
+
var attachmentId = id.regex(/^[^\uD800-\uDFFF]*$/u);
|
|
7
|
+
var timestamp = z.number().int().nonnegative().safe();
|
|
8
|
+
var jsonObject = z.record(z.string(), z.json());
|
|
9
|
+
var FeedbackStatusSchema = z.enum(["pending", "handled"]);
|
|
10
|
+
var FeedbackCollectionStatusSchema = z.enum(["collecting", "complete", "partial", "failed"]);
|
|
11
|
+
var FeedbackNotificationStatusSchema = z.enum(["pending", "sending", "sent", "deferred", "failed"]);
|
|
12
|
+
var FeedbackEvidenceInputSchema = z.strictObject({
|
|
13
|
+
id,
|
|
14
|
+
source: z.string().min(1).max(128),
|
|
15
|
+
sequence: z.number().int().nonnegative().safe(),
|
|
16
|
+
kind: z.enum(["log", "error", "request", "interaction", "environment", "snapshot", "replay", "business", "missing"]),
|
|
17
|
+
timestamp,
|
|
18
|
+
requestId: id.optional(),
|
|
19
|
+
errorId: id.optional(),
|
|
20
|
+
data: jsonObject,
|
|
21
|
+
missingReason: z.string().max(2e3).optional()
|
|
22
|
+
});
|
|
23
|
+
var FeedbackEvidenceSchema = FeedbackEvidenceInputSchema.extend({ feedbackId: id, revision: z.number().int().min(1) });
|
|
24
|
+
var FeedbackAttachmentInputSchema = z.strictObject({
|
|
25
|
+
id: attachmentId,
|
|
26
|
+
name: z.string().min(1).max(255),
|
|
27
|
+
contentType: z.string().min(1).max(128),
|
|
28
|
+
size: z.number().int().min(0).max(5 * 1024 * 1024),
|
|
29
|
+
checksum: z.string().regex(/^[a-f0-9]{64}$/)
|
|
30
|
+
});
|
|
31
|
+
var FeedbackAttachmentSchema = FeedbackAttachmentInputSchema.extend({
|
|
32
|
+
feedbackId: id,
|
|
33
|
+
status: z.enum(["pending", "available", "failed"]),
|
|
34
|
+
missingReason: z.string().max(2e3).optional()
|
|
35
|
+
});
|
|
36
|
+
var FeedbackSubmitInputSchema = z.strictObject({
|
|
37
|
+
submissionId: id,
|
|
38
|
+
appId: id,
|
|
39
|
+
description: z.string().max(1e4).optional(),
|
|
40
|
+
category: z.string().max(64).optional(),
|
|
41
|
+
contact: z.string().max(320).optional(),
|
|
42
|
+
url: z.string().max(2048).optional(),
|
|
43
|
+
appVersion: z.string().max(128).optional(),
|
|
44
|
+
buildId: z.string().max(128).optional(),
|
|
45
|
+
commit: z.string().max(128).optional(),
|
|
46
|
+
anchor: z.strictObject({ kind: z.enum(["error", "feedback"]), timestamp, errorId: id.optional() }).optional(),
|
|
47
|
+
evidence: z.array(FeedbackEvidenceInputSchema).max(1e3).optional(),
|
|
48
|
+
attachments: z.array(FeedbackAttachmentInputSchema).max(20).optional()
|
|
49
|
+
});
|
|
50
|
+
var FeedbackReportSchema = z.object({
|
|
51
|
+
id,
|
|
52
|
+
number: z.string(),
|
|
53
|
+
appId: id,
|
|
54
|
+
scopeId: id,
|
|
55
|
+
userId: id,
|
|
56
|
+
status: FeedbackStatusSchema,
|
|
57
|
+
collectionStatus: FeedbackCollectionStatusSchema,
|
|
58
|
+
notificationStatus: FeedbackNotificationStatusSchema,
|
|
59
|
+
description: z.string().optional(),
|
|
60
|
+
summary: z.string().optional(),
|
|
61
|
+
category: z.string().optional(),
|
|
62
|
+
contact: z.string().optional(),
|
|
63
|
+
url: z.string().optional(),
|
|
64
|
+
appVersion: z.string().optional(),
|
|
65
|
+
buildId: z.string().optional(),
|
|
66
|
+
commit: z.string().optional(),
|
|
67
|
+
createdAt: timestamp,
|
|
68
|
+
updatedAt: timestamp,
|
|
69
|
+
version: z.number().int().min(1),
|
|
70
|
+
evidenceRevision: z.number().int().min(1)
|
|
71
|
+
});
|
|
72
|
+
var FeedbackListInputSchema = PaginationQuerySchema.extend({
|
|
73
|
+
sortDirection: z.enum(["asc", "desc"]).optional(),
|
|
74
|
+
status: FeedbackStatusSchema.optional(),
|
|
75
|
+
collectionStatus: FeedbackCollectionStatusSchema.optional(),
|
|
76
|
+
notificationStatus: FeedbackNotificationStatusSchema.optional(),
|
|
77
|
+
appId: id.optional(),
|
|
78
|
+
appVersion: z.string().max(128).optional(),
|
|
79
|
+
search: z.string().max(200).optional(),
|
|
80
|
+
from: z.coerce.number().int().nonnegative().safe().optional(),
|
|
81
|
+
to: z.coerce.number().int().nonnegative().safe().optional()
|
|
82
|
+
}).strict();
|
|
83
|
+
var FeedbackIdInputSchema = z.strictObject({ id });
|
|
84
|
+
var FeedbackEvidenceQuerySchema = PaginationQuerySchema.extend({
|
|
85
|
+
id,
|
|
86
|
+
source: z.string().max(128).optional(),
|
|
87
|
+
kind: FeedbackEvidenceInputSchema.shape.kind.optional(),
|
|
88
|
+
requestId: id.optional(),
|
|
89
|
+
errorId: id.optional(),
|
|
90
|
+
from: z.coerce.number().int().nonnegative().safe().optional(),
|
|
91
|
+
to: z.coerce.number().int().nonnegative().safe().optional()
|
|
92
|
+
}).strict();
|
|
93
|
+
var FeedbackSetStatusInputSchema = z.strictObject({ id, status: FeedbackStatusSchema, expectedVersion: z.number().int().min(1), note: z.string().max(1e4).optional() });
|
|
94
|
+
var FeedbackAppendEvidenceInputSchema = z.strictObject({ id, evidence: z.array(FeedbackEvidenceInputSchema).max(1e3) });
|
|
95
|
+
var FeedbackEvidenceAckSchema = z.object({ acknowledged: z.array(id), evidenceRevision: z.number().int().min(1) });
|
|
96
|
+
var FeedbackCompleteInputSchema = z.strictObject({ id, missing: z.array(z.string().max(2e3)).max(100).optional() });
|
|
97
|
+
var FeedbackRetryInputSchema = z.strictObject({ id, target: z.enum(["collect", "notify", "export", "attachment"]), targetId: z.string().max(128).optional() });
|
|
98
|
+
var FeedbackExportInputSchema = z.strictObject({ id, evidenceRevision: z.number().int().min(1).optional() });
|
|
99
|
+
var FeedbackExportQuerySchema = z.strictObject({ id, jobId: id });
|
|
100
|
+
var FeedbackJobSchema = z.object({
|
|
101
|
+
id,
|
|
102
|
+
feedbackId: id,
|
|
103
|
+
type: z.enum(["collect", "notify", "export", "cleanup"]),
|
|
104
|
+
status: z.enum(["pending", "running", "succeeded", "failed"]),
|
|
105
|
+
attempts: z.number().int().nonnegative(),
|
|
106
|
+
createdAt: timestamp,
|
|
107
|
+
updatedAt: timestamp,
|
|
108
|
+
nextRunAt: timestamp.optional(),
|
|
109
|
+
lastError: z.string().optional(),
|
|
110
|
+
result: jsonObject.optional()
|
|
111
|
+
});
|
|
112
|
+
var FeedbackHistorySchema = z.object({ id, feedbackId: id, userId: id, from: FeedbackStatusSchema, to: FeedbackStatusSchema, timestamp, note: z.string().optional() });
|
|
113
|
+
var FeedbackDetailSchema = z.object({ report: FeedbackReportSchema, attachments: z.array(FeedbackAttachmentSchema), history: z.array(FeedbackHistorySchema), jobs: z.array(FeedbackJobSchema) });
|
|
114
|
+
var FeedbackUploadInputSchema = z.strictObject({ id, attachmentId, dataBase64: z.string().max(4 * Math.ceil(5 * 1024 * 1024 / 3)).refine((value) => value.length % 4 === 0 && /^[A-Z0-9+/]*={0,2}$/i.test(value)) });
|
|
115
|
+
var FeedbackAttachmentQuerySchema = z.strictObject({ id, attachmentId });
|
|
116
|
+
var FeedbackAttachmentDataSchema = z.object({ name: z.string(), contentType: z.string(), dataBase64: z.string() });
|
|
117
|
+
|
|
118
|
+
// src/feedback/feedback-contract.ts
|
|
119
|
+
var feedbackContract = {
|
|
120
|
+
reports: {
|
|
121
|
+
submit: route({ method: "POST", path: "/feedback/reports", operationId: "feedback.reports.submit", summary: "submit feedback", tags: ["feedback"] }).input(FeedbackSubmitInputSchema).output(haiResultSchema(FeedbackReportSchema)),
|
|
122
|
+
list: route({ method: "GET", path: "/feedback/reports", operationId: "feedback.reports.list", summary: "list feedback", tags: ["feedback"] }).input(FeedbackListInputSchema).output(haiResultSchema(paginatedSchema(FeedbackReportSchema))),
|
|
123
|
+
get: route({ method: "GET", path: "/feedback/reports/{id}", operationId: "feedback.reports.get", summary: "get feedback", tags: ["feedback"] }).input(FeedbackIdInputSchema).output(haiResultSchema(FeedbackDetailSchema)),
|
|
124
|
+
getEvidence: route({ method: "GET", path: "/feedback/reports/{id}/evidence", operationId: "feedback.reports.getEvidence", summary: "getEvidence feedback", tags: ["feedback"] }).input(FeedbackEvidenceQuerySchema).output(haiResultSchema(paginatedSchema(FeedbackEvidenceSchema))),
|
|
125
|
+
setStatus: route({ method: "PATCH", path: "/feedback/reports/{id}/status", operationId: "feedback.reports.setStatus", summary: "setStatus feedback", tags: ["feedback"] }).input(FeedbackSetStatusInputSchema).output(haiResultSchema(FeedbackReportSchema)),
|
|
126
|
+
retry: route({ method: "POST", path: "/feedback/reports/{id}/retry", operationId: "feedback.reports.retry", summary: "retry feedback", tags: ["feedback"] }).input(FeedbackRetryInputSchema).output(HaiVoidResultSchema),
|
|
127
|
+
export: route({ method: "POST", path: "/feedback/reports/{id}/exports", operationId: "feedback.reports.export", summary: "export feedback", tags: ["feedback"] }).input(FeedbackExportInputSchema).output(haiResultSchema(FeedbackJobSchema)),
|
|
128
|
+
appendEvidence: route({ method: "POST", path: "/feedback/reports/{id}/evidence", operationId: "feedback.reports.appendEvidence", summary: "appendEvidence feedback", tags: ["feedback"] }).input(FeedbackAppendEvidenceInputSchema).output(haiResultSchema(FeedbackEvidenceAckSchema)),
|
|
129
|
+
getExport: route({ method: "GET", path: "/feedback/reports/{id}/exports/{jobId}", operationId: "feedback.reports.getExport", summary: "Download feedback export", tags: ["feedback"] }).input(FeedbackExportQuerySchema).output(haiResultSchema(FeedbackAttachmentDataSchema)),
|
|
130
|
+
completeCollection: route({ method: "POST", path: "/feedback/reports/{id}/complete", operationId: "feedback.reports.completeCollection", summary: "completeCollection feedback", tags: ["feedback"] }).input(FeedbackCompleteInputSchema).output(haiResultSchema(FeedbackReportSchema))
|
|
131
|
+
},
|
|
132
|
+
attachments: {
|
|
133
|
+
upload: route({ method: "POST", path: "/feedback/reports/{id}/attachments/{attachmentId}", operationId: "feedback.attachments.upload", summary: "Upload feedback attachment", tags: ["feedback"] }).input(FeedbackUploadInputSchema).output(haiResultSchema(FeedbackAttachmentSchema)),
|
|
134
|
+
get: route({ method: "GET", path: "/feedback/reports/{id}/attachments/{attachmentId}", operationId: "feedback.attachments.get", summary: "Read feedback attachment", tags: ["feedback"] }).input(FeedbackAttachmentQuerySchema).output(haiResultSchema(FeedbackAttachmentDataSchema))
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export { FeedbackAppendEvidenceInputSchema, FeedbackAttachmentDataSchema, FeedbackAttachmentInputSchema, FeedbackAttachmentQuerySchema, FeedbackAttachmentSchema, FeedbackCollectionStatusSchema, FeedbackCompleteInputSchema, FeedbackDetailSchema, FeedbackEvidenceAckSchema, FeedbackEvidenceInputSchema, FeedbackEvidenceQuerySchema, FeedbackEvidenceSchema, FeedbackExportInputSchema, FeedbackExportQuerySchema, FeedbackHistorySchema, FeedbackIdInputSchema, FeedbackJobSchema, FeedbackListInputSchema, FeedbackNotificationStatusSchema, FeedbackReportSchema, FeedbackRetryInputSchema, FeedbackSetStatusInputSchema, FeedbackStatusSchema, FeedbackSubmitInputSchema, FeedbackUploadInputSchema, feedbackContract };
|
|
139
|
+
//# sourceMappingURL=chunk-OQG36ECJ.js.map
|
|
140
|
+
//# sourceMappingURL=chunk-OQG36ECJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/feedback/feedback-schemas.ts","../src/feedback/feedback-contract.ts"],"names":[],"mappings":"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","file":"chunk-OQG36ECJ.js","sourcesContent":["/**\n * @h-ai/api-contract — 反馈的跨端数据契约。\n * 身份、租户、存储 key 和通知收件人只由可信服务端确定,不接受客户端覆盖。\n */\nimport { z } from 'zod'\nimport { PaginationQuerySchema } from '../common/pagination-schemas.js'\n\nconst id = z.string().min(1).max(128)\n// 附件标识须可无损编码为 Unicode;正常代理对(如 emoji)不受限。\nconst attachmentId = id.regex(/^[^\\uD800-\\uDFFF]*$/u)\nconst timestamp = z.number().int().nonnegative().safe()\nconst jsonObject = z.record(z.string(), z.json())\n\n/**\n * 反馈处理状态。\n * @example\n * ```ts\n * import { FeedbackStatusSchema } from '@h-ai/api-contract'\n * FeedbackStatusSchema.parse('pending')\n * ```\n */\nexport const FeedbackStatusSchema = z.enum(['pending', 'handled'])\n/**\n * 材料状态。\n * @example\n * ```ts\n * import { FeedbackCollectionStatusSchema } from '@h-ai/api-contract'\n * FeedbackCollectionStatusSchema.parse('collecting')\n * ```\n */\nexport const FeedbackCollectionStatusSchema = z.enum(['collecting', 'complete', 'partial', 'failed'])\n/**\n * 通知状态,sent 仅表示邮件服务受理。\n * @example\n * ```ts\n * import { FeedbackNotificationStatusSchema } from '@h-ai/api-contract'\n * FeedbackNotificationStatusSchema.parse('pending')\n * ```\n */\nexport const FeedbackNotificationStatusSchema = z.enum(['pending', 'sending', 'sent', 'deferred', 'failed'])\n\n/**\n * 单条有界、JSON 可序列化的诊断证据。\n * @example\n * ```ts\n * import { FeedbackEvidenceInputSchema } from '@h-ai/api-contract'\n * FeedbackEvidenceInputSchema.parse({ id: 'event-1', source: 'browser', sequence: 1, kind: 'log', timestamp: 1, data: { message: 'Failed' } })\n * ```\n */\nexport const FeedbackEvidenceInputSchema = z.strictObject({\n id,\n source: z.string().min(1).max(128),\n sequence: z.number().int().nonnegative().safe(),\n kind: z.enum(['log', 'error', 'request', 'interaction', 'environment', 'snapshot', 'replay', 'business', 'missing']),\n timestamp,\n requestId: id.optional(),\n errorId: id.optional(),\n data: jsonObject,\n missingReason: z.string().max(2000).optional(),\n})\n/**\n * 已保存证据及所属修订。\n * @example\n * ```ts\n * import { FeedbackEvidenceSchema } from '@h-ai/api-contract'\n * FeedbackEvidenceSchema.parse({ id: 'event-1', feedbackId: 'report-1', revision: 1, source: 'browser', sequence: 1, kind: 'log', timestamp: 1, data: {} })\n * ```\n */\nexport const FeedbackEvidenceSchema = FeedbackEvidenceInputSchema.extend({ feedbackId: id, revision: z.number().int().min(1) })\n\n/**\n * 附件声明,不含可指定的 S3 key。\n * @example\n * ```ts\n * import { FeedbackAttachmentInputSchema } from '@h-ai/api-contract'\n * FeedbackAttachmentInputSchema.parse({ id: 'image-1', name: 'screen.png', contentType: 'image/png', size: 4, checksum: '0'.repeat(64) })\n * ```\n */\nexport const FeedbackAttachmentInputSchema = z.strictObject({\n id: attachmentId,\n name: z.string().min(1).max(255),\n contentType: z.string().min(1).max(128),\n size: z.number().int().min(0).max(5 * 1024 * 1024),\n checksum: z.string().regex(/^[a-f0-9]{64}$/),\n})\n/**\n * 附件的受权元数据。\n * @example\n * ```ts\n * import { FeedbackAttachmentSchema } from '@h-ai/api-contract'\n * FeedbackAttachmentSchema.parse({ id: 'image-1', feedbackId: 'report-1', name: 'screen.png', contentType: 'image/png', size: 4, checksum: '0'.repeat(64), status: 'pending' })\n * ```\n */\nexport const FeedbackAttachmentSchema = FeedbackAttachmentInputSchema.extend({\n feedbackId: id,\n status: z.enum(['pending', 'available', 'failed']),\n missingReason: z.string().max(2000).optional(),\n})\n\n/**\n * 幂等反馈提交;所有补充输入均可选。\n * @example\n * ```ts\n * import { FeedbackSubmitInputSchema } from '@h-ai/api-contract'\n * FeedbackSubmitInputSchema.parse({ submissionId: 'submit-1', appId: 'orders' })\n * ```\n */\nexport const FeedbackSubmitInputSchema = z.strictObject({\n submissionId: id,\n appId: id,\n description: z.string().max(10000).optional(),\n category: z.string().max(64).optional(),\n contact: z.string().max(320).optional(),\n url: z.string().max(2048).optional(),\n appVersion: z.string().max(128).optional(),\n buildId: z.string().max(128).optional(),\n commit: z.string().max(128).optional(),\n anchor: z.strictObject({ kind: z.enum(['error', 'feedback']), timestamp, errorId: id.optional() }).optional(),\n evidence: z.array(FeedbackEvidenceInputSchema).max(1000).optional(),\n attachments: z.array(FeedbackAttachmentInputSchema).max(20).optional(),\n})\n\n/**\n * 反馈摘要,应用版本与乐观锁 version 分开。\n * @example\n * ```ts\n * import { FeedbackReportSchema } from '@h-ai/api-contract'\n * FeedbackReportSchema.parse({ id: 'report-1', number: 'FB-1', appId: 'orders', scopeId: 'tenant-1', userId: 'user-1', status: 'pending', collectionStatus: 'collecting', notificationStatus: 'pending', createdAt: 1, updatedAt: 1, version: 1, evidenceRevision: 1 })\n * ```\n */\nexport const FeedbackReportSchema = z.object({\n id,\n number: z.string(),\n appId: id,\n scopeId: id,\n userId: id,\n status: FeedbackStatusSchema,\n collectionStatus: FeedbackCollectionStatusSchema,\n notificationStatus: FeedbackNotificationStatusSchema,\n description: z.string().optional(),\n summary: z.string().optional(),\n category: z.string().optional(),\n contact: z.string().optional(),\n url: z.string().optional(),\n appVersion: z.string().optional(),\n buildId: z.string().optional(),\n commit: z.string().optional(),\n createdAt: timestamp,\n updatedAt: timestamp,\n version: z.number().int().min(1),\n evidenceRevision: z.number().int().min(1),\n})\n\n/**\n * 列表筛选和受限分页。\n * @example\n * ```ts\n * import { FeedbackListInputSchema } from '@h-ai/api-contract'\n * FeedbackListInputSchema.parse({ page: 1, pageSize: 20 })\n * ```\n */\nexport const FeedbackListInputSchema = PaginationQuerySchema.extend({\n sortDirection: z.enum(['asc', 'desc']).optional(),\n status: FeedbackStatusSchema.optional(),\n collectionStatus: FeedbackCollectionStatusSchema.optional(),\n notificationStatus: FeedbackNotificationStatusSchema.optional(),\n appId: id.optional(),\n appVersion: z.string().max(128).optional(),\n search: z.string().max(200).optional(),\n from: z.coerce.number().int().nonnegative().safe().optional(),\n to: z.coerce.number().int().nonnegative().safe().optional(),\n}).strict()\n/**\n * 受权记录定位。\n * @example\n * ```ts\n * import { FeedbackIdInputSchema } from '@h-ai/api-contract'\n * FeedbackIdInputSchema.parse({ id: 'report-1' })\n * ```\n */\nexport const FeedbackIdInputSchema = z.strictObject({ id })\n/**\n * 证据索引查询。\n * @example\n * ```ts\n * import { FeedbackEvidenceQuerySchema } from '@h-ai/api-contract'\n * FeedbackEvidenceQuerySchema.parse({ id: 'report-1', pageSize: 20 })\n * ```\n */\nexport const FeedbackEvidenceQuerySchema = PaginationQuerySchema.extend({\n id,\n source: z.string().max(128).optional(),\n kind: FeedbackEvidenceInputSchema.shape.kind.optional(),\n requestId: id.optional(),\n errorId: id.optional(),\n from: z.coerce.number().int().nonnegative().safe().optional(),\n to: z.coerce.number().int().nonnegative().safe().optional(),\n}).strict()\n/**\n * 状态更新必须携带已读版本。\n * @example\n * ```ts\n * import { FeedbackSetStatusInputSchema } from '@h-ai/api-contract'\n * FeedbackSetStatusInputSchema.parse({ id: 'report-1', status: 'handled', expectedVersion: 1 })\n * ```\n */\nexport const FeedbackSetStatusInputSchema = z.strictObject({ id, status: FeedbackStatusSchema, expectedVersion: z.number().int().min(1), note: z.string().max(10000).optional() })\n/**\n * 提交后补采分块,服务端按来源序号幂等确认。\n * @example\n * ```ts\n * import { FeedbackAppendEvidenceInputSchema } from '@h-ai/api-contract'\n * FeedbackAppendEvidenceInputSchema.parse({ id: 'report-1', evidence: [] })\n * ```\n */\nexport const FeedbackAppendEvidenceInputSchema = z.strictObject({ id, evidence: z.array(FeedbackEvidenceInputSchema).max(1000) })\n/**\n * 已可靠入库的证据确认。\n * @example\n * ```ts\n * import { FeedbackEvidenceAckSchema } from '@h-ai/api-contract'\n * FeedbackEvidenceAckSchema.parse({ acknowledged: ['event-1'], evidenceRevision: 1 })\n * ```\n */\nexport const FeedbackEvidenceAckSchema = z.object({ acknowledged: z.array(id), evidenceRevision: z.number().int().min(1) })\n/**\n * 采集结束或部分缺失。\n * @example\n * ```ts\n * import { FeedbackCompleteInputSchema } from '@h-ai/api-contract'\n * FeedbackCompleteInputSchema.parse({ id: 'report-1', missing: [] })\n * ```\n */\nexport const FeedbackCompleteInputSchema = z.strictObject({ id, missing: z.array(z.string().max(2000)).max(100).optional() })\n/**\n * 按任务类别重试。\n * @example\n * ```ts\n * import { FeedbackRetryInputSchema } from '@h-ai/api-contract'\n * FeedbackRetryInputSchema.parse({ id: 'report-1', target: 'notify' })\n * ```\n */\nexport const FeedbackRetryInputSchema = z.strictObject({ id, target: z.enum(['collect', 'notify', 'export', 'attachment']), targetId: z.string().max(128).optional() })\n/**\n * 固定证据修订的导出请求。\n * @example\n * ```ts\n * import { FeedbackExportInputSchema } from '@h-ai/api-contract'\n * FeedbackExportInputSchema.parse({ id: 'report-1' })\n * ```\n */\nexport const FeedbackExportInputSchema = z.strictObject({ id, evidenceRevision: z.number().int().min(1).optional() })\n/**\n * 已生成问题包的受权下载定位。\n * @example\n * ```ts\n * import { FeedbackExportQuerySchema } from '@h-ai/api-contract'\n * FeedbackExportQuerySchema.parse({ id: 'report-1', jobId: 'job-1' })\n * ```\n */\nexport const FeedbackExportQuerySchema = z.strictObject({ id, jobId: id })\n\n/**\n * 后台任务的安全状态,不暴露邮件正文、租约和存储 key。\n * @example\n * ```ts\n * import { FeedbackJobSchema } from '@h-ai/api-contract'\n * FeedbackJobSchema.parse({ id: 'job-1', feedbackId: 'report-1', type: 'export', status: 'pending', attempts: 0, createdAt: 1, updatedAt: 1 })\n * ```\n */\nexport const FeedbackJobSchema = z.object({\n id,\n feedbackId: id,\n type: z.enum(['collect', 'notify', 'export', 'cleanup']),\n status: z.enum(['pending', 'running', 'succeeded', 'failed']),\n attempts: z.number().int().nonnegative(),\n createdAt: timestamp,\n updatedAt: timestamp,\n nextRunAt: timestamp.optional(),\n lastError: z.string().optional(),\n result: jsonObject.optional(),\n})\n/**\n * 处理变更历史。\n * @example\n * ```ts\n * import { FeedbackHistorySchema } from '@h-ai/api-contract'\n * FeedbackHistorySchema.parse({ id: 'history-1', feedbackId: 'report-1', userId: 'user-1', from: 'pending', to: 'handled', timestamp: 1 })\n * ```\n */\nexport const FeedbackHistorySchema = z.object({ id, feedbackId: id, userId: id, from: FeedbackStatusSchema, to: FeedbackStatusSchema, timestamp, note: z.string().optional() })\n/**\n * 详情按需加载,完整日志通过单独分页接口查询。\n * @example\n * ```ts\n * import type { FeedbackDetail } from '@h-ai/api-contract'\n * function numberOfAttachments(detail: FeedbackDetail) { return detail.attachments.length }\n * ```\n */\nexport const FeedbackDetailSchema = z.object({ report: FeedbackReportSchema, attachments: z.array(FeedbackAttachmentSchema), history: z.array(FeedbackHistorySchema), jobs: z.array(FeedbackJobSchema) })\n/**\n * 有界附件上传,解码前后均须检查长度和 checksum。\n * @example\n * ```ts\n * import { FeedbackUploadInputSchema } from '@h-ai/api-contract'\n * FeedbackUploadInputSchema.parse({ id: 'report-1', attachmentId: 'image-1', dataBase64: 'iVBORw==' })\n * ```\n */\nexport const FeedbackUploadInputSchema = z.strictObject({ id, attachmentId, dataBase64: z.string().max(4 * Math.ceil(5 * 1024 * 1024 / 3)).refine(value => value.length % 4 === 0 && /^[A-Z0-9+/]*={0,2}$/i.test(value)) })\n/**\n * 附件受权读取定位。\n * @example\n * ```ts\n * import { FeedbackAttachmentQuerySchema } from '@h-ai/api-contract'\n * FeedbackAttachmentQuerySchema.parse({ id: 'report-1', attachmentId: 'image-1' })\n * ```\n */\nexport const FeedbackAttachmentQuerySchema = z.strictObject({ id, attachmentId })\n/**\n * 受权附件内容,不暴露 S3 凭据或公网链接。\n * @example\n * ```ts\n * import { FeedbackAttachmentDataSchema } from '@h-ai/api-contract'\n * FeedbackAttachmentDataSchema.parse({ name: 'screen.png', contentType: 'image/png', dataBase64: 'iVBORw==' })\n * ```\n */\nexport const FeedbackAttachmentDataSchema = z.object({ name: z.string(), contentType: z.string(), dataBase64: z.string() })\n\n/**\n * FeedbackStatus 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackStatus } from '@h-ai/api-contract'\n * const value: FeedbackStatus = 'pending'\n * ```\n */\nexport type FeedbackStatus = z.infer<typeof FeedbackStatusSchema>\n/**\n * FeedbackCollectionStatus 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackCollectionStatus } from '@h-ai/api-contract'\n * const value: FeedbackCollectionStatus = 'collecting'\n * ```\n */\nexport type FeedbackCollectionStatus = z.infer<typeof FeedbackCollectionStatusSchema>\n/**\n * FeedbackNotificationStatus 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackNotificationStatus } from '@h-ai/api-contract'\n * const value: FeedbackNotificationStatus = 'pending'\n * ```\n */\nexport type FeedbackNotificationStatus = z.infer<typeof FeedbackNotificationStatusSchema>\n/**\n * FeedbackEvidenceInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackEvidenceInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackEvidenceInput) { return value.id }\n * ```\n */\nexport type FeedbackEvidenceInput = z.infer<typeof FeedbackEvidenceInputSchema>\n/**\n * FeedbackEvidence 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackEvidence } from '@h-ai/api-contract'\n * function inspect(value: FeedbackEvidence) { return value.id }\n * ```\n */\nexport type FeedbackEvidence = z.infer<typeof FeedbackEvidenceSchema>\n/**\n * FeedbackAttachmentInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackAttachmentInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackAttachmentInput) { return value.id }\n * ```\n */\nexport type FeedbackAttachmentInput = z.infer<typeof FeedbackAttachmentInputSchema>\n/**\n * FeedbackAttachment 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackAttachment } from '@h-ai/api-contract'\n * function inspect(value: FeedbackAttachment) { return value.id }\n * ```\n */\nexport type FeedbackAttachment = z.infer<typeof FeedbackAttachmentSchema>\n/**\n * FeedbackSubmitInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackSubmitInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackSubmitInput) { return value.submissionId }\n * ```\n */\nexport type FeedbackSubmitInput = z.infer<typeof FeedbackSubmitInputSchema>\n/**\n * FeedbackReport 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackReport } from '@h-ai/api-contract'\n * function inspect(value: FeedbackReport) { return value.id }\n * ```\n */\nexport type FeedbackReport = z.infer<typeof FeedbackReportSchema>\n/**\n * FeedbackListInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackListInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackListInput) { return value.pageSize }\n * ```\n */\nexport type FeedbackListInput = z.infer<typeof FeedbackListInputSchema>\n/**\n * FeedbackEvidenceQuery 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackEvidenceQuery } from '@h-ai/api-contract'\n * function inspect(value: FeedbackEvidenceQuery) { return value.id }\n * ```\n */\nexport type FeedbackEvidenceQuery = z.infer<typeof FeedbackEvidenceQuerySchema>\n/**\n * FeedbackSetStatusInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackSetStatusInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackSetStatusInput) { return value.id }\n * ```\n */\nexport type FeedbackSetStatusInput = z.infer<typeof FeedbackSetStatusInputSchema>\n/**\n * FeedbackAppendEvidenceInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackAppendEvidenceInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackAppendEvidenceInput) { return value.id }\n * ```\n */\nexport type FeedbackAppendEvidenceInput = z.infer<typeof FeedbackAppendEvidenceInputSchema>\n/**\n * FeedbackEvidenceAck 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackEvidenceAck } from '@h-ai/api-contract'\n * function inspect(value: FeedbackEvidenceAck) { return value.acknowledged.length }\n * ```\n */\nexport type FeedbackEvidenceAck = z.infer<typeof FeedbackEvidenceAckSchema>\n/**\n * FeedbackCompleteInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackCompleteInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackCompleteInput) { return value.id }\n * ```\n */\nexport type FeedbackCompleteInput = z.infer<typeof FeedbackCompleteInputSchema>\n/**\n * FeedbackRetryInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackRetryInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackRetryInput) { return value.id }\n * ```\n */\nexport type FeedbackRetryInput = z.infer<typeof FeedbackRetryInputSchema>\n/**\n * FeedbackExportInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackExportInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackExportInput) { return value.id }\n * ```\n */\nexport type FeedbackExportInput = z.infer<typeof FeedbackExportInputSchema>\n/**\n * FeedbackJob 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackJob } from '@h-ai/api-contract'\n * function inspect(value: FeedbackJob) { return value.id }\n * ```\n */\nexport type FeedbackJob = z.infer<typeof FeedbackJobSchema>\n/**\n * FeedbackHistory 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackHistory } from '@h-ai/api-contract'\n * function inspect(value: FeedbackHistory) { return value.id }\n * ```\n */\nexport type FeedbackHistory = z.infer<typeof FeedbackHistorySchema>\n/**\n * FeedbackDetail 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackDetail } from '@h-ai/api-contract'\n * function inspect(value: FeedbackDetail) { return value.report.number }\n * ```\n */\nexport type FeedbackDetail = z.infer<typeof FeedbackDetailSchema>\n/**\n * FeedbackUploadInput 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackUploadInput } from '@h-ai/api-contract'\n * function inspect(value: FeedbackUploadInput) { return value.id }\n * ```\n */\nexport type FeedbackUploadInput = z.infer<typeof FeedbackUploadInputSchema>\n/**\n * FeedbackAttachmentData 的共享类型,由对应 schema 推导。\n * @example\n * ```ts\n * import type { FeedbackAttachmentData } from '@h-ai/api-contract'\n * function inspect(value: FeedbackAttachmentData) { return value.contentType }\n * ```\n */\nexport type FeedbackAttachmentData = z.infer<typeof FeedbackAttachmentDataSchema>\n","/** @h-ai/api-contract — 反馈的受权 HTTP 契约。 */\nimport { paginatedSchema } from '../common/pagination-schemas.js'\nimport { haiResultSchema, HaiVoidResultSchema } from '../common/result-schemas.js'\nimport { route } from '../common/route.js'\nimport {\n FeedbackAppendEvidenceInputSchema,\n FeedbackAttachmentDataSchema,\n FeedbackAttachmentQuerySchema,\n FeedbackAttachmentSchema,\n FeedbackCompleteInputSchema,\n FeedbackDetailSchema,\n FeedbackEvidenceAckSchema,\n FeedbackEvidenceQuerySchema,\n FeedbackEvidenceSchema,\n FeedbackExportInputSchema,\n FeedbackExportQuerySchema,\n FeedbackIdInputSchema,\n FeedbackJobSchema,\n FeedbackListInputSchema,\n FeedbackReportSchema,\n FeedbackRetryInputSchema,\n FeedbackSetStatusInputSchema,\n FeedbackSubmitInputSchema,\n FeedbackUploadInputSchema,\n} from './feedback-schemas.js'\n\n/**\n * 反馈契约,宿主自行决定是否挂载。\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n * const contract = apiContract.create({ feedback: apiContract.feedback })\n * const path = apiContract.pathOf(contract.feedback.reports.submit)\n * ```\n */\nexport const feedbackContract = {\n reports: {\n submit: route({ method: 'POST', path: '/feedback/reports', operationId: 'feedback.reports.submit', summary: 'submit feedback', tags: ['feedback'] })\n .input(FeedbackSubmitInputSchema)\n .output(haiResultSchema(FeedbackReportSchema)),\n list: route({ method: 'GET', path: '/feedback/reports', operationId: 'feedback.reports.list', summary: 'list feedback', tags: ['feedback'] })\n .input(FeedbackListInputSchema)\n .output(haiResultSchema(paginatedSchema(FeedbackReportSchema))),\n get: route({ method: 'GET', path: '/feedback/reports/{id}', operationId: 'feedback.reports.get', summary: 'get feedback', tags: ['feedback'] })\n .input(FeedbackIdInputSchema)\n .output(haiResultSchema(FeedbackDetailSchema)),\n getEvidence: route({ method: 'GET', path: '/feedback/reports/{id}/evidence', operationId: 'feedback.reports.getEvidence', summary: 'getEvidence feedback', tags: ['feedback'] })\n .input(FeedbackEvidenceQuerySchema)\n .output(haiResultSchema(paginatedSchema(FeedbackEvidenceSchema))),\n setStatus: route({ method: 'PATCH', path: '/feedback/reports/{id}/status', operationId: 'feedback.reports.setStatus', summary: 'setStatus feedback', tags: ['feedback'] })\n .input(FeedbackSetStatusInputSchema)\n .output(haiResultSchema(FeedbackReportSchema)),\n retry: route({ method: 'POST', path: '/feedback/reports/{id}/retry', operationId: 'feedback.reports.retry', summary: 'retry feedback', tags: ['feedback'] })\n .input(FeedbackRetryInputSchema)\n .output(HaiVoidResultSchema),\n export: route({ method: 'POST', path: '/feedback/reports/{id}/exports', operationId: 'feedback.reports.export', summary: 'export feedback', tags: ['feedback'] })\n .input(FeedbackExportInputSchema)\n .output(haiResultSchema(FeedbackJobSchema)),\n appendEvidence: route({ method: 'POST', path: '/feedback/reports/{id}/evidence', operationId: 'feedback.reports.appendEvidence', summary: 'appendEvidence feedback', tags: ['feedback'] })\n .input(FeedbackAppendEvidenceInputSchema)\n .output(haiResultSchema(FeedbackEvidenceAckSchema)),\n getExport: route({ method: 'GET', path: '/feedback/reports/{id}/exports/{jobId}', operationId: 'feedback.reports.getExport', summary: 'Download feedback export', tags: ['feedback'] })\n .input(FeedbackExportQuerySchema)\n .output(haiResultSchema(FeedbackAttachmentDataSchema)),\n completeCollection: route({ method: 'POST', path: '/feedback/reports/{id}/complete', operationId: 'feedback.reports.completeCollection', summary: 'completeCollection feedback', tags: ['feedback'] })\n .input(FeedbackCompleteInputSchema)\n .output(haiResultSchema(FeedbackReportSchema)),\n },\n attachments: {\n upload: route({ method: 'POST', path: '/feedback/reports/{id}/attachments/{attachmentId}', operationId: 'feedback.attachments.upload', summary: 'Upload feedback attachment', tags: ['feedback'] })\n .input(FeedbackUploadInputSchema)\n .output(haiResultSchema(FeedbackAttachmentSchema)),\n get: route({ method: 'GET', path: '/feedback/reports/{id}/attachments/{attachmentId}', operationId: 'feedback.attachments.get', summary: 'Read feedback attachment', tags: ['feedback'] })\n .input(FeedbackAttachmentQuerySchema)\n .output(haiResultSchema(FeedbackAttachmentDataSchema)),\n },\n}\n\n/**\n * 反馈 typed client 的契约类型。\n * @example\n * ```ts\n * import type { FeedbackContract } from '@h-ai/api-contract'\n * import { apiContract } from '@h-ai/api-contract'\n * const contract: FeedbackContract = apiContract.feedback\n * ```\n */\nexport type FeedbackContract = typeof feedbackContract\n"]}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { haiResultSchema, route } from './chunk-
|
|
1
|
+
import { haiResultSchema, route } from './chunk-JKPLID6E.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
var PaymentProviderSchema = z.enum(["wechat", "alipay", "stripe"]);
|
|
5
|
-
var PaymentTradeTypeSchema = z.enum(["jsapi", "h5"
|
|
5
|
+
var PaymentTradeTypeSchema = z.enum(["jsapi", "h5"]);
|
|
6
6
|
var PaymentCreateOrderInputSchema = z.object({
|
|
7
7
|
provider: PaymentProviderSchema,
|
|
8
8
|
amount: z.number().int().min(1),
|
|
9
9
|
description: z.string().min(1),
|
|
10
10
|
tradeType: PaymentTradeTypeSchema,
|
|
11
|
-
userId: z.string().optional(),
|
|
11
|
+
userId: z.string().trim().min(1).max(128).optional(),
|
|
12
12
|
metadata: z.record(z.string(), z.string()).optional()
|
|
13
|
-
});
|
|
13
|
+
}).strict().refine((input) => input.tradeType === (input.provider === "wechat" ? "jsapi" : "h5"), { path: ["tradeType"] }).refine((input) => input.provider !== "wechat" || input.userId !== void 0, { path: ["userId"] });
|
|
14
14
|
var PaymentCreateOrderDataSchema = z.object({
|
|
15
15
|
provider: PaymentProviderSchema,
|
|
16
16
|
tradeType: PaymentTradeTypeSchema,
|
|
17
17
|
clientParams: z.record(z.string(), z.unknown()),
|
|
18
18
|
prepayId: z.string().optional()
|
|
19
|
-
});
|
|
19
|
+
}).refine((order) => order.tradeType === (order.provider === "wechat" ? "jsapi" : "h5"), { path: ["tradeType"] });
|
|
20
20
|
var PaymentQueryOrderInputSchema = z.object({
|
|
21
21
|
orderNo: z.string().min(1)
|
|
22
22
|
});
|
|
@@ -63,5 +63,5 @@ var paymentContract = {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
export { PaymentCreateOrderDataSchema, PaymentCreateOrderInputSchema, PaymentNotifyMessageSchema, PaymentOrderSchema, PaymentProviderSchema, PaymentQueryOrderInputSchema, PaymentRefundDataSchema, PaymentRefundInputSchema, PaymentStripeNotifyDataSchema, PaymentTradeTypeSchema, paymentContract };
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-R5GDWFYC.js.map
|
|
67
|
+
//# sourceMappingURL=chunk-R5GDWFYC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payment/payment-schemas.ts","../src/payment/payment-contract.ts"],"names":["z"],"mappings":"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","file":"chunk-R5GDWFYC.js","sourcesContent":["import type { HaiResult } from '@h-ai/core'\nimport { z } from 'zod'\n\n/**\n * 支付渠道 Schema。\n * @example\n * ```ts\n * import { PaymentProviderSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentProviderSchema.parse('wechat')\n * void value\n * ```\n */\nexport const PaymentProviderSchema = z.enum(['wechat', 'alipay', 'stripe'])\n\n/**\n * 完整实现的支付类型:微信 jsapi,支付宝/Stripe h5。\n * @example\n * ```ts\n * import { PaymentTradeTypeSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentTradeTypeSchema.parse('jsapi')\n * void value\n * ```\n */\nexport const PaymentTradeTypeSchema = z.enum(['jsapi', 'h5'])\n\n/**\n * 创建支付订单入参 Schema。\n * @example\n * ```ts\n * import { PaymentCreateOrderInputSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentCreateOrderInputSchema.parse({\n * provider: 'wechat',\n * amount: 100,\n * description: 'Example order',\n * tradeType: 'jsapi',\n * userId: 'example-openid'\n * })\n * void value\n * ```\n */\nexport const PaymentCreateOrderInputSchema = z.object({\n provider: PaymentProviderSchema,\n amount: z.number().int().min(1),\n description: z.string().min(1),\n tradeType: PaymentTradeTypeSchema,\n userId: z.string().trim().min(1).max(128).optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n}).strict().refine(input => input.tradeType === (input.provider === 'wechat' ? 'jsapi' : 'h5'), { path: ['tradeType'] }).refine(input => input.provider !== 'wechat' || input.userId !== undefined, { path: ['userId'] })\n\n/**\n * 创建支付订单业务数据 Schema。\n * @example\n * ```ts\n * import { PaymentCreateOrderDataSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentCreateOrderDataSchema.parse({\n * provider: 'wechat',\n * tradeType: 'jsapi',\n * prepayId: 'example-prepay',\n * clientParams: {\n * appId: 'wx-example',\n * timeStamp: '1767225600',\n * nonceStr: 'example-nonce',\n * package: 'prepay_id=example-prepay',\n * signType: 'RSA',\n * paySign: 'example-only-signature'\n * }\n * })\n * void value\n * ```\n */\nexport const PaymentCreateOrderDataSchema = z.object({\n provider: PaymentProviderSchema,\n tradeType: PaymentTradeTypeSchema,\n clientParams: z.record(z.string(), z.unknown()),\n prepayId: z.string().optional(),\n}).refine(order => order.tradeType === (order.provider === 'wechat' ? 'jsapi' : 'h5'), { path: ['tradeType'] })\n\n/**\n * 查询支付订单入参 Schema。\n * @example\n * ```ts\n * import { PaymentQueryOrderInputSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentQueryOrderInputSchema.parse({\n * orderNo: 'order_1'\n * })\n * void value\n * ```\n */\nexport const PaymentQueryOrderInputSchema = z.object({\n orderNo: z.string().min(1),\n})\n\n/**\n * 支付订单业务数据 Schema。\n * @example\n * ```ts\n * import { PaymentOrderSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentOrderSchema.parse({\n * orderNo: 'order_1',\n * status: 'pending',\n * amount: 0\n * })\n * void value\n * ```\n */\nexport const PaymentOrderSchema = z.object({\n orderNo: z.string(),\n transactionId: z.string().optional(),\n status: z.enum(['pending', 'paid', 'closed', 'refunded', 'failed']),\n amount: z.number(),\n // ISO 8601 时间戳(例如 `2024-01-02T03:04:05.000Z`),由服务端以 `Date#toISOString()` 序列化。\n paidAt: z.iso.datetime().optional(),\n})\n\n/**\n * 退款入参 Schema。\n * @example\n * ```ts\n * import { PaymentRefundInputSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentRefundInputSchema.parse({\n * provider: 'wechat',\n * orderNo: 'order_1',\n * refundNo: 'refund_1',\n * amount: 1\n * })\n * void value\n * ```\n */\nexport const PaymentRefundInputSchema = z.object({\n provider: PaymentProviderSchema,\n orderNo: z.string(),\n refundNo: z.string(),\n amount: z.number().int().min(1),\n reason: z.string().optional(),\n})\n\n/**\n * 退款业务数据 Schema。\n * @example\n * ```ts\n * import { PaymentRefundDataSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentRefundDataSchema.parse({\n * refundNo: 'refund_1',\n * refundId: 'example',\n * status: 'processing'\n * })\n * void value\n * ```\n */\nexport const PaymentRefundDataSchema = z.object({\n refundNo: z.string(),\n refundId: z.string(),\n status: z.enum(['processing', 'success', 'failed']),\n})\n\n/**\n * 微信/支付宝通知响应 Schema。\n * @example\n * ```ts\n * import { PaymentNotifyMessageSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentNotifyMessageSchema.parse({\n * code: 'example-1',\n * message: 'example'\n * })\n * void value\n * ```\n */\nexport const PaymentNotifyMessageSchema = z.object({\n code: z.string(),\n message: z.string(),\n})\n\n/**\n * Stripe 通知响应 Schema。\n * @example\n * ```ts\n * import { PaymentStripeNotifyDataSchema } from '@h-ai/api-contract'\n *\n * const value = PaymentStripeNotifyDataSchema.parse({\n * received: true\n * })\n * void value\n * ```\n */\nexport const PaymentStripeNotifyDataSchema = z.object({\n received: z.boolean(),\n})\n\n/**\n * 按渠道和已实现支付方式创建订单的请求。\n * @example\n * ```ts\n * import type { PaymentCreateOrderInput } from '@h-ai/api-contract'\n * import { PaymentCreateOrderInputSchema } from '@h-ai/api-contract'\n *\n * const value: PaymentCreateOrderInput = PaymentCreateOrderInputSchema.parse({\n * provider: 'wechat',\n * amount: 100,\n * description: 'Example order',\n * tradeType: 'jsapi',\n * userId: 'example-openid'\n * })\n * void value\n * ```\n */\nexport type PaymentCreateOrderInput = z.infer<typeof PaymentCreateOrderInputSchema>\n/**\n * 以 HaiResult 区分成功业务数据和公共错误的 PaymentCreateOrderOutput 响应。\n * @example\n * ```ts\n * import type { PaymentCreateOrderOutput } from '@h-ai/api-contract'\n * import { PaymentCreateOrderDataSchema } from '@h-ai/api-contract'\n * import { ok } from '@h-ai/core'\n *\n * const response: PaymentCreateOrderOutput = ok(PaymentCreateOrderDataSchema.parse({\n * provider: 'wechat',\n * tradeType: 'jsapi',\n * prepayId: 'example-prepay',\n * clientParams: {\n * appId: 'wx-example',\n * timeStamp: '1767225600',\n * nonceStr: 'example-nonce',\n * package: 'prepay_id=example-prepay',\n * signType: 'RSA',\n * paySign: 'example-only-signature'\n * }\n * }))\n * if (response.success) void response.data\n * ```\n */\nexport type PaymentCreateOrderOutput = HaiResult<z.infer<typeof PaymentCreateOrderDataSchema>>\n/**\n * 退款请求,金额单位与支付契约一致。\n * @example\n * ```ts\n * import type { PaymentRefundInput } from '@h-ai/api-contract'\n * import { PaymentRefundInputSchema } from '@h-ai/api-contract'\n *\n * const value: PaymentRefundInput = PaymentRefundInputSchema.parse({\n * provider: 'wechat',\n * orderNo: 'order_1',\n * refundNo: 'refund_1',\n * amount: 1\n * })\n * void value\n * ```\n */\nexport type PaymentRefundInput = z.infer<typeof PaymentRefundInputSchema>\n","import { z } from 'zod'\nimport { haiResultSchema } from '../common/result-schemas.js'\nimport { route } from '../common/route.js'\nimport {\n PaymentCreateOrderDataSchema,\n PaymentCreateOrderInputSchema,\n PaymentNotifyMessageSchema,\n PaymentOrderSchema,\n PaymentQueryOrderInputSchema,\n PaymentRefundDataSchema,\n PaymentRefundInputSchema,\n PaymentStripeNotifyDataSchema,\n} from './payment-schemas.js'\n\n// Webhook 通知体由各支付渠道决定(且通常需要原始 raw body 校验签名),\n// 因此 contract 层只声明为 unknown,由 procedure 实现负责按渠道解析。\nconst WebhookBodySchema = z.unknown()\n// 微信与支付宝通知共享同一响应结构,仅在本 contract 内复用。\nconst notifyMessageOutputSchema = haiResultSchema(PaymentNotifyMessageSchema)\n\n/**\n * Payment 领域 oRPC contract。\n * @example\n * ```ts\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const contract = apiContract.payment\n * void contract\n * ```\n */\nexport const paymentContract = {\n orders: {\n create: route({ method: 'POST', path: '/payment/orders', operationId: 'payment.orders.create', summary: 'Create payment order', tags: ['payment', 'orders'] })\n .input(PaymentCreateOrderInputSchema)\n .output(haiResultSchema(PaymentCreateOrderDataSchema)),\n get: route({ method: 'GET', path: '/payment/orders/{orderNo}', operationId: 'payment.orders.get', summary: 'Get payment order', tags: ['payment', 'orders'] })\n .input(PaymentQueryOrderInputSchema)\n .output(haiResultSchema(PaymentOrderSchema)),\n refund: route({ method: 'POST', path: '/payment/orders/{orderNo}/refunds', operationId: 'payment.orders.refund', summary: 'Refund payment order', tags: ['payment', 'orders'] })\n .input(PaymentRefundInputSchema)\n .output(haiResultSchema(PaymentRefundDataSchema)),\n },\n notifications: {\n wechat: route({ method: 'POST', path: '/payment/notifications/wechat', operationId: 'payment.notifications.wechat', summary: 'Handle WeChat payment notification', tags: ['payment', 'notifications'] })\n .input(WebhookBodySchema)\n .output(notifyMessageOutputSchema),\n alipay: route({ method: 'POST', path: '/payment/notifications/alipay', operationId: 'payment.notifications.alipay', summary: 'Handle Alipay payment notification', tags: ['payment', 'notifications'] })\n .input(WebhookBodySchema)\n .output(notifyMessageOutputSchema),\n stripe: route({ method: 'POST', path: '/payment/notifications/stripe', operationId: 'payment.notifications.stripe', summary: 'Handle Stripe payment notification', tags: ['payment', 'notifications'] })\n .input(WebhookBodySchema)\n .output(haiResultSchema(PaymentStripeNotifyDataSchema)),\n },\n}\n\n/**\n * payment 领域公开 procedure 契约的完整类型。\n * @example\n * ```ts\n * import type { PaymentContract } from '@h-ai/api-contract'\n * import { apiContract } from '@h-ai/api-contract'\n *\n * const contract: PaymentContract = apiContract.payment\n * void contract\n * ```\n */\nexport type PaymentContract = typeof paymentContract\n"]}
|