관리자 패널
규칙
- 데이터 테이블: 서버 측 페이지네이션, 정렬, 필터링 — 모든 행을 클라이언트 측에 로드하지 말고
?page=1&limit=25&sort=createdAt&order=desc사용 - CRUD 패턴: 목록(테이블), 생성(양식/모달), 읽기(상세 보기), 업데이트(편집 양식), 삭제(확인 대화상자) — 모든 리소스에 걸쳐 일관된 레이아웃
- 역할 기반 접근: 역할(admin, editor, viewer)을 권한 매트릭스와 함께 정의 — 모든 API 경로에서 서버 측 권한 확인, UI에서만 확인하지 않음
- 벌크 작업: 여러 행 선택, 일괄 작업(삭제, 내보내기, 상태 변경) — 파괴적 작업은 확인, 대량 배치의 경우 백그라운드에서 처리
- 검색: 주요 필드에 걸쳐 디바운스된 텍스트 검색(300ms) — 정확한 쿼리를 위해 열 필터와 결합
- 사용자 관리: 사용자 목록, 세부 정보 보기, 역할 변경, 계정 활성화/비활성화, 가장(admin 전용, 감사 로그 포함)
- 감사 로그: 누가 무엇을 언제 변경했는지 기록 —
{ userId, action, resource, resourceId, changes, timestamp } - 레이아웃: 사이드바 탐색(접을 수 있음), 이동 경로, 작업 버튼이 있는 페이지 제목 — 반응형이지만 데스크톱에 최적화됨
권한 확인 패턴
const PERMISSIONS = {
admin: ["users:read", "users:write", "users:delete", "data:read", "data:write", "data:delete"],
editor: ["data:read", "data:write"],
viewer: ["data:read"],
} as const;
function can(role: string, permission: string): boolean {
return PERMISSIONS[role]?.includes(permission) ?? false;
}
// 미들웨어
if (!can(user.role, "users:write")) return Response.json({ error: "Forbidden" }, { status: 403 });
데이터 테이블 API 패턴
GET /api/admin/users?page=1&limit=25&sort=createdAt&order=desc&search=john&role=admin
응답: { data: [...], total: 150, page: 1, limit: 25, totalPages: 6 }
피해야 할 사항
- 클라이언트 측 전용 권한 확인 — 항상 서버에서 강제 실행
- 모든 데이터를 로드한 후 브라우저에서 페이지네이션 — 서버 측 페이지네이션 사용
- 파괴적 작업에 대한 확인 없음 — 항상 삭제 및 벌크 작업을 확인
- 감사 추적 누락 — 누가 무엇을 변경했는지 알아야 함