[st] fix: mock 파일 제거 & statistics 엔티티 수정

This commit is contained in:
2026-04-20 17:56:11 +09:00
parent e8de6d66f8
commit 34a0324124
3 changed files with 16 additions and 299 deletions
@@ -11,13 +11,17 @@ import { CodeSelect } from "@/entities/code";
import {
type ApprovalRequest,
statisticsApprovalApi,
statisticsVerificationDetailColumnInfo,
type StatisticsVerificationFilterState,
type StatisticsVerificationSubFilterState,
statisticsVerificationSummaryColumnInfo,
type StatsInputStatusList,
useStAnlsSidoCombo,
useStAnlsSigunguCombo,
useStatsVrfcRptData,
useStatsVrfcRsltData,
type VerifyResultItem,
} from "@/entities/statistics";
import type { VerifyResultItem } from "@/entities/statistics/model/general-verification-interface";
import type { StatsInputStatusList } from "@/entities/statistics/model/input/statistics-input-status-interface";
import {
Button,
Combobox,
@@ -39,15 +43,6 @@ import {
useComboboxAnchor,
} from "@common/components";
import {
statisticsVerificationDetailColumnInfo,
statisticsVerificationSummaryColumnInfo,
} from "../../../entities/statistics/model/statistics-verification-report/statistics-verification-report-columns";
import type {
StatisticsVerificationFilterState,
StatisticsVerificationSubFilterState,
} from "../../../entities/statistics/model/statistics-verification-report/statistics-verification-report-types";
import DataGrid from "@/components/module/DataGrid";
import { toGridRows } from "@/components/util/grid/gridFunction";
+10
View File
@@ -14,6 +14,7 @@ export {
type JobStatusDto,
type OutlierRecordDto,
} from "./model/analysis/analysis-interface";
export { type VerifyResultItem } from "./model/general-verification-interface";
export {
IMR_DETAIL_VISIBLE_COLUMNS_BY_STATS_CD,
IMR_DETAIL_VISIBLE_COLUMNS_DEFAULT,
@@ -32,6 +33,7 @@ export {
type ImrLogResponse,
} from "./model/imr/imr-interface";
export { imrVerificationHistoryColumns } from "./model/imr/imr-verification-history-columns";
export { type StatsInputStatusList } from "./model/input/statistics-input-status-interface";
export {
type StAnlsDtlListApiResponse,
type StAnlsDtlResponse,
@@ -65,6 +67,14 @@ export {
type ApprovalRequest,
type ApprovalResponse,
} from "./model/statistics-approval-interface";
export {
statisticsVerificationDetailColumnInfo,
statisticsVerificationSummaryColumnInfo,
} from "./model/statistics-verification-report/statistics-verification-report-columns";
export {
type StatisticsVerificationFilterState,
type StatisticsVerificationSubFilterState,
} from "./model/statistics-verification-report/statistics-verification-report-types";
export {
hbArticleColumnInfo,
imrArticleColumnInfo,
@@ -1,288 +0,0 @@
import { fakerKO as faker } from "@faker-js/faker";
import type {
StatisticsVerificationDetailRow,
StatisticsVerificationFilterState,
StatisticsVerificationOption,
StatisticsVerificationSubFilterState,
StatisticsVerificationSummaryRow,
} from "./statistics-verification-report-types";
const NETWORK_DELAY_MS = 300;
export const SIDO_OPTIONS: StatisticsVerificationOption[] = [
{ label: "전체", value: "ALL" },
{ label: "서울특별시", value: "SEOUL" },
{ label: "부산광역시", value: "BUSAN" },
{ label: "대구광역시", value: "DAEGU" },
{ label: "경기도", value: "GYEONGGI" },
];
const SIGUNGU_OPTIONS_BY_SIDO: Record<string, StatisticsVerificationOption[]> =
{
ALL: [{ label: "전체", value: "ALL" }],
SEOUL: [
{ label: "전체", value: "ALL" },
{ label: "중구", value: "SEOUL_JUNGGU" },
{ label: "강남구", value: "SEOUL_GANGNAM" },
],
BUSAN: [
{ label: "전체", value: "ALL" },
{ label: "해운대구", value: "BUSAN_HAEUNDAE" },
{ label: "수영구", value: "BUSAN_SUYEONG" },
],
DAEGU: [
{ label: "전체", value: "ALL" },
{ label: "중구", value: "DAEGU_JUNGGU" },
{ label: "달서구", value: "DAEGU_DALSEO" },
],
GYEONGGI: [
{ label: "전체", value: "ALL" },
{ label: "수원시", value: "GYEONGGI_SUWON" },
{ label: "성남시", value: "GYEONGGI_SEONGNAM" },
],
};
export const STATS_INDICATOR_OPTIONS: StatisticsVerificationOption[] = [
{ label: "통계항목", value: "ALL" },
{ label: "하수도 보급률", value: "SEWERAGE_SUPPLY" },
{ label: "관로 보급 현황", value: "PIPE_STATUS" },
{ label: "분류식 비율", value: "SEPARATED_RATIO" },
];
export const STATUS_OPTIONS: StatisticsVerificationOption[] = [
{ label: "수정완료", value: "DONE" },
{ label: "검토중", value: "REVIEW" },
{ label: "오류", value: "ERROR" },
];
export const APPROVAL_STATUS_OPTIONS: StatisticsVerificationOption[] = [
{ label: "전체", value: "ALL" },
{ label: "승인완료", value: "APPROVED" },
{ label: "반려", value: "REJECTED" },
{ label: "대기", value: "PENDING" },
];
export const DEFAULT_FILTERS: StatisticsVerificationFilterState = {
sido: "ALL",
sigungu: "ALL",
year: "ALL",
statsIndicator: "ALL",
};
export const DEFAULT_SUB_FILTERS: StatisticsVerificationSubFilterState = {
status: "DONE",
approvalStatus: "ALL",
};
export function getYearOptions(): StatisticsVerificationOption[] {
const thisYear = new Date().getFullYear();
return [
{ label: "전체", value: "ALL" },
...Array.from({ length: 5 }, (_, index) => {
const year = String(thisYear - index - 1);
return { label: year, value: year };
}),
];
}
export function getSigunguOptions(
sido: string,
): StatisticsVerificationOption[] {
return SIGUNGU_OPTIONS_BY_SIDO[sido] ?? [];
}
export async function fetchStatisticsVerificationSummaryMock(
filters: StatisticsVerificationFilterState,
): Promise<StatisticsVerificationSummaryRow[]> {
await wait();
faker.seed(20260416);
const rows = Array.from({ length: 12 }, (_, index) => {
const sido = pickSidoName(filters.sido);
const sigungu = pickSigunguName(filters.sido, filters.sigungu);
const progressStatus = faker.helpers.arrayElement([
"승인대기",
"승인완료",
"반려",
]);
return {
summaryId: index + 1,
sido,
sigungu,
reportType: faker.helpers.arrayElement([
"정기보고",
"수정보고",
"보완보고",
]),
progressStatus,
writerName: faker.person.lastName() + faker.person.firstName(),
writerContact: faker.phone.number({ style: "national" }),
writerDept: faker.helpers.arrayElement([
"통계팀",
"하수행정과",
"정책기획과",
]),
writerPosition: faker.helpers.arrayElement([
"주무관",
"팀장",
"과장",
]),
approverName:
progressStatus === "승인대기"
? "-"
: faker.person.lastName() + faker.person.firstName(),
approverDept:
progressStatus === "승인대기"
? "-"
: faker.helpers.arrayElement(["검증운영팀", "하수행정과"]),
approverPosition:
progressStatus === "승인대기"
? "-"
: faker.helpers.arrayElement(["팀장", "과장"]),
returnReason:
progressStatus === "반려"
? faker.helpers.arrayElement([
"오류내역 확인 필요",
"예외사유 보강 필요",
"입력값 검증 재요청",
])
: "-",
};
});
return rows.filter((row) => {
if (filters.sido !== "ALL" && row.sido !== pickSidoName(filters.sido))
return false;
if (filters.sigungu !== "ALL") {
const currentSigungu = pickSigunguName(
filters.sido,
filters.sigungu,
);
if (row.sigungu !== currentSigungu) return false;
}
return true;
});
}
export async function fetchStatisticsVerificationDetailMock(
filters: StatisticsVerificationFilterState,
subFilters: StatisticsVerificationSubFilterState,
selectedSummaryId?: number | null,
): Promise<StatisticsVerificationDetailRow[]> {
await wait();
faker.seed(20260417);
const rows = Array.from({ length: 24 }, (_, index) => {
const approvalYn = faker.helpers.arrayElement(["승인", "미승인"]);
const status = faker.helpers.arrayElement([
"수정완료",
"검토중",
"오류",
]);
const summaryId = faker.number.int({ min: 1, max: 12 });
return {
detailId: index + 1,
summaryId,
sido: pickSidoName(filters.sido),
sigungu: pickSigunguName(filters.sido, filters.sigungu),
indicator: pickIndicator(filters.statsIndicator),
detailItem: faker.helpers.arrayElement([
"처리구역면적",
"처리인구",
"분류식관거연장",
"하수관로보급률",
]),
verifyDate: faker.date
.recent({ days: 20 })
.toISOString()
.slice(0, 10),
errorDetail: faker.helpers.arrayElement([
"전년 대비 편차 초과",
"입력값 누락",
"상호검증 불일치",
]),
inputValue: faker.number.int({ min: 100, max: 5000 }),
compareValue: faker.number.int({ min: 100, max: 5000 }),
status,
exceptionReason:
status === "오류"
? faker.lorem.sentence({ min: 1, max: 2 })
: "-",
returnOpinion:
approvalYn === "미승인"
? faker.helpers.arrayElement([
"산식 재검토 필요",
"근거자료 보강 요청",
"담당자 확인 필요",
])
: "-",
approvalYn,
};
});
return rows.filter((row) => {
if (selectedSummaryId && row.summaryId !== selectedSummaryId)
return false;
if (subFilters.status === "DONE" && row.status !== "수정완료")
return false;
if (subFilters.status === "REVIEW" && row.status !== "검토중")
return false;
if (subFilters.status === "ERROR" && row.status !== "오류")
return false;
if (
subFilters.approvalStatus === "APPROVED" &&
row.approvalYn !== "승인"
)
return false;
if (
subFilters.approvalStatus === "REJECTED" &&
row.approvalYn !== "미승인"
)
return false;
return true;
});
}
function wait() {
return new Promise((resolve) => setTimeout(resolve, NETWORK_DELAY_MS));
}
function pickSidoName(value: string): string {
if (value === "ALL")
return faker.helpers.arrayElement([
"서울특별시",
"부산광역시",
"대구광역시",
"경기도",
]);
const matched = SIDO_OPTIONS.find((option) => option.value === value);
return matched?.label ?? "서울특별시";
}
function pickSigunguName(sido: string, sigungu: string): string {
if (sigungu !== "ALL") {
const options = getSigunguOptions(sido);
const matched = options.find((option) => option.value === sigungu);
if (matched) return matched.label;
}
const options = getSigunguOptions(sido).filter(
(option) => option.value !== "ALL",
);
if (options.length === 0) return "전체";
return faker.helpers.arrayElement(options).label;
}
function pickIndicator(indicator: string): string {
if (indicator === "ALL")
return faker.helpers.arrayElement(
STATS_INDICATOR_OPTIONS.filter((item) => item.value !== "ALL"),
).label;
const matched = STATS_INDICATOR_OPTIONS.find(
(option) => option.value === indicator,
);
return matched?.label ?? "통계항목";
}