스킬 정리 및 리팩토링

This commit is contained in:
2026-02-26 09:05:17 +09:00
parent 4c52d6d82f
commit 406af7408a
71 changed files with 3776 additions and 3934 deletions

View File

@@ -1,10 +1,48 @@
import { useState, useCallback } from "react";
import { z } from "zod";
import type { KisRuntimeCredentials } from "@/features/settings/store/use-kis-runtime-store";
import type {
DashboardStockCashOrderRequest,
DashboardStockCashOrderResponse,
} from "@/features/trade/types/trade.types";
import { fetchOrderCash } from "@/features/trade/apis/kis-stock.api";
import { parseKisAccountParts } from "@/lib/kis/account";
const placeOrderRequestSchema = z
.object({
symbol: z.string().trim().regex(/^\d{6}$/),
side: z.enum(["buy", "sell"]),
orderType: z.enum(["limit", "market"]),
quantity: z.number().int().positive(),
price: z.number(),
accountNo: z.string().trim().min(1),
accountProductCode: z.string().trim().optional(),
})
.superRefine((request, ctx) => {
if (request.orderType === "limit" && request.price <= 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["price"],
message: "지정가 주문은 가격이 0보다 커야 합니다.",
});
}
if (request.orderType === "market" && request.price < 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["price"],
message: "시장가 주문은 가격이 0 이상이어야 합니다.",
});
}
if (!parseKisAccountParts(request.accountNo, request.accountProductCode)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["accountNo"],
message: "계좌번호 형식이 올바르지 않습니다. (8-2)",
});
}
});
export function useOrder() {
const [isLoading, setIsLoading] = useState(false);
@@ -28,6 +66,15 @@ export function useOrder() {
setResult(null);
try {
const validationResult = placeOrderRequestSchema.safeParse(request);
if (!validationResult.success) {
setError(
validationResult.error.issues[0]?.message ??
"주문 요청 값이 올바르지 않습니다.",
);
return null;
}
const data = await fetchOrderCash(request, credentials);
setResult(data);
return data;