feat: add admin test data reset

This commit is contained in:
unknown
2026-07-20 19:48:40 +09:00
parent 7617c9f371
commit c45c47109c
4 changed files with 127 additions and 2 deletions

View File

@@ -62,6 +62,14 @@ interface ImportResult {
rows: ImportRow[];
}
interface VisitRequestResetResult {
visitRequests: number;
visitors: number;
approvals: number;
accessEvents: number;
passDeliveries: number;
}
interface AdminRouterDeps {
query: QueryFn;
}
@@ -481,6 +489,50 @@ export function createAdminRouter(deps: AdminRouterDeps = { query }): Router {
ok(res, await diagnoseEmailConnectivity());
}));
router.post('/visit-requests/reset-test-data', asyncRoute(async (req, res) => {
const actor = await requireAdmin(dbQuery, req);
if (String(req.body?.confirm ?? '').trim() !== '초기화') {
throw new ApiError(400, '확인 입력란에 "초기화"를 입력하세요.');
}
const targetRequests = await dbQuery<{ id: string; visitor_id: string }>(
'SELECT id, visitor_id FROM visit_requests',
);
const visitorIds = [...new Set(targetRequests.rows.map((row) => Number(row.visitor_id)))];
const passDeliveries = await dbQuery<{ id: string }>('DELETE FROM pass_deliveries RETURNING id');
const approvals = await dbQuery<{ id: string }>('DELETE FROM approvals RETURNING id');
const accessEvents = await dbQuery<{ id: string }>('DELETE FROM access_events RETURNING id');
const visitRequests = await dbQuery<{ id: string }>('DELETE FROM visit_requests RETURNING id');
const visitors = visitorIds.length > 0
? await dbQuery<{ id: string }>(
`
DELETE FROM visitors v
WHERE v.id = ANY($1::bigint[])
AND NOT EXISTS (SELECT 1 FROM visit_requests vr WHERE vr.visitor_id = v.id)
RETURNING id
`,
[visitorIds],
)
: { rows: [] };
const result: VisitRequestResetResult = {
visitRequests: visitRequests.rows.length,
visitors: visitors.rows.length,
approvals: approvals.rows.length,
accessEvents: accessEvents.rows.length,
passDeliveries: passDeliveries.rows.length,
};
await audit(
dbQuery,
actor,
'VISIT_REQUEST',
null,
`출입신청 테스트 데이터 초기화: 신청 ${result.visitRequests}건, 방문자 ${result.visitors}건, 승인 ${result.approvals}건, 입퇴장 ${result.accessEvents}건, 발송 ${result.passDeliveries}`,
);
ok(res, result);
}));
router.get('/teams', asyncRoute(async (req, res) => {
await requireAdmin(dbQuery, req);
ok(res, await listTeams(dbQuery));