后端迁移后台管理任务写操作
This commit is contained in:
+52
-46
@@ -1,5 +1,3 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
markInventoryItemDelivered,
|
markInventoryItemDelivered,
|
||||||
releaseReservedInventoryItem,
|
releaseReservedInventoryItem,
|
||||||
@@ -41,15 +39,31 @@ import {
|
|||||||
resolveTaskInventoryGroupCodes,
|
resolveTaskInventoryGroupCodes,
|
||||||
} from './shared.js'
|
} from './shared.js'
|
||||||
|
|
||||||
/** @typedef {import('../../../types/admin-read-inputs.js').AdminEntityIdInput} AdminEntityIdInput */
|
import type {
|
||||||
/** @typedef {import('../../../types/admin-read-inputs.js').AdminViewerSessionInput} AdminViewerSessionInput */
|
AdminEntityIdInput,
|
||||||
/** @typedef {import('../../../types/admin-write-models.js').AdminTaskActionResponse} AdminTaskActionResponse */
|
AdminViewerSessionInput,
|
||||||
/** @typedef {import('../../../types/admin-write-models.js').AdminTaskBindingReleaseResponse} AdminTaskBindingReleaseResponse */
|
} from '../../../types/admin-read-inputs.js'
|
||||||
/** @typedef {import('../../../types/admin-write-models.js').AdminTaskManualDispatchResponse} AdminTaskManualDispatchResponse */
|
import type { AdminTaskManualDispatchInput } from '../../../types/admin-write-inputs.js'
|
||||||
|
import type {
|
||||||
|
AdminTaskActionResponse,
|
||||||
|
AdminTaskBindingReleaseResponse,
|
||||||
|
AdminTaskManualDispatchResponse,
|
||||||
|
} from '../../../types/admin-write-models.js'
|
||||||
|
import type { TaskRow } from '../../../types/repository-rows.js'
|
||||||
|
import type { TaskUpdatePatch } from '../../../types/repository-inputs.js'
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
type CloseAdminTaskDeps = {
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
getRequiredTask?: (taskId: AdminEntityIdInput) => Promise<TaskRow>
|
||||||
export async function releaseAdminTaskInventory(taskId) {
|
listTaskInventoryBindingsByTaskId?: (taskId: AdminEntityIdInput) => Promise<any[]>
|
||||||
|
releaseReservedInventoryItem?: (inventoryItemId: AdminEntityIdInput, updatedAt: string) => Promise<unknown>
|
||||||
|
updateClaimToken?: (tokenId: AdminEntityIdInput, patch: Record<string, unknown>) => Promise<unknown>
|
||||||
|
updateTask?: (taskId: AdminEntityIdInput, patch: TaskUpdatePatch) => Promise<any>
|
||||||
|
createTaskEvent?: (taskId: AdminEntityIdInput, eventType: string, payload: Record<string, unknown>, createdAt: string) => Promise<unknown>
|
||||||
|
closeTencentBrowserSession?: (sessionId: string) => Promise<unknown>
|
||||||
|
nowIso?: () => string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function releaseAdminTaskInventory(taskId: AdminEntityIdInput): Promise<AdminTaskActionResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const primaryInventoryItemId = getTaskPrimaryInventoryItemId(task)
|
const primaryInventoryItemId = getTaskPrimaryInventoryItemId(task)
|
||||||
|
|
||||||
@@ -81,10 +95,10 @@ export async function releaseAdminTaskInventory(taskId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskBindingReleaseResponse>} */
|
export async function releaseAdminTaskInventoryBinding(
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
taskId: AdminEntityIdInput,
|
||||||
/** @param {AdminEntityIdInput} bindingId */
|
bindingId: AdminEntityIdInput,
|
||||||
export async function releaseAdminTaskInventoryBinding(taskId, bindingId) {
|
): Promise<AdminTaskBindingReleaseResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const binding = await getTaskInventoryBindingById(Number(bindingId))
|
const binding = await getTaskInventoryBindingById(Number(bindingId))
|
||||||
|
|
||||||
@@ -151,10 +165,10 @@ export async function releaseAdminTaskInventoryBinding(taskId, bindingId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function regenerateAdminTaskClaimLink(
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
taskId: AdminEntityIdInput,
|
||||||
/** @param {AdminViewerSessionInput | null} [session] */
|
session: AdminViewerSessionInput | null = null,
|
||||||
export async function regenerateAdminTaskClaimLink(taskId, session = null) {
|
): Promise<AdminTaskActionResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const primaryClaimTokenId = getTaskPrimaryClaimTokenId(task)
|
const primaryClaimTokenId = getTaskPrimaryClaimTokenId(task)
|
||||||
const viewerContext = createAdminViewerContext(session)
|
const viewerContext = createAdminViewerContext(session)
|
||||||
@@ -204,10 +218,10 @@ export async function regenerateAdminTaskClaimLink(taskId, session = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function confirmAdminTaskAssistedRole(
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
taskId: AdminEntityIdInput,
|
||||||
/** @param {AdminViewerSessionInput | null} [session] */
|
session: AdminViewerSessionInput | null = null,
|
||||||
export async function confirmAdminTaskAssistedRole(taskId, session = null) {
|
): Promise<AdminTaskActionResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const viewerContext = createAdminViewerContext(session)
|
const viewerContext = createAdminViewerContext(session)
|
||||||
ensureViewerCanOperateAssistedTask(task, viewerContext, 'confirm')
|
ensureViewerCanOperateAssistedTask(task, viewerContext, 'confirm')
|
||||||
@@ -219,10 +233,10 @@ export async function confirmAdminTaskAssistedRole(taskId, session = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function redeemAdminTaskAssisted(
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
taskId: AdminEntityIdInput,
|
||||||
/** @param {AdminViewerSessionInput | null} [session] */
|
session: AdminViewerSessionInput | null = null,
|
||||||
export async function redeemAdminTaskAssisted(taskId, session = null) {
|
): Promise<AdminTaskActionResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const viewerContext = createAdminViewerContext(session)
|
const viewerContext = createAdminViewerContext(session)
|
||||||
ensureViewerCanOperateAssistedTask(task, viewerContext, 'redeem')
|
ensureViewerCanOperateAssistedTask(task, viewerContext, 'redeem')
|
||||||
@@ -234,16 +248,12 @@ export async function redeemAdminTaskAssisted(taskId, session = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function closeAdminTask(taskId: AdminEntityIdInput): Promise<AdminTaskActionResponse> {
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
|
||||||
export async function closeAdminTask(taskId) {
|
|
||||||
return closeAdminTaskWithDeps(taskId)
|
return closeAdminTaskWithDeps(taskId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
|
||||||
export async function closeAdminTaskWithDeps(
|
export async function closeAdminTaskWithDeps(
|
||||||
taskId,
|
taskId: AdminEntityIdInput,
|
||||||
{
|
{
|
||||||
getRequiredTask: getTask = getRequiredTask,
|
getRequiredTask: getTask = getRequiredTask,
|
||||||
listTaskInventoryBindingsByTaskId: listBindings = listTaskInventoryBindingsByTaskId,
|
listTaskInventoryBindingsByTaskId: listBindings = listTaskInventoryBindingsByTaskId,
|
||||||
@@ -253,8 +263,8 @@ export async function closeAdminTaskWithDeps(
|
|||||||
createTaskEvent: createEvent = createTaskEvent,
|
createTaskEvent: createEvent = createTaskEvent,
|
||||||
closeTencentBrowserSession: closeSession = closeTencentBrowserSession,
|
closeTencentBrowserSession: closeSession = closeTencentBrowserSession,
|
||||||
nowIso: getNowIso = nowIso,
|
nowIso: getNowIso = nowIso,
|
||||||
} = {},
|
}: CloseAdminTaskDeps = {},
|
||||||
) {
|
): Promise<AdminTaskActionResponse> {
|
||||||
const task = await getTask(taskId)
|
const task = await getTask(taskId)
|
||||||
|
|
||||||
if (task.task_status === 'redeemed') {
|
if (task.task_status === 'redeemed') {
|
||||||
@@ -326,9 +336,7 @@ export async function closeAdminTaskWithDeps(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function markAdminTaskManualReview(taskId: AdminEntityIdInput): Promise<AdminTaskActionResponse> {
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
|
||||||
export async function markAdminTaskManualReview(taskId) {
|
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const updatedTask = await updateTask(task.id, {
|
const updatedTask = await updateTask(task.id, {
|
||||||
task_status: 'manual_review',
|
task_status: 'manual_review',
|
||||||
@@ -342,9 +350,7 @@ export async function markAdminTaskManualReview(taskId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskActionResponse>} */
|
export async function retryAdminTask(taskId: AdminEntityIdInput): Promise<AdminTaskActionResponse> {
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
|
||||||
export async function retryAdminTask(taskId) {
|
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
const now = nowIso()
|
const now = nowIso()
|
||||||
|
|
||||||
@@ -408,7 +414,7 @@ export async function retryAdminTask(taskId) {
|
|||||||
updated_at: now,
|
updated_at: now,
|
||||||
})
|
})
|
||||||
|
|
||||||
const response = {
|
const response: AdminTaskActionResponse = {
|
||||||
task: mapTaskActionPayload(updatedTask),
|
task: mapTaskActionPayload(updatedTask),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,11 +426,11 @@ export async function retryAdminTask(taskId) {
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<AdminTaskManualDispatchResponse>} */
|
export async function completeAdminTaskManualDispatch(
|
||||||
/** @param {AdminEntityIdInput} taskId */
|
taskId: AdminEntityIdInput,
|
||||||
/** @param {{ outcome?: string, resultMessage?: string, deliveryReference?: string, deliveredCredential?: string }} [payload] */
|
payload: AdminTaskManualDispatchInput = {},
|
||||||
/** @param {AdminViewerSessionInput | null} [session] */
|
session: AdminViewerSessionInput | null = null,
|
||||||
export async function completeAdminTaskManualDispatch(taskId, payload = {}, session = null) {
|
): Promise<AdminTaskManualDispatchResponse> {
|
||||||
const task = await getRequiredTask(taskId)
|
const task = await getRequiredTask(taskId)
|
||||||
|
|
||||||
if (!isManualDispatchTask(task)) {
|
if (!isManualDispatchTask(task)) {
|
||||||
@@ -768,6 +768,14 @@
|
|||||||
- `npm run typecheck`
|
- `npm run typecheck`
|
||||||
- `npm run build`
|
- `npm run build`
|
||||||
- `npm test` 共 139 个用例通过
|
- `npm test` 共 139 个用例通过
|
||||||
|
195. 后台 Admin 任务写操作迁移到 `.ts`:
|
||||||
|
- `src/services/admin/write/task-actions.ts`
|
||||||
|
196. Admin 任务库存释放、绑定释放、领取链接重建、半自动确认 / 兑换、关闭任务、转人工复核、重试、人工履约回写已进入 TS 编译链路;entity id、viewer session、手动履约 input、action response、binding release response、依赖注入 close deps 与 task patch 补齐类型
|
||||||
|
197. Docker 内验证通过:
|
||||||
|
- `src/services/admin/*.test.js` 共 8 个用例通过
|
||||||
|
- `npm run typecheck`
|
||||||
|
- `npm run build`
|
||||||
|
- `npm test` 共 139 个用例通过
|
||||||
|
|
||||||
## 下一步建议
|
## 下一步建议
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user