[요약]
- 사용자 약 20만 명 규모의 경상북도 모바일 도민증 ‘모이소’에서 API 서버와 관리자 웹, Flutter 앱을 운영하고 기능을 개선했습니다. 플랫폼 내 신규 서비스는 화면 기획부터 개발과 배포까지 담당했습니다.
- 운영 중 발생한 조회 성능, 메모리 부족, 데이터 정합성 문제를 분석하고 개선했으며, 공공기관 감리와 보안 진단에서 지적된 접근제어, 파일 업로드, 개인정보 처리 등의 취약점을 조치했습니다.
- 매일 진행 상황을 정리해 공유했고, 이슈가 발생하면 상황과 처리 계획을 먼저 보고한 뒤 진행 경과와 완료 결과를 공유했습니다. 별도 검토가 필요한 사안은 내용을 정리해 담당 과장과 확인 후 진행했습니다.
[기술]
| 언어 | Java 11 · 21, Dart |
| 프레임워크 | Spring Boot 2 · 3, Spring Security, JPA / Hibernate, Thymeleaf, Bootstrap, Flutter |
| 데이터 | MySQL, Oracle |
| 서버 · 형상관리 | Linux, nginx, GitLab |
| 인증 · 보안 | Spring Security, JWT, 세션 인증, AES, RSA, 취약점 진단 대응 |
[경력] 에즈넷 · 2024.03 ~ 2025.09 · 개발팀 사원
대표 포함 4인, 실무자 3인 규모 SI입니다. 실무 인원은 퍼블리셔 과장과 프로그래머 과장, 저 세 명이었고, 제가 맡은 프로젝트는 개발 전 영역을 직접 다뤘습니다.
경상북도 모바일 도민증 '모이소'
2024.04 ~ 2025.08 · 사용자 약 20만 명 · 발주 경상북도, 주관 파라미터, 개발 수행 에즈넷
Java 11 · Spring Boot 2.6 · JPA · MySQL · Thymeleaf · Bootstrap · Flutter · 공공 마이데이터 연계
도민이 모바일 신분 확인과 복지 서비스를 한 앱에서 이용하는 플랫폼입니다. 사수가 담당하던 프로젝트를 인수받아 API 서버와 관리자 웹, Flutter 앱 개발을 전담했고, 신규 서비스는 화면기획서 작성부터 배포까지 맡았습니다.
농어민수당 집계 쿼리 개선
- 상황
- 관리자 집계 화면이 느리다는 요청이 들어왔습니다. 사수가 자리를 비운 기간이라 고객 요청을 직접 받아 처리했습니다
- 판단
- 연도 조건이
date_format(create_date,'%Y')로 들어가 인덱스를 타지 못하고 있었고, 불필요한 LIKE '%연도%'도 있었습니다 - 별도
create_year 컬럼과 직접 비교하도록 변경 - 신청 서비스가 여럿이지만 농어민수당만 건수가 많아 이 테이블만 대상으로 삼았습니다. 나머지 신청 서비스는 건수가 적어 제외했습니다
- 진행
- 원인과 처리 계획을 먼저 보고한 뒤 작업했고, 완료 후 결과를 보고했습니다
그 외
- 근무상황표 조회가 10초 이상 걸리던 것을, 교사와 날짜마다 반복하던 로그 조회를 날짜 범위 조회 한 번과 중첩 맵으로 바꿔 0.5초 미만으로 단축
- 첨부파일 암호화 후 조회만 해도 평문이 DB에 덮어써지던 문제를 추적해, 영속 엔티티에 복호화 값을 넣어 더티체킹이 UPDATE를 실행하는 것이 원인임을 확인하고
save · flush · detach 이후 복호화하도록 순서를 재배치
- Base64로 저장된 기존 파일을 AES로 전환할 때, 일괄 마이그레이션 대신 헤더 4바이트 매직값으로 포맷을 판별해 구버전과 신버전이 스키마 변경 없이 공존하도록 구성
- 농어민수당 거주이력 검증을 최근 전입일 기준에서 12개월 전체 주소 이력 확인으로 변경 (외부 기관 XML은 스펙과 달리 태그 누락과 빈 값이 발생)
- 수만 건 엑셀 다운로드의 OOM과 타임아웃을 스트리밍과 비동기 생성으로 해소, 주민등록번호 메모리 잔존 문제를 가변 버퍼와 즉시 초기화로 조치
- 보안 취약점 진단 지적 항목 조치 후 이행진단 통과, 감리 산출물(ERD · 테이블 정의서 · 인덱스 명세서 · 성능시험 결과서 등) 작성
덕성여자대학교 산학협력단 홈페이지
2024.03 ~ 2025.08 · 3인 팀, 점차 메인 담당 · 본인 커밋 103
Java 11 · Spring Boot 2.5 · Spring Security · JPA · MySQL · Oracle · Thymeleaf · Bootstrap
교수와 연구자의 산학협력 실적을 등록, 심사하고 외부 연계 시스템에 제공하는 홈페이지입니다. 기존 담당자에게 이어받아 백엔드와 프론트엔드를 맡았고, 규모가 크지 않아 고객과 직접 메일과 전화로 소통했습니다.
외부 시스템 연계 변환 계층
- 상황
- 산학협력 실적을 외부 연계 시스템에 제공해야 하는데, 외부가 기대하는 컬럼 명세가 내부 도메인 구조와 달랐습니다
- 그 코드값은 외부 정책에 따라 언제든 바뀔 수 있었습니다
- 판단
- 내부 도메인을 외부 스펙에 직접 맞추면 외부가 바뀔 때마다 도메인과 쿼리가 흔들립니다. 둘 사이에 변환 계층을 뒀습니다
- 제공 전용 뷰 테이블을 따로 설계
- 내부와 외부 코드의 매핑은 별도 테이블과 JSON 코드맵으로 관리해 런타임에 읽도록 구성
- 코드값이 바뀌어도 소스 수정과 재배포 없이 DB만 고치면 됩니다
- 정합성
- 뷰 테이블에는 최종 승인분만 있어야 해서, 심사 상태가 최종 승인이 아니면 뷰 테이블에서 레코드를 삭제하도록 상태 변경 시점에 동기화
- 한계
- 원본 데이터가 구분자로 직렬화된 레거시라 변환부가 배열 인덱스 접근으로 남았고, 매핑을 읽을 때마다 파서를 새로 만듭니다. 이어받은 직후가 리팩터링 비용이 가장 낮은 시점이었는데 그때 정리하지 못했습니다
그 외
- URL의 식별자만 바꾸면 다른 사람의 신청 내역과 인증서를 열람할 수 있던 문제를, 한 곳만 막지 않고 같은 패턴을 전 도메인에서 찾아 세션 사용자와 데이터 소유자를 대조하도록 적용. 출력과 다운로드 엔드포인트도 예외 없이
- 교수가 탈퇴하면 실적 목록의 신청자 이름이 사라지던 문제를, 등록 시점 이름을 스냅샷 컬럼에 보관하고 조인 대신 그 값을 읽도록 변경
- 학사 시스템(Oracle) 연계를 위한 별도 API를 초기 구성
- 심사 상태 코드가 정수로 흩어져 있고 관리자와 교수에게 다르게 보여야 해서, 변환 로직을 도메인 메서드로 캡슐화
- 윈도우 서버가 강제 업데이트 후 반복 중단되어 리눅스 환경으로 이전
그 외 프로젝트
카썹 중고 자동차 부품 거래 플랫폼 · 2025.08 ~ 2025.09 · 3인 팀 합류
- 인증 없이 열려 있던 앱 API 전반에 JWT 인증을 적용하고, 컨트롤러마다 반복되던 검증을 한 메서드로 통합 (직접 만들기보다 Spring Security를 썼어야 했습니다)
- 신고된 리뷰가 삭제돼도 내용을 확인할 수 있도록, 원본에 플래그를 두는 대신 신고 도메인에 스냅샷을 저장해 원본 삭제 정책과 분리
tomas 입시 상담 예약 서비스 · 2024.05 ~ 2024.09 · 3인 팀
- 회원 탈퇴 시 여러 테이블의 참조 때문에 개발자가 직접 SQL을 실행하던 작업을 관리 도구로 대체. 논리 삭제 전환은 조회 쿼리 전체를 손봐야 해 중장기 과제로 두고, 정해진 순서로만 실행되는 도구로 당장의 운영 문제를 해결
- 암호화 비밀번호 판별 정규식이 실제 적용된 알고리즘과 달라 검증이 어긋나던 문제를 수정
사내 운영 자동화 2024.07 · 단독 · 직접 제안해 개발
- 운영 중인 9개 사이트의 상태를 점검하는 도구에서, 다운이 유지되는 동안 주기마다 메일이 쏟아지던 것을 정상과 이상이 바뀌는 시점에만 보내도록 변경. 재시작 직후 첫 점검은 기록만 해 재기동 시 알림도 차단
[일하는 방식]
- 매일 퇴근 전 그날의 진행경과를 정리해 보고했습니다. 사수는 별도 회의 없이 그 기록을 근거로 발주처 담당자와 소통했습니다
- 이슈가 생기면 먼저 알리고, 어떻게 처리하겠다는 안을 함께 올렸습니다
- 신규 서비스는 발주처 협의 내용을 받아 와이어프레임으로 화면기획서를 작성한 뒤 개발에 들어갔습니다
- 기존 UI 컴포넌트로 만들 수 있는 화면은 직접 구현하고 퍼블리셔 과장의 검토를 받았습니다. 새로 설계가 필요한 화면은 요청해서 받았습니다