后端迁移后台管理读侧映射

This commit is contained in:
yml
2026-05-21 16:49:50 +08:00
parent 1ac6b849b1
commit 89754802d1
5 changed files with 36 additions and 36 deletions
@@ -1,19 +1,13 @@
// @ts-check
import { getInventoryItemById } from '../../repositories/inventory-repo.js' import { getInventoryItemById } from '../../repositories/inventory-repo.js'
import { getOrderById } from '../../repositories/order-repo.js' import { getOrderById } from '../../repositories/order-repo.js'
import { getTaskById } from '../../repositories/task-repo.js' import { getTaskById } from '../../repositories/task-repo.js'
import { createHttpError } from '../../utils/http.js' import { createHttpError } from '../../utils/http.js'
import { mapAdminTaskSummary } from './admin-task-read-helpers.js' import { mapAdminTaskSummary } from './admin-task-read-helpers.js'
/** @typedef {import('../../types/admin-read-models.js').AdminInventoryItemListItem} AdminInventoryItemListItem */ import type { AdminInventoryItemListItem } from '../../types/admin-read-models.js'
/** @typedef {import('../../types/repository-rows.js').InventoryItemRow} InventoryItemRow */ import type { InventoryItemRow } from '../../types/repository-rows.js'
/** export async function mapAdminInventoryListItem(item: InventoryItemRow): Promise<AdminInventoryItemListItem> {
* @param {InventoryItemRow} item
* @returns {Promise<AdminInventoryItemListItem>}
*/
export async function mapAdminInventoryListItem(item) {
const task = item.reserved_by_task_id ? await getTaskById(item.reserved_by_task_id) : null const task = item.reserved_by_task_id ? await getTaskById(item.reserved_by_task_id) : null
const order = task?.order_id ? await getOrderById(task.order_id) : null const order = task?.order_id ? await getOrderById(task.order_id) : null
const taskSummary = task ? mapAdminTaskSummary(task) : null const taskSummary = task ? mapAdminTaskSummary(task) : null
@@ -38,7 +32,7 @@ export async function mapAdminInventoryListItem(item) {
} }
} }
export async function getRequiredInventoryItem(inventoryItemId) { export async function getRequiredInventoryItem(inventoryItemId: number | string): Promise<InventoryItemRow> {
const inventoryItem = await getInventoryItemById(Number(inventoryItemId)) const inventoryItem = await getInventoryItemById(Number(inventoryItemId))
if (!inventoryItem) { if (!inventoryItem) {
@@ -1,19 +1,13 @@
// @ts-check
import { listOrderItemsByOrderId } from '../../repositories/order-item-repo.js' import { listOrderItemsByOrderId } from '../../repositories/order-item-repo.js'
import { listTasksByOrderId } from '../../repositories/task-repo.js' import { listTasksByOrderId } from '../../repositories/task-repo.js'
import { formatFenToAmount, normalizeFen } from '../../utils/money.js' import { formatFenToAmount, normalizeFen } from '../../utils/money.js'
import { resolveDisplayShopName, resolveOrderItemTitle } from './admin-read-shared-helpers.js' import { resolveDisplayShopName, resolveOrderItemTitle } from './admin-read-shared-helpers.js'
import { buildOrderBindingSummary, getTaskBindingSummaryMap } from './admin-task-read-helpers.js' import { buildOrderBindingSummary, getTaskBindingSummaryMap } from './admin-task-read-helpers.js'
/** @typedef {import('../../types/admin-read-models.js').AdminOrderListItem} AdminOrderListItem */ import type { AdminOrderListItem } from '../../types/admin-read-models.js'
/** @typedef {import('../../types/repository-rows.js').OrderListRow} OrderListRow */ import type { OrderItemRow, OrderListRow } from '../../types/repository-rows.js'
/** export async function mapAdminOrderListItem(item: OrderListRow): Promise<AdminOrderListItem> {
* @param {OrderListRow} item
* @returns {Promise<AdminOrderListItem>}
*/
export async function mapAdminOrderListItem(item) {
const [tasks, orderItems] = await Promise.all([ const [tasks, orderItems] = await Promise.all([
listTasksByOrderId(item.id), listTasksByOrderId(item.id),
listOrderItemsByOrderId(item.id), listOrderItemsByOrderId(item.id),
@@ -55,7 +49,7 @@ export async function mapAdminOrderListItem(item) {
} }
} }
export function summarizeOrderItems(items) { export function summarizeOrderItems(items: OrderItemRow[] | null | undefined): string {
const normalizedItems = Array.isArray(items) ? items : [] const normalizedItems = Array.isArray(items) ? items : []
if (normalizedItems.length === 0) { if (normalizedItems.length === 0) {
@@ -1,5 +1,3 @@
// @ts-check
export { export {
getRequiredInventoryItem, getRequiredInventoryItem,
mapAdminInventoryListItem, mapAdminInventoryListItem,
@@ -1,19 +1,22 @@
// @ts-check
import { listTasksByOrderId } from '../../repositories/task-repo.js' import { listTasksByOrderId } from '../../repositories/task-repo.js'
import { formatFenToAmount, parseAmountToFen } from '../../utils/money.js' import { formatFenToAmount, parseAmountToFen } from '../../utils/money.js'
import { extractAgisoTradePayload, resolveAgisoTradePlatformOrderId } from '../order/agiso-trade-parsing.js' import { extractAgisoTradePayload, resolveAgisoTradePlatformOrderId } from '../order/agiso-trade-parsing.js'
import { safeParseJson } from './admin-query-utils.js' import { safeParseJson } from './admin-query-utils.js'
import { resolveDisplayShopName } from './admin-read-shared-helpers.js' import { resolveDisplayShopName } from './admin-read-shared-helpers.js'
/** @typedef {import('../../types/admin-read-models.js').AdminWebhookEventListItem} AdminWebhookEventListItem */ import type { AdminWebhookEventListItem } from '../../types/admin-read-models.js'
/** @typedef {import('../../types/repository-rows.js').WebhookEventRow} WebhookEventRow */ import type { WebhookEventRow } from '../../types/repository-rows.js'
/** type JsonRecord = Record<string, any>
* @param {WebhookEventRow} item
* @returns {Promise<AdminWebhookEventListItem>} type MapAdminWebhookEventOptions = {
*/ includeRaw?: boolean
export async function mapAdminWebhookEvent(item, { includeRaw = false } = {}) { }
export async function mapAdminWebhookEvent(
item: WebhookEventRow,
{ includeRaw = false }: MapAdminWebhookEventOptions = {},
): Promise<AdminWebhookEventListItem> {
const headers = normalizeRecord(safeParseJson(item.headers_json)) const headers = normalizeRecord(safeParseJson(item.headers_json))
const query = normalizeRecord(safeParseJson(item.query_json)) const query = normalizeRecord(safeParseJson(item.query_json))
const body = normalizeRecord(safeParseJson(item.body_json)) const body = normalizeRecord(safeParseJson(item.body_json))
@@ -131,11 +134,11 @@ export async function mapAdminWebhookEvent(item, { includeRaw = false } = {}) {
} }
} }
function extractWebhookPayload(body) { function extractWebhookPayload(body: JsonRecord): JsonRecord {
return extractAgisoTradePayload(body) return extractAgisoTradePayload(body)
} }
function extractWebhookItemSources(payload) { function extractWebhookItemSources(payload: unknown): JsonRecord[] {
const normalizedPayload = normalizeRecord(payload) const normalizedPayload = normalizeRecord(payload)
const candidates = [ const candidates = [
normalizedPayload.orders, normalizedPayload.orders,
@@ -167,7 +170,7 @@ function extractWebhookItemSources(payload) {
return [] return []
} }
export function resolveWebhookVisibilityLevel(processError) { export function resolveWebhookVisibilityLevel(processError: unknown): string {
const normalized = String(processError || '').trim() const normalized = String(processError || '').trim()
if (normalized.startsWith('ignored_')) { if (normalized.startsWith('ignored_')) {
@@ -177,11 +180,11 @@ export function resolveWebhookVisibilityLevel(processError) {
return 'important' return 'important'
} }
function normalizeRecord(value) { function normalizeRecord(value: unknown): JsonRecord {
return value && typeof value === 'object' && !Array.isArray(value) ? value : {} return value && typeof value === 'object' && !Array.isArray(value) ? value : {}
} }
function pickFirstNonEmpty(values) { function pickFirstNonEmpty(values: unknown[]): string {
for (const value of values) { for (const value of values) {
if (typeof value === 'string' && value.trim()) { if (typeof value === 'string' && value.trim()) {
return value.trim() return value.trim()
+11
View File
@@ -715,6 +715,17 @@
- `npm run typecheck` - `npm run typecheck`
- `npm run build` - `npm run build`
- `npm test` 共 139 个用例通过 - `npm test` 共 139 个用例通过
177. 后台 Admin 读侧聚合与订单 / 库存 / Webhook 映射 helper 迁移到 `.ts`
- `src/services/admin/admin-inventory-read-helpers.ts`
- `src/services/admin/admin-order-read-helpers.ts`
- `src/services/admin/admin-webhook-read-helpers.ts`
- `src/services/admin/admin-service.ts`
178. Admin 库存占用任务映射、订单商品摘要、Webhook 原始 payload 展开与后台服务聚合出口已进入 TS 编译链路;列表 row、Webhook options、动态 JSON record 与导出入口补齐类型
179. Docker 内验证通过:
- `src/services/admin/*.test.js` 共 8 个用例通过
- `npm run typecheck`
- `npm run build`
- `npm test` 共 139 个用例通过
## 下一步建议 ## 下一步建议