feat: submit batches to status backend
This commit is contained in:
parent
b3bcc2af45
commit
3e2d7b36f2
@ -6,6 +6,7 @@ import {
|
|||||||
} from "../shared/auth-messages";
|
} from "../shared/auth-messages";
|
||||||
import { createBatchSubmitClient } from "../shared/batch-submit-client";
|
import { createBatchSubmitClient } from "../shared/batch-submit-client";
|
||||||
import { createBackendMetricsClient } from "../shared/backend-metrics-client";
|
import { createBackendMetricsClient } from "../shared/backend-metrics-client";
|
||||||
|
import { DEFAULT_BATCH_SUBMIT_BASE_URL } from "../shared/batch-submit-config";
|
||||||
import { DEFAULT_BACKEND_METRICS_BASE_URL } from "../shared/backend-metrics-config";
|
import { DEFAULT_BACKEND_METRICS_BASE_URL } from "../shared/backend-metrics-config";
|
||||||
import { isBackendMetricsSearchRequestMessage } from "../shared/backend-metrics-messages";
|
import { isBackendMetricsSearchRequestMessage } from "../shared/backend-metrics-messages";
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ export function registerBackgroundMessageHandler(
|
|||||||
authClient: createLogtoAuthClient()
|
authClient: createLogtoAuthClient()
|
||||||
});
|
});
|
||||||
submitBatch ??= createBatchSubmitClient({
|
submitBatch ??= createBatchSubmitClient({
|
||||||
baseUrl: "http://127.0.0.1:4319",
|
baseUrl: DEFAULT_BATCH_SUBMIT_BASE_URL,
|
||||||
getAccessToken: () => authController!.getAccessToken(),
|
getAccessToken: () => authController!.getAccessToken(),
|
||||||
sendMessage: () =>
|
sendMessage: () =>
|
||||||
Promise.reject(new Error("background batch submit does not use sendMessage"))
|
Promise.reject(new Error("background batch submit does not use sendMessage"))
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type { BatchPayload } from "../content/market/batch-payload";
|
import type { BatchPayload } from "../content/market/batch-payload";
|
||||||
import { isAuthResponseMessage } from "./auth-messages";
|
import { isAuthResponseMessage } from "./auth-messages";
|
||||||
|
import { DEFAULT_BATCH_SUBMIT_BASE_URL } from "./batch-submit-config";
|
||||||
|
|
||||||
interface FetchResponseLike {
|
interface FetchResponseLike {
|
||||||
json(): Promise<unknown>;
|
json(): Promise<unknown>;
|
||||||
@ -16,11 +17,12 @@ type GetAccessTokenLike = () => Promise<string>;
|
|||||||
type SendMessageLike = (message: unknown) => Promise<unknown>;
|
type SendMessageLike = (message: unknown) => Promise<unknown>;
|
||||||
|
|
||||||
export function createBatchSubmitClient(options: {
|
export function createBatchSubmitClient(options: {
|
||||||
baseUrl: string;
|
baseUrl?: string;
|
||||||
fetchImpl?: FetchLike;
|
fetchImpl?: FetchLike;
|
||||||
getAccessToken?: GetAccessTokenLike;
|
getAccessToken?: GetAccessTokenLike;
|
||||||
sendMessage: SendMessageLike;
|
sendMessage: SendMessageLike;
|
||||||
}) {
|
}) {
|
||||||
|
const baseUrl = options.baseUrl ?? DEFAULT_BATCH_SUBMIT_BASE_URL;
|
||||||
const fetchImpl = options.fetchImpl ?? fetch;
|
const fetchImpl = options.fetchImpl ?? fetch;
|
||||||
const getAccessToken =
|
const getAccessToken =
|
||||||
options.getAccessToken ?? (() => readAccessToken(options.sendMessage));
|
options.getAccessToken ?? (() => readAccessToken(options.sendMessage));
|
||||||
@ -29,7 +31,7 @@ export function createBatchSubmitClient(options: {
|
|||||||
async submitBatch(payload: BatchPayload) {
|
async submitBatch(payload: BatchPayload) {
|
||||||
const token = await getAccessToken();
|
const token = await getAccessToken();
|
||||||
const response = await fetchImpl(
|
const response = await fetchImpl(
|
||||||
new URL("/api/mock/batches", options.baseUrl).toString(),
|
buildBatchSubmitUrl(baseUrl),
|
||||||
{
|
{
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
headers: {
|
headers: {
|
||||||
@ -48,11 +50,15 @@ export function createBatchSubmitClient(options: {
|
|||||||
throw new Error(`batch submit failed: ${response.status}`);
|
throw new Error(`batch submit failed: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
return readBatchSubmitResponse(await response.json());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildBatchSubmitUrl(baseUrl: string): string {
|
||||||
|
return new URL("/api/v1/batch-status/batches", baseUrl).toString();
|
||||||
|
}
|
||||||
|
|
||||||
async function readAccessToken(sendMessage: SendMessageLike): Promise<string> {
|
async function readAccessToken(sendMessage: SendMessageLike): Promise<string> {
|
||||||
const response = await sendMessage({ type: "auth:get-access-token" });
|
const response = await sendMessage({ type: "auth:get-access-token" });
|
||||||
|
|
||||||
@ -67,3 +73,23 @@ async function readAccessToken(sendMessage: SendMessageLike): Promise<string> {
|
|||||||
|
|
||||||
return response.value.accessToken;
|
return response.value.accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readBatchSubmitResponse(payload: unknown): unknown {
|
||||||
|
if (!isRecord(payload)) {
|
||||||
|
throw new Error("batch submit response is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.success !== true) {
|
||||||
|
const message =
|
||||||
|
typeof payload.msg === "string" && payload.msg.trim()
|
||||||
|
? payload.msg
|
||||||
|
: "batch submit failed";
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "data" in payload ? payload.data : payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null;
|
||||||
|
}
|
||||||
|
|||||||
1
src/shared/batch-submit-config.ts
Normal file
1
src/shared/batch-submit-config.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const DEFAULT_BATCH_SUBMIT_BASE_URL = "http://192.168.31.29:8083";
|
||||||
@ -1,8 +1,13 @@
|
|||||||
import { describe, expect, test, vi } from "vitest";
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
|
import { DEFAULT_BATCH_SUBMIT_BASE_URL } from "../src/shared/batch-submit-config";
|
||||||
import { createBatchSubmitClient } from "../src/shared/batch-submit-client";
|
import { createBatchSubmitClient } from "../src/shared/batch-submit-client";
|
||||||
|
|
||||||
describe("batch-submit-client", () => {
|
describe("batch-submit-client", () => {
|
||||||
|
test("exports the default batch submit base url", () => {
|
||||||
|
expect(DEFAULT_BATCH_SUBMIT_BASE_URL).toBe("http://192.168.31.29:8083");
|
||||||
|
});
|
||||||
|
|
||||||
test("posts the batch payload with a Bearer token", async () => {
|
test("posts the batch payload with a Bearer token", async () => {
|
||||||
const sendMessage = vi.fn(async () => ({
|
const sendMessage = vi.fn(async () => ({
|
||||||
ok: true,
|
ok: true,
|
||||||
@ -12,7 +17,15 @@ describe("batch-submit-client", () => {
|
|||||||
const fetchImpl = vi.fn(async () => ({
|
const fetchImpl = vi.fn(async () => ({
|
||||||
ok: true,
|
ok: true,
|
||||||
status: 200,
|
status: 200,
|
||||||
json: async () => ({ acceptedCount: 2, ok: true })
|
json: async () => ({
|
||||||
|
data: {
|
||||||
|
batch_id: "p7pdhhtde8kj-2026-04-22T12:30:00.000Z",
|
||||||
|
status: true,
|
||||||
|
talent_count: 1
|
||||||
|
},
|
||||||
|
msg: "",
|
||||||
|
success: true
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const client = createBatchSubmitClient({
|
const client = createBatchSubmitClient({
|
||||||
@ -32,7 +45,7 @@ describe("batch-submit-client", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(fetchImpl).toHaveBeenCalledWith(
|
expect(fetchImpl).toHaveBeenCalledWith(
|
||||||
"http://127.0.0.1:4319/api/mock/batches",
|
"http://127.0.0.1:4319/api/v1/batch-status/batches",
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
authors: [{ authorId: "111", authorName: "达人A" }],
|
authors: [{ authorId: "111", authorName: "达人A" }],
|
||||||
@ -52,6 +65,38 @@ describe("batch-submit-client", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("throws when the batch submit api returns success false", async () => {
|
||||||
|
const client = createBatchSubmitClient({
|
||||||
|
baseUrl: "http://127.0.0.1:4319",
|
||||||
|
fetchImpl: vi.fn(async () => ({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
json: async () => ({
|
||||||
|
data: null,
|
||||||
|
msg: "duplicate batch id",
|
||||||
|
success: false
|
||||||
|
})
|
||||||
|
})),
|
||||||
|
sendMessage: vi.fn(async () => ({
|
||||||
|
ok: true,
|
||||||
|
type: "auth:token",
|
||||||
|
value: { accessToken: "abc123" }
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
client.submitBatch({
|
||||||
|
authors: [],
|
||||||
|
batchId: "批次A-2026-04-22T12:30:00.000Z",
|
||||||
|
batchName: "批次A",
|
||||||
|
createdAt: "2026-04-22T12:30:00.000Z",
|
||||||
|
creatorName: "王少卿",
|
||||||
|
logtoUserId: "p7pdhhtde8kj",
|
||||||
|
resource: "https://talent-search.intelligrow.cn"
|
||||||
|
})
|
||||||
|
).rejects.toThrow(/duplicate batch id/i);
|
||||||
|
});
|
||||||
|
|
||||||
test("throws on unauthorized responses", async () => {
|
test("throws on unauthorized responses", async () => {
|
||||||
const client = createBatchSubmitClient({
|
const client = createBatchSubmitClient({
|
||||||
baseUrl: "http://127.0.0.1:4319",
|
baseUrl: "http://127.0.0.1:4319",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user