Files
order_site/apps/backend/src/repositories/fulfillment-profile-repo.ts
T
2026-05-27 13:12:07 +08:00

156 lines
4.0 KiB
TypeScript

import { query, withTransaction } from '../db/client.js'
type FulfillmentProfileRow = {
id: number
profile_key: string
name: string
executor_key: string
requires_claim: boolean
auto_dispatch: boolean
inventory_strategy: string
config_json: string | Record<string, unknown>
created_at: string
updated_at: string
}
type FulfillmentProfileRequirementRow = {
id: number
profile_id: number
role_key: string
roleKey?: string
credential_type: string
credentialType?: string
quantity_per_unit: number
is_required: boolean
config_json: string | Record<string, unknown>
created_at: string
updated_at: string
}
type FulfillmentProfileUpsertInput = {
profileKey: string
name: string
executorKey: string
requiresClaim?: boolean
autoDispatch?: boolean
inventoryStrategy?: string
configJson?: string | Record<string, unknown>
createdAt: string
updatedAt: string
}
export type FulfillmentProfileRequirementInput = {
roleKey: string
credentialType: string
quantityPerUnit?: number | string
isRequired?: boolean
configJson?: string | Record<string, unknown>
}
export async function getFulfillmentProfileByKey(profileKey: string): Promise<FulfillmentProfileRow | null> {
const result = await query<FulfillmentProfileRow>(
'SELECT * FROM fulfillment_profiles WHERE profile_key = $1 LIMIT 1',
[String(profileKey || '').trim()],
)
return result.rows[0] || null
}
export async function upsertFulfillmentProfile(
input: FulfillmentProfileUpsertInput,
): Promise<FulfillmentProfileRow | null> {
const result = await query<FulfillmentProfileRow>(
`
INSERT INTO fulfillment_profiles (
profile_key,
name,
executor_key,
requires_claim,
auto_dispatch,
inventory_strategy,
config_json,
created_at,
updated_at
) VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9)
ON CONFLICT (profile_key) DO UPDATE
SET
name = EXCLUDED.name,
executor_key = EXCLUDED.executor_key,
requires_claim = EXCLUDED.requires_claim,
auto_dispatch = EXCLUDED.auto_dispatch,
inventory_strategy = EXCLUDED.inventory_strategy,
config_json = EXCLUDED.config_json,
updated_at = EXCLUDED.updated_at
RETURNING *
`,
[
input.profileKey,
input.name,
input.executorKey,
Boolean(input.requiresClaim),
Boolean(input.autoDispatch),
input.inventoryStrategy || 'static_pool',
input.configJson || '{}',
input.createdAt,
input.updatedAt,
],
)
return result.rows[0] || null
}
export async function replaceFulfillmentProfileRequirements(
profileId: number | string,
requirements: FulfillmentProfileRequirementInput[] = [],
timestamp: string,
): Promise<void> {
await withTransaction(async (client) => {
await client.query(
'DELETE FROM fulfillment_profile_requirements WHERE profile_id = $1',
[Number(profileId)],
)
for (const requirement of requirements) {
await client.query(
`
INSERT INTO fulfillment_profile_requirements (
profile_id,
role_key,
credential_type,
quantity_per_unit,
is_required,
config_json,
created_at,
updated_at
) VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8)
`,
[
Number(profileId),
requirement.roleKey,
requirement.credentialType,
Number(requirement.quantityPerUnit || 1),
requirement.isRequired !== false,
requirement.configJson || '{}',
timestamp,
timestamp,
],
)
}
})
}
export async function listFulfillmentProfileRequirements(
profileId: number | string,
): Promise<FulfillmentProfileRequirementRow[]> {
const result = await query<FulfillmentProfileRequirementRow>(
`
SELECT *
FROM fulfillment_profile_requirements
WHERE profile_id = $1
ORDER BY id ASC
`,
[Number(profileId)],
)
return result.rows
}