重构后台管理服务并推进渐进式类型化
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
// @ts-check
|
||||
|
||||
import { query, withTransaction } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-inputs.js').InventoryCreateItemInput} InventoryCreateItemInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').InventoryListQueryInput} InventoryListQueryInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').InventorySkuSuggestionQueryInput} InventorySkuSuggestionQueryInput */
|
||||
/** @typedef {import('../types/repository-rows.js').InventoryItemRow} InventoryItemRow */
|
||||
/** @typedef {import('../types/repository-rows.js').InventoryListQueryResult} InventoryListQueryResult */
|
||||
/** @typedef {import('../types/repository-rows.js').InventorySkuSuggestionRow} InventorySkuSuggestionRow */
|
||||
|
||||
const INVENTORY_ITEM_SELECT = `
|
||||
SELECT
|
||||
ii.id,
|
||||
@@ -26,6 +35,7 @@ const INVENTORY_ITEM_SELECT = `
|
||||
LEFT JOIN fulfillment_tasks ft ON ft.id = tib.task_id
|
||||
`
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function findFirstAvailableInventoryItemBySkuCode(skuCode, credentialType = 'tencent_code') {
|
||||
const result = await query(
|
||||
`${INVENTORY_ITEM_SELECT}
|
||||
@@ -35,9 +45,10 @@ export async function findFirstAvailableInventoryItemBySkuCode(skuCode, credenti
|
||||
[skuCode, credentialType],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {InventoryItemRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function assignReservedInventoryItem(inventoryItemId, taskId, updatedAt, roleKey = 'primary_code') {
|
||||
return withTransaction(async (client) => {
|
||||
const inventoryResult = await client.query(
|
||||
@@ -76,6 +87,7 @@ export async function assignReservedInventoryItem(inventoryItemId, taskId, updat
|
||||
})
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function getInventoryItemById(inventoryItemId) {
|
||||
const result = await query(
|
||||
`${INVENTORY_ITEM_SELECT}
|
||||
@@ -84,9 +96,10 @@ export async function getInventoryItemById(inventoryItemId) {
|
||||
[Number(inventoryItemId)],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {InventoryItemRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function markInventoryItemDelivered(inventoryItemId, deliveredAt) {
|
||||
return withTransaction(async (client) => {
|
||||
await client.query(
|
||||
@@ -111,6 +124,7 @@ export async function markInventoryItemDelivered(inventoryItemId, deliveredAt) {
|
||||
})
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function markInventoryItemConsumed(inventoryItemId, reason, consumedAt) {
|
||||
return withTransaction(async (client) => {
|
||||
await client.query(
|
||||
@@ -139,6 +153,8 @@ export async function markInventoryItemConsumed(inventoryItemId, reason, consume
|
||||
})
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryListQueryResult>} */
|
||||
/** @param {InventoryListQueryInput} [queryInput] */
|
||||
export async function listInventoryItems({
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
@@ -146,7 +162,7 @@ export async function listInventoryItems({
|
||||
credentialType = '',
|
||||
status = '',
|
||||
batchNo = '',
|
||||
} = {}) {
|
||||
} = /** @type {InventoryListQueryInput} */ ({})) {
|
||||
const offset = (page - 1) * pageSize
|
||||
const filters = []
|
||||
const params = []
|
||||
@@ -188,16 +204,18 @@ export async function listInventoryItems({
|
||||
)
|
||||
|
||||
return {
|
||||
items: itemsResult.rows,
|
||||
items: /** @type {InventoryItemRow[]} */ (itemsResult.rows),
|
||||
total: Number(totalResult.rows[0]?.total || 0),
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventorySkuSuggestionRow[]>} */
|
||||
/** @param {InventorySkuSuggestionQueryInput} [queryInput] */
|
||||
export async function listInventorySkuSuggestions({
|
||||
credentialType = '',
|
||||
keyword = '',
|
||||
limit = 50,
|
||||
} = {}) {
|
||||
} = /** @type {InventorySkuSuggestionQueryInput} */ ({})) {
|
||||
const filters = []
|
||||
const params = []
|
||||
|
||||
@@ -238,9 +256,10 @@ export async function listInventorySkuSuggestions({
|
||||
params,
|
||||
)
|
||||
|
||||
return result.rows
|
||||
return /** @type {InventorySkuSuggestionRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
/** @param {InventoryCreateItemInput[]} rows */
|
||||
export async function createInventoryItems(rows) {
|
||||
let created = 0
|
||||
|
||||
@@ -284,6 +303,7 @@ export async function createInventoryItems(rows) {
|
||||
return created
|
||||
}
|
||||
|
||||
/** @returns {Promise<InventoryItemRow | null>} */
|
||||
export async function releaseReservedInventoryItem(inventoryItemId, updatedAt) {
|
||||
return withTransaction(async (client) => {
|
||||
await client.query(
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
import { query } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-inputs.js').OrderItemReplaceInput} OrderItemReplaceInput */
|
||||
/** @typedef {import('../types/repository-rows.js').OrderItemRow} OrderItemRow */
|
||||
|
||||
/** @returns {Promise<OrderItemRow[]>} */
|
||||
export async function listOrderItemsByOrderId(orderId) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -11,9 +17,11 @@ export async function listOrderItemsByOrderId(orderId) {
|
||||
[Number(orderId)],
|
||||
)
|
||||
|
||||
return result.rows
|
||||
return /** @type {OrderItemRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderItemRow[]>} */
|
||||
/** @param {OrderItemReplaceInput[]} items */
|
||||
export async function replaceOrderItems(orderId, items) {
|
||||
await query('DELETE FROM order_items WHERE order_id = $1', [Number(orderId)])
|
||||
|
||||
@@ -47,7 +55,8 @@ export async function replaceOrderItems(orderId, items) {
|
||||
return listOrderItemsByOrderId(orderId)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderItemRow | null>} */
|
||||
export async function getOrderItemById(orderItemId) {
|
||||
const result = await query('SELECT * FROM order_items WHERE id = $1 LIMIT 1', [Number(orderItemId)])
|
||||
return result.rows[0] || null
|
||||
return /** @type {OrderItemRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
// @ts-check
|
||||
|
||||
import { query } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-inputs.js').OrderUpsertInput} OrderUpsertInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').OrderListQueryInput} OrderListQueryInput */
|
||||
/** @typedef {import('../types/repository-rows.js').OrderListQueryResult} OrderListQueryResult */
|
||||
/** @typedef {import('../types/repository-rows.js').OrderListRow} OrderListRow */
|
||||
/** @typedef {import('../types/repository-rows.js').OrderRow} OrderRow */
|
||||
|
||||
/** @returns {Promise<OrderRow | null>} */
|
||||
export async function findOrderByPlatformOrderId({ provider = 'agiso', platform, shopId = '', platformOrderId }) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -11,9 +20,11 @@ export async function findOrderByPlatformOrderId({ provider = 'agiso', platform,
|
||||
[provider, platform, shopId, platformOrderId],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {OrderRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderRow | null>} */
|
||||
/** @param {OrderUpsertInput} input */
|
||||
export async function createOrder(input) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -57,9 +68,11 @@ export async function createOrder(input) {
|
||||
],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {OrderRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderRow | null>} */
|
||||
/** @param {OrderUpsertInput} input */
|
||||
export async function updateOrder(orderId, input) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -101,14 +114,17 @@ export async function updateOrder(orderId, input) {
|
||||
],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {OrderRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderRow | null>} */
|
||||
export async function getOrderById(orderId) {
|
||||
const result = await query('SELECT * FROM orders WHERE id = $1 LIMIT 1', [Number(orderId)])
|
||||
return result.rows[0] || null
|
||||
return /** @type {OrderRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<OrderListQueryResult>} */
|
||||
/** @param {OrderListQueryInput} [queryInput] */
|
||||
export async function listOrders({
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
@@ -117,7 +133,7 @@ export async function listOrders({
|
||||
skuCode = '',
|
||||
dateFrom = '',
|
||||
dateTo = '',
|
||||
} = {}) {
|
||||
} = /** @type {OrderListQueryInput} */ ({})) {
|
||||
const offset = (page - 1) * pageSize
|
||||
const filters = []
|
||||
const params = []
|
||||
@@ -166,7 +182,7 @@ export async function listOrders({
|
||||
)
|
||||
|
||||
return {
|
||||
items: itemsResult.rows,
|
||||
items: /** @type {OrderListRow[]} */ (itemsResult.rows),
|
||||
total: Number(totalResult.rows[0]?.total || 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
import { query } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-rows.js').TaskInventoryBindingRow} TaskInventoryBindingRow */
|
||||
/** @typedef {import('../types/repository-rows.js').TaskInventoryBindingSummaryRow} TaskInventoryBindingSummaryRow */
|
||||
|
||||
/** @returns {Promise<TaskInventoryBindingRow[]>} */
|
||||
export async function listTaskInventoryBindingsByTaskId(taskId) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -29,9 +35,10 @@ export async function listTaskInventoryBindingsByTaskId(taskId) {
|
||||
[Number(taskId)],
|
||||
)
|
||||
|
||||
return result.rows
|
||||
return /** @type {TaskInventoryBindingRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskInventoryBindingRow | null>} */
|
||||
export async function getTaskInventoryBindingById(bindingId) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -61,9 +68,10 @@ export async function getTaskInventoryBindingById(bindingId) {
|
||||
[Number(bindingId)],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {TaskInventoryBindingRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskInventoryBindingSummaryRow[]>} */
|
||||
export async function listTaskInventoryBindingSummariesByTaskIds(taskIds = []) {
|
||||
const normalizedTaskIds = Array.from(new Set((Array.isArray(taskIds) ? taskIds : [])
|
||||
.map((value) => Number(value))
|
||||
@@ -89,5 +97,5 @@ export async function listTaskInventoryBindingSummariesByTaskIds(taskIds = []) {
|
||||
[normalizedTaskIds],
|
||||
)
|
||||
|
||||
return result.rows
|
||||
return /** @type {TaskInventoryBindingSummaryRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
// @ts-check
|
||||
|
||||
import { query, withTransaction } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-inputs.js').TaskCreateInput} TaskCreateInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').TaskListQueryInput} TaskListQueryInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').TaskTencentContextPatch} TaskTencentContextPatch */
|
||||
/** @typedef {import('../types/repository-inputs.js').TaskUpdatePatch} TaskUpdatePatch */
|
||||
/** @typedef {import('../types/repository-rows.js').TaskListQueryResult} TaskListQueryResult */
|
||||
/** @typedef {import('../types/repository-rows.js').TaskRow} TaskRow */
|
||||
|
||||
const TASK_FIELDS = `
|
||||
ft.*,
|
||||
ct.id AS primary_claim_token_id,
|
||||
@@ -52,6 +61,7 @@ function buildTaskSelect(extraFields = '') {
|
||||
return `SELECT ${fieldSql} ${TASK_JOINS}`
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow[]>} */
|
||||
export async function listTasksByOrderId(orderId) {
|
||||
const result = await query(
|
||||
`${buildTaskSelect()}
|
||||
@@ -59,9 +69,11 @@ export async function listTasksByOrderId(orderId) {
|
||||
ORDER BY ft.id ASC`,
|
||||
[Number(orderId)],
|
||||
)
|
||||
return result.rows
|
||||
return /** @type {TaskRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow | null>} */
|
||||
/** @param {TaskCreateInput} input */
|
||||
export async function createTask(input) {
|
||||
return withTransaction(async (client) => {
|
||||
const taskResult = await client.query(
|
||||
@@ -139,6 +151,8 @@ export async function createTask(input) {
|
||||
})
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow | null>} */
|
||||
/** @param {TaskUpdatePatch} patch */
|
||||
export async function updateTask(taskId, patch) {
|
||||
const current = await getTaskById(taskId)
|
||||
if (!current) {
|
||||
@@ -212,10 +226,12 @@ export async function updateTask(taskId, patch) {
|
||||
})
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow | null>} */
|
||||
export async function getTaskById(taskId) {
|
||||
return getTaskByIdWithExecutor(query, taskId)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow | null>} */
|
||||
export async function findTaskByClaimTokenId(claimTokenId) {
|
||||
const result = await query(
|
||||
`${buildTaskSelect()}
|
||||
@@ -224,9 +240,11 @@ export async function findTaskByClaimTokenId(claimTokenId) {
|
||||
LIMIT 1`,
|
||||
[Number(claimTokenId)],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
return /** @type {TaskRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskListQueryResult>} */
|
||||
/** @param {TaskListQueryInput} [queryInput] */
|
||||
export async function listTasks({
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
@@ -237,7 +255,7 @@ export async function listTasks({
|
||||
roleId = '',
|
||||
dateFrom = '',
|
||||
dateTo = '',
|
||||
} = {}) {
|
||||
} = /** @type {TaskListQueryInput} */ ({})) {
|
||||
const offset = (page - 1) * pageSize
|
||||
const filters = []
|
||||
const params = []
|
||||
@@ -301,11 +319,12 @@ export async function listTasks({
|
||||
)
|
||||
|
||||
return {
|
||||
items: itemsResult.rows,
|
||||
items: /** @type {TaskRow[]} */ (itemsResult.rows),
|
||||
total: Number(totalResult.rows[0]?.total || 0),
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {TaskTencentContextPatch} patch */
|
||||
async function upsertTencentBrowserContextWithClient(client, taskId, patch = {}, timestamp) {
|
||||
const currentResult = await client.query(
|
||||
'SELECT * FROM tencent_browser_contexts WHERE task_id = $1 LIMIT 1',
|
||||
@@ -399,6 +418,7 @@ async function upsertTencentBrowserContextWithClient(client, taskId, patch = {},
|
||||
)
|
||||
}
|
||||
|
||||
/** @returns {Promise<TaskRow | null>} */
|
||||
async function getTaskByIdWithExecutor(executor, taskId) {
|
||||
const result = await executor(
|
||||
`${buildTaskSelect()}
|
||||
@@ -406,7 +426,7 @@ async function getTaskByIdWithExecutor(executor, taskId) {
|
||||
LIMIT 1`,
|
||||
[Number(taskId)],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
return /** @type {TaskRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
function containsTencentPatch(patch = {}) {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
// @ts-check
|
||||
|
||||
import { query } from '../db/client.js'
|
||||
|
||||
/** @typedef {import('../types/repository-inputs.js').WebhookEventCreateInput} WebhookEventCreateInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').WebhookEventListQueryInput} WebhookEventListQueryInput */
|
||||
/** @typedef {import('../types/repository-inputs.js').WebhookEventUpdatePatch} WebhookEventUpdatePatch */
|
||||
/** @typedef {import('../types/repository-rows.js').WebhookEventListQueryResult} WebhookEventListQueryResult */
|
||||
/** @typedef {import('../types/repository-rows.js').WebhookEventRow} WebhookEventRow */
|
||||
|
||||
/** @returns {Promise<WebhookEventRow | null>} */
|
||||
/** @param {WebhookEventCreateInput} input */
|
||||
export async function createWebhookEvent(input) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -39,9 +49,11 @@ export async function createWebhookEvent(input) {
|
||||
],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {WebhookEventRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<WebhookEventRow | null>} */
|
||||
/** @param {WebhookEventUpdatePatch} patch */
|
||||
export async function updateWebhookEvent(eventId, patch) {
|
||||
const current = await getWebhookEventById(eventId)
|
||||
if (!current) {
|
||||
@@ -62,14 +74,17 @@ export async function updateWebhookEvent(eventId, patch) {
|
||||
[Boolean(next.processed), next.process_error || '', next.related_order_id || null, Number(eventId)],
|
||||
)
|
||||
|
||||
return result.rows[0] || null
|
||||
return /** @type {WebhookEventRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<WebhookEventRow | null>} */
|
||||
export async function getWebhookEventById(eventId) {
|
||||
const result = await query('SELECT * FROM webhook_events WHERE id = $1 LIMIT 1', [Number(eventId)])
|
||||
return result.rows[0] || null
|
||||
return /** @type {WebhookEventRow | null} */ (result.rows[0] || null)
|
||||
}
|
||||
|
||||
/** @returns {Promise<WebhookEventListQueryResult>} */
|
||||
/** @param {WebhookEventListQueryInput} [queryInput] */
|
||||
export async function listWebhookEvents({
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
@@ -80,7 +95,7 @@ export async function listWebhookEvents({
|
||||
relatedOrderId = '',
|
||||
dateFrom = '',
|
||||
dateTo = '',
|
||||
} = {}) {
|
||||
} = /** @type {WebhookEventListQueryInput} */ ({})) {
|
||||
const offset = (page - 1) * pageSize
|
||||
const filters = []
|
||||
const params = []
|
||||
@@ -137,11 +152,12 @@ export async function listWebhookEvents({
|
||||
)
|
||||
|
||||
return {
|
||||
items: itemsResult.rows,
|
||||
items: /** @type {WebhookEventRow[]} */ (itemsResult.rows),
|
||||
total: Number(totalResult.rows[0]?.total || 0),
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {Promise<WebhookEventRow[]>} */
|
||||
export async function listWebhookEventsByOrderId(orderId) {
|
||||
const result = await query(
|
||||
`
|
||||
@@ -153,5 +169,5 @@ export async function listWebhookEventsByOrderId(orderId) {
|
||||
[Number(orderId)],
|
||||
)
|
||||
|
||||
return result.rows
|
||||
return /** @type {WebhookEventRow[]} */ (result.rows)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user