가비아 · 하이웍스개발팀
문서화되지 않은 레거시 서비스의 재설계
담당자와 인수인계 문서가 없는 레거시 서비스의 요구사항을 파악하고, 기존 서비스의 오류와 전환을 막던 요구사항을 해결해 신규 서비스로 개편했습니다.
2025.08 — 2026.04
- TypeScript
- React
- Next.js
- TanStack Query
주요 성과
- 인수인계 없이 남겨진 레거시 서비스의 요구사항을 파악하고, 기존 구현의 오류와 예외 조건을 분석하며 개편했습니다.
- 수년간 남아 있던 라이선스 처리 오류를 발견하고 개선했으며, 관련 변경사항을 프론트엔드 3개 서비스에 반영하고 서버 로직 수정안을 공유했습니다.
- 개편 과정에서 추가된 신규 기능의 구현·검증까지 담당해 기존 서비스를 종료하고 개편한 서비스로 전환했습니다.
요구사항부터 다시 파악해야 했던 레거시 서비스
하이웍스의 다른 관리 화면들은 모두 개편됐지만, 사용자 관리만 약 1년 반 동안 레거시 서비스로 남아 있었습니다. 사이드바나 공통 기능을 변경할 때마다 기존 페이지에도 별도로 수정 사항을 반영해야 했고, 이러한 중복 작업을 줄이고자 사용자 관리 개편을 진행했습니다.
하지만 기존 개발자와 기획자는 모두 퇴사했고, 인수인계 문서도 없었습니다. 기존 코드만으로는 정확한 동작과 그 이유를 파악하기 어려워, 여러 담당자를 찾아가 기능별 요구사항과 예외 조건을 확인하며 개편을 진행했습니다.
특히 라이선스는 요금제에 따라 포함되는 서비스가 달랐고, 함께 할당할 수 없는 조합도 있었습니다. 담당자에게 실제 라이선스 할당 기준을 확인하고, 이를 바탕으로 기존 구현을 검토했습니다.

기존 화면의 선택 조건과 API 요청 생성 과정을 살펴보고, 서버에 직접 요청을 보내 실제 처리 결과도 확인했습니다. 이 과정에서 라이선스 할당 기준과 다르게 동작하는 문제뿐 아니라, 서버가 변경을 적용하지 않고도 성공 응답을 반환하는 문제를 발견했습니다.
UI부터 API 요청까지 다시 설계하기
그룹웨어 라이선스에는 메일을 비롯한 여러 서비스가 포함되어 있어, 개별 메일 라이선스와 중복 할당할 수 없습니다. 하지만 기존 라이선스 변경 화면에서는 이러한 조합을 선택할 수 있었고, 화면에서 선택한 내용이 실제 API 요청에 제대로 반영되지 않는 문제도 있었습니다.
| 라이선스 | 포함된 서비스 |
|---|---|
| 그룹웨어 | 메일, 드라이브, 근무관리 등 |
| 메일 | 메일 |
그룹웨어를 사용 중인 계정에서 메일을 '할당'하면 그룹웨어가 자동으로 '회수'로 변경됐습니다. 하지만 그룹웨어를 다시 '변경 안 함'으로 선택할 수 있었고, 이 상태에서 저장하면 API 요청에서 메일이 빠져 기존 그룹웨어만 유지됐습니다.
요청 전 선택 상태

생성된 API 요청
// 실제 생성된 요청
{
"groupware": {
"use_flag": true
}
}
// 화면의 선택을 그대로 옮긴 조합 (라이선스 정책상 동시 할당 불가)
// "groupware": {
// "use_flag": true
// },
// "mail": {
// "use_flag": true
// }
기존 코드는 화면에서 선택한 값을 isChecked로 변환한 뒤, 여러 함수에서 라이선스별로 값을 변경하거나 제외했습니다. 실제 API 요청이 어떻게 만들어지는지 파악하려면 각 함수의 처리 과정을 모두 따라가야 했습니다.
Before · 여러 단계의 요청값 변환
// 그룹웨어 할당 시 다른 라이선스의 요청값 보정
if (groupwareLicense?.isChecked) {
return licenses.reduce((acc, license) => {
if (groupwareLicense.key === license.key) {
return { ...acc, [license.key]: { use_flag: true } };
}
if (FILE_LICENSES.includes(license.key)) {
return { ...acc, [license.key]: { use_flag: license.isChecked } };
}
return { ...acc, [license.key]: { use_flag: false } };
}, {});
}
// 1. 라이선스별 조건에 따라 요청값 변경
const adjusted = adjustLicenses(licenseForm);
// 2. 일부 라이선스의 선택값 복원
const restored = restoreIndependentLicenses(adjusted, licenseForm);
// 3. false인 라이선스를 요청에서 제외
const request = removeFalseLicenses(restored);
After · 선택 상태에 따른 요청 생성
/**
* 라이선스 변경 요청 생성
* 회수는 요청에서 제외하며, use_flag: false는 정지를 의미합니다.
*/
licenseRadioForms.forEach((license) => {
// 다른 라이선스에 포함된 경우 제외
if (license.disabled) return;
if (license.checkedTarget === '변경안함') {
// 기존에 할당된 라이선스만 유지
if (isAlreadyAssigned(license)) body[license.key] = { use_flag: true };
return;
}
if (license.checkedTarget === '할당') {
body[license.key] = { use_flag: true };
}
if (license.checkedTarget === '회수') {
// 요청에서 제외
}
});
메일을 개별 할당할 때는 그룹웨어의 '변경 안 함' 선택을 제한하고, 선택 상태와 비활성화 여부에 따라 API 요청을 직접 생성하도록 구조를 단순화했습니다. 또한 회수와 정지의 차이를 코드에 명시해 각 조건의 의도를 쉽게 파악할 수 있도록 했습니다.
서버에 함께 할당할 수 없는 라이선스 조합을 직접 요청했을 때는 HTTP 200 응답이 반환됐지만, 실제 라이선스 변경은 적용되지 않았습니다. 기존 백엔드의 검증 로직과 에러 처리 방식을 분석하여 라이선스 조합별 검증 조건과 에러 코드, 수정 사항을 실제 서버에 적용할 수 있도록 문서로 정리해 공유했습니다.
서비스 전환을 막고 있던 마지막 과제
기존 사용자 관리 서비스에는 감사로그가 별도로 추가되어 있었지만, 개편한 서비스에는 적용되지 않은 상태였습니다. 감사로그가 필요한 고객사가 있어 기존 서비스를 종료하지 못하고 있었습니다.
개편한 서비스에는 기존에 없던 기능도 추가되어 감사로그를 그대로 옮길 수는 없었습니다. 기존 프론트엔드와 백엔드 코드, 감사로그 API를 직접 분석해 조회·등록·수정·삭제 등 기능별 기록 대상과 변경 내용, 성공·실패에 따른 처리 조건을 정리했습니다.
정리한 내용을 표로 작성해 공유하고, 이를 기준으로 신규 서비스 전반에 감사로그를 구현했습니다.
| 기능 | 작업 유형 | 기록 내용 |
|---|---|---|
| 사용자 목록 | 조회 | 목록 조회 이력 |
| 사용자 등록 | 등록 | 등록한 사용자 |
| 사용자 정보 수정 | 수정 | 대상 사용자, 수정 항목 및 변경 값 |
| 라이선스 변경 | 수정 | 대상 사용자, 라이선스 변경 내용 |
| 사용자 일괄 등록 | 등록 | 등록한 사용자 |
| 사용자 복원 | 수정 | 복원한 사용자 |
기능마다 기록할 내용이 달라, 사용자 정보와 라이선스 변경 내역을 감사로그 메시지로 변환하는 공통 훅을 구현했습니다. 내부 식별값을 실제 명칭으로 변환하고, 변경 전후 상태를 비교해 라이선스 할당·회수 내역을 구분했습니다.
레거시 서비스를 대체하기까지
기존 개발자와 기획자가 남긴 문서가 없었고, 기존 코드에도 잘못된 동작이 남아 있었습니다. 단순히 기능을 옮기는 데 그치지 않고, 실제 요구사항과 처리 결과를 확인하며 개편을 진행했습니다.
| 마주한 문제 | 해결한 방법 |
|---|---|
| 담당자 퇴사와 인수인계 문서 부재 코드만으로는 동작의 의도를 알 수 없음 | 여러 담당자를 찾아 직접 확인 → 기능별 요구사항과 예외 조건 파악 |
| 수년간 남아 있던 라이선스 처리 오류 기존 코드와 실제 정책이 일치하지 않는 문제 | 기존 코드와 실제 처리 결과 비교 → 잘못된 UI와 API 요청 개선 |
| 프론트엔드 수정만으로 끝나지 않는 문제 서버에서도 잘못된 요청에 성공 응답 반환 | 백엔드 검증과 에러 처리 분석 → 서버 수정 조건과 에러 코드를 정리해 공유 |
| 신규 서비스에 누락된 감사로그 감사로그가 필요한 고객사로 인해 기존 서비스 종료 지연 | 기존 감사로그 분석 및 개편 서비스에 적용 → 기존 로그를 분석·정리하고, 공통 훅으로 구현해 재사용 |
기존 구현의 오류를 개선하고 누락된 요구사항까지 반영해, 구 서비스를 종료하고 개편한 서비스로 전환할 수 있었습니다.