File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import 'server-only';
import type { PointStandard } from '@/lib/domain/point-standard';
import type { PointStandardQuery } from '@/lib/domain/point-standard-query';
import type { PointStandardValues } from '@/lib/domain/point-standard-form';
// TODO(백엔드): 포인트 기준관리 API가 아직 없다. 아래 mock 저장소를 지우고 다른 Repository처럼
// backendFetch + getSessionAccessToken으로 교체하면 호출부는 그대로 둘 수 있다.
// 이슈: 저장소가 모듈 메모리라 서버를 다시 띄우면 수정·삭제가 초기값으로 되돌아간다.
let STANDARDS: PointStandard[] = [
{
id: 'EVENT-1',
eventCode: 'EVENT-1',
point: 5,
limitPoint: 10,
isDuplicable: true,
siteCode: 'SELF_STUDY',
description: '과제 제출 시 20포인트 지급',
isActive: true,
updatedAt: '2026-01-10 09:40',
},
{
id: 'EVENT-2',
eventCode: 'EVENT-2',
point: 10,
limitPoint: 0,
isDuplicable: true,
siteCode: 'SELF_STUDY',
description: '수업완료 시 10포인트 지급',
isActive: true,
updatedAt: '2026-01-18 10:02',
},
{
id: 'EVENT-3',
eventCode: 'EVENT-3',
point: 5,
limitPoint: 0,
isDuplicable: false,
siteCode: 'SELF_STUDY',
description: '과정 이수 시 100포인트 지급',
isActive: true,
updatedAt: '2026-02-05 13:26',
},
{
id: 'EVENT-4',
eventCode: 'EVENT-4',
point: 3,
limitPoint: 30,
isDuplicable: true,
siteCode: 'FOX_PAY_APP',
description: '출석 체크 시 3포인트 지급',
isActive: true,
updatedAt: '2026-01-24 16:11',
},
{
id: 'EVENT-5',
eventCode: 'EVENT-5',
point: 20,
limitPoint: 60,
isDuplicable: false,
siteCode: 'FOX_PAY_APP',
description: '금융OX퀴즈 정답 시 20포인트 지급',
isActive: false,
updatedAt: '2026-01-02 11:35',
},
];
function matchesKeyword(standard: PointStandard, keyword: string): boolean {
const needle = keyword.toLowerCase();
return (
standard.eventCode.toLowerCase().includes(needle) ||
standard.description.toLowerCase().includes(needle)
);
}
/** 기획 PTS10100001 ② — 최근 수정일시 순 정렬. */
function byUpdatedAtDesc(a: PointStandard, b: PointStandard): number {
return b.updatedAt.localeCompare(a.updatedAt);
}
export async function fetchPointStandards(
query: PointStandardQuery
): Promise<{ items: PointStandard[]; totalCount: number }> {
const filtered = query.keyword
? STANDARDS.filter((standard) => matchesKeyword(standard, query.keyword))
: [...STANDARDS];
filtered.sort(byUpdatedAtDesc);
const start = (query.page - 1) * query.pageSize;
return {
items: filtered.slice(start, start + query.pageSize),
totalCount: filtered.length,
};
}
function nowStamp(): string {
const now = new Date();
const pad = (value: number) => String(value).padStart(2, '0');
return (
`${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ` +
`${pad(now.getHours())}:${pad(now.getMinutes())}`
);
}
export async function updatePointStandard(
values: PointStandardValues
): Promise<void> {
const index = STANDARDS.findIndex((standard) => standard.id === values.id);
if (index < 0) {
throw new Error(`포인트 기준을 찾을 수 없습니다: ${values.id}`);
}
STANDARDS[index] = {
...STANDARDS[index],
point: values.point,
limitPoint: values.limitPoint,
isDuplicable: values.isDuplicable,
description: values.description,
isActive: values.isActive,
updatedAt: nowStamp(),
};
}
export async function deletePointStandard(id: string): Promise<void> {
const next = STANDARDS.filter((standard) => standard.id !== id);
if (next.length === STANDARDS.length) {
throw new Error(`포인트 기준을 찾을 수 없습니다: ${id}`);
}
STANDARDS = next;
}