收紧后端 TypeScript:统一 Json 类型与 TaskContext 契约

关闭 allowJs;集中 JsonObject 定义并替换分散 any 别名;parseTaskContext 返回 TaskContext;任务详情 API 标注 AdminTaskDetailView;测试减少 as any。
This commit is contained in:
yml2213
2026-07-10 15:52:05 +08:00
parent e7244eaa5e
commit 8bcd9bbd81
79 changed files with 415 additions and 259 deletions
@@ -2,6 +2,7 @@ import { createHttpError } from '../../utils/http.js'
import { parseTaskContext } from '../../utils/task-json.js'
import { isTaskFinalStatus, normalizeTaskStatus, TASK_STATUS } from '../../domain/task-status.js'
import type { TaskRow } from '../../types/repository/rows.js'
import type { JsonObject } from '../../types/json.js'
export type ClaimIdentity = {
expectedUid: string
@@ -9,8 +10,6 @@ export type ClaimIdentity = {
source: string
}
type JsonObject = Record<string, any>
const CLAIM_UID_MAX_LENGTH = 64
export function normalizeClaimUid(value: unknown): string {
@@ -131,10 +130,22 @@ export function assertLewanAutoFulfillmentUidReady(
return expectedUid
}
export type ClaimIdentityAdminSummary = {
expectedUid: string
submittedAt: string | null
source: string
ready: boolean
boundUid: string
boundRoleName: string
uidMatched: boolean | null
compatibilityMode: 'uid' | 'legacy_no_uid'
note: string
}
export function buildClaimIdentityAdminSummary(
context: unknown,
options: { flowLike?: unknown; taskRoleId?: unknown; taskRoleName?: unknown } = {},
) {
): ClaimIdentityAdminSummary {
const identity = getClaimIdentityFromContext(context)
const boundUid = resolveBoundRoleUid(options.flowLike) || normalizeClaimUid(options.taskRoleId)
const flow = isPlainObject(options.flowLike) ? options.flowLike : {}
@@ -11,9 +11,9 @@ import { buildClaimUrl } from './claim-service.js'
import { buildClaimIdentityPayload, getClaimIdentityFromContext } from './claim-identity.js'
import { resolveKuaishouFeifeiH5UrlWithUid } from '../fulfillment/kuaishou-feifei/index.js'
import type { ClaimTokenRow, OrderItemRow, OrderRow, TaskRow } from '../../types/repository/rows.js'
import { asJsonObject, type JsonObject } from '../../types/json.js'
export const CLAIM_TERMINAL_STATUSES = new Set([TASK_STATUS.EXPIRED, TASK_STATUS.CLOSED])
type JsonObject = Record<string, any>
type ClaimContext = {
claimToken: ClaimTokenRow
task: TaskRow
@@ -343,13 +343,13 @@ export function mapClaimKuaishouCloudFulfillment(task: TaskRow, order: OrderRow)
return null
}
const binding = source.binding && typeof source.binding === 'object' ? source.binding : {}
const role = source.role && typeof source.role === 'object' ? source.role : {}
const purchase = source.purchase && typeof source.purchase === 'object' ? source.purchase : {}
const ticket = source.ticket && typeof source.ticket === 'object' ? source.ticket : {}
const dispatch = source.dispatch && typeof source.dispatch === 'object' ? source.dispatch : {}
const returnNumber = source.returnNumber && typeof source.returnNumber === 'object' ? source.returnNumber : {}
const consume = source.consume && typeof source.consume === 'object' ? source.consume : {}
const binding = asJsonObject(source.binding)
const role = asJsonObject(source.role)
const purchase = asJsonObject(source.purchase)
const ticket = asJsonObject(source.ticket)
const dispatch = asJsonObject(source.dispatch)
const returnNumber = asJsonObject(source.returnNumber)
const consume = asJsonObject(source.consume)
const roleName = String(role.name || binding.roleName || '').trim()
const roleId = String(role.rid || binding.roleId || '').trim()
const defaultRoleName = String(role.defaultName || role.defaultRoleName || '').trim()
@@ -3,6 +3,7 @@ import { getTaskById, updateTask, updateTaskStatusIfCurrent } from '../../reposi
import { createHttpError } from '../../utils/http.js'
import { parseTaskContext as parseTaskContextValue } from '../../utils/task-json.js'
import { addHours, nowIso } from '../../utils/time.js'
import { asJsonObject, type JsonObject } from '../../types/json.js'
import {
TASK_STATUS,
canRedeemKuaishouCloudClaimStatus,
@@ -29,7 +30,6 @@ import { buildClaimDetailPayload, getClaimContext } from './kuaishou-cloud-claim
import { syncKuaishouCloudRoleInfo } from './kuaishou-cloud-sync-service.js'
import type { TaskRow } from '../../types/repository/rows.js'
type JsonObject = Record<string, any>
type ClaimDetailPayload = ReturnType<typeof buildClaimDetailPayload>
async function verifyIndustryVoucherTicket(
@@ -537,9 +537,7 @@ function isKuaishouCloudMockTask(task: Partial<TaskRow> | null | undefined) {
function isKuaishouCloudMockContext(context: JsonObject = {}) {
const flow =
context.kuaishouCloudFulfillment && typeof context.kuaishouCloudFulfillment === 'object'
? context.kuaishouCloudFulfillment
: {}
asJsonObject(context.kuaishouCloudFulfillment)
const mock = flow.mock && typeof flow.mock === 'object' ? flow.mock : context.mock
return Boolean(mock && typeof mock === 'object' && mock.enabled === true)
@@ -558,7 +556,7 @@ function buildMockVerifiedKuaishouCloudFlow(value: unknown, timestamp: string) {
return {
...flow,
mock: {
...(source.mock && typeof source.mock === 'object' ? source.mock : {}),
...(asJsonObject(source.mock)),
enabled: true,
},
binding: {
@@ -593,7 +591,7 @@ async function completeMockKuaishouCloudClaimTask(task: TaskRow, timestamp: stri
const nextFlow = {
...flow,
mock: {
...(source.mock && typeof source.mock === 'object' ? source.mock : {}),
...(asJsonObject(source.mock)),
enabled: true,
},
dispatch: {
@@ -5,6 +5,7 @@ import {
refreshKuaishouCloudTaskRoleInfo,
} from '../fulfillment/kuaishou-cloud/index.js'
import type { TaskRow } from '../../types/repository/rows.js'
import { parseTaskContext as parseTaskContextValue } from '../../utils/task-json.js'
export async function syncKuaishouCloudRoleInfo(task: TaskRow) {
const flow = normalizeKuaishouCloudFlow(parseTaskContext(task).kuaishouCloudFulfillment)
@@ -45,20 +46,6 @@ export async function syncKuaishouCloudRoleInfo(task: TaskRow) {
}
}
function parseTaskContext(task: Partial<TaskRow> | null | undefined): Record<string, any> {
const rawValue = task?.context_json
if (!rawValue) {
return {}
}
if (typeof rawValue === 'object') {
return rawValue
}
try {
return JSON.parse(String(rawValue || '{}'))
} catch {
return {}
}
function parseTaskContext(task: Partial<TaskRow> | null | undefined) {
return parseTaskContextValue(task)
}