이번 프로젝트는 아이디어를 만들지 않았다
Flutter 실습 기간이 주어졌을 때, 첫 번째 고민은 “무엇을 만들지”가 아니었다. “내가 실제로 이해하는 문제가 뭔지”였다.
억지로 아이디어를 만드는 것과, 이미 알고 있는 불편에서 출발하는 것은 시작부터 다르다. 기능 우선순위를 잡을 때도, 예외 케이스를 정의할 때도, 내가 이해하는 문제에서 출발한 프로젝트가 훨씬 빠르다.
그래서 골랐다. 교대근무자를 위한 급여 계산기.
호텔, 병원, 물류센터처럼 교대근무가 일상인 환경에서는 급여가 단순 계산이 아니다. 시급에 시간만 곱하면 끝이 아니다. 야간 시간대에 걸쳤는지, 공휴일이었는지, 자정을 넘겼는지, 휴게 시간은 얼마였는지에 따라 수령액이 달라진다. 나는 HR과 재무 업무를 경험했기 때문에 이 복잡함이 얼마나 실질적인 문제인지 알고 있었다.
달력을 버린 이유
초안에는 달력이 있었다.
날짜를 선택하면 근무를 입력할 수 있는 구조. 시각적으로 직관적이고, 완성했을 때 보기도 좋다. 그런데 Flutter 입문 단계에서 달력 커스터마이징은 생각보다 깊은 작업이다. 선택 가능한 날짜 범위, 마킹 스타일, 터치 인터랙션, 월 이동 — 이것들을 제대로 다루려면 학습 목표가 달력 자체가 되어버린다.
더 중요한 문제는 따로 있었다. 이 앱에서 달력이 진짜 필요한가?
이 앱의 핵심은 근무 기록을 예쁘게 시각화하는 것이 아니다. 야간수당과 휴일수당이 정확하게 반영된 급여 합계를 빠르게 확인하는 것이다. 달력을 없애고 리스트로 바꾸니, 앱이 무엇을 위한 것인지 오히려 더 선명해졌다.
결과적으로 화면 구조는 3개로 정리됐다.
- 홈 — 이번 달 예상 급여 합계 + 근무 기록 카드 리스트
- 근무 입력 — 날짜 / 시작·종료 시간 / 휴게 시간 / 공휴일 여부
- 설정 — 시급 및 수당 규칙
기능을 줄인 게 아니라, 필요한 것만 남긴 것이다.
기술 선택: Flutter + Provider + SharedPreferences
처음에는 어떤 언어로 시작해야 할지 혼동이 있었다. Python으로 로직을 먼저 짜야 하는지, Java와는 어떻게 다른지. 하지만 결론은 명확했다. 화면과 계산 로직 모두 Dart 안에서 처리하는 구조였다.
Dart는 낯설었지만 Java와 문법적으로 닮은 부분이 많았다. 계산 클래스를 설계하는 데 심리적 장벽이 생각보다 낮았다. Flutter를 처음 다루면서도, 급여 계산 로직이 분리된 구조를 만들고 싶어서 모델·상태·화면을 나누는 방향을 초반부터 의식했다.
폴더 구조는 아래처럼 잡았다.
lib/
├── models/ — ShiftEntry, 급여 데이터 모델
├── providers/ — ChangeNotifier 기반 상태 관리
├── screens/ — 홈, 입력, 설정 화면
├── utils/ — 계산 로직, 유틸 함수
└── widgets/ — 재사용 UI 컴포넌트
상태 관리는 Provider/ChangeNotifier 계열로 정리했다. 전역 상태가 필요한 부분은 Provider로 관리하고, 로컬 저장은 SharedPreferences 중심으로 구성했다. 단일 파일에 모든 것을 쑤셔넣는 것보다, 초반부터 역할을 나누는 것이 결과적으로 유지보수에 훨씬 낫다는 것을 이 프로젝트에서 직접 확인했다.
생성형 도구를 쓰는 방식도 배운 프로젝트였다
UI 구상은 Stitch 프롬프트로, 코드 구조와 로직은 Jules 프롬프트로 시작했다.
이 과정에서 가장 빠르게 체감한 것은, 프롬프트를 어떻게 쓰느냐에 따라 결과물의 질이 완전히 달라진다는 점이었다. “Flutter로 급여 계산기 만들어줘”라고 쓰면 껍데기 중심의 결과가 나온다. 반대로 입력값의 구조, 계산 규칙, 상태 갱신 방식, 저장 방식까지 명시하면 훨씬 쓸 수 있는 결과가 나온다.
디자인용 프롬프트와 구현용 프롬프트를 분리하니, 화면과 로직이 뒤섞이지 않았다. 프롬프트 자체가 일종의 기획서 역할을 했다. 코드보다 먼저, 어떤 정보를 도구에게 정확히 전달해야 원하는 결과가 나오는지를 배운 프로젝트이기도 했다.
급여 계산 로직: 생각보다 복잡한 문제
비개발자도 이해할 수 있는 설명
급여 계산기라고 하면 단순해 보인다. 시급 × 시간 = 급여. 그게 전부라면 앱을 만들 필요도 없다.
문제는 교대근무의 현실이다. 오후 10시에 출근해서 다음날 오전 6시에 퇴근하는 근무라면, 이 8시간이 전부 같은 단가로 계산되지 않는다. 밤 10시부터 다음날 오전 6시까지의 구간에는 야간 수당이 붙는다. 그날이 공휴일이면 또 달라진다. 중간에 1시간 휴게를 쉬었다면 실근로는 7시간이다.
이 모든 경우를 앱이 자동으로 처리해줘야 한다. 사용자는 날짜, 시작 시간, 종료 시간, 휴게 시간, 공휴일 여부만 입력하면 된다.
개발 회고 관점의 설명
화면을 그리는 것보다 어려웠던 건, 급여 계산 규칙을 코드가 이해할 수 있는 형태로 바꾸는 일이었다.
가장 까다로운 케이스는 자정을 넘기는 근무였다. 예를 들어 20:00 ~ 05:00 근무는 달력 기준으로 날짜가 바뀐다. 이걸 단순히 시간 차이로만 계산하면 05:00 - 20:00 = -15시간이 나온다. 자정을 기준으로 날짜를 분리하거나, DateTime 객체를 활용해 다음 날 새벽으로 처리하는 로직이 필요하다.
야간 수당 구간 겹침도 마찬가지다. 22:00~06:00 구간 안에서 실제 근무 시간이 얼마나 겹치는지를 계산해야 한다. 휴게 시간 차감, 공휴일 플래그 분기, 연장근로 여부 판단까지 더해지면 단순해 보이는 계산 함수 하나가 꽤 많은 경계값 처리를 담게 된다.
이 프로젝트에서 실제로 설계하려 한 계산 항목을 정리하면 다음과 같다.
- 시작/종료 시간 기반 총 체류 시간
- 휴게 시간 차감 후 실근로 시간
- 자정을 넘기는 근무의 날짜 분리 처리
- 야간 시간대(
22:00~06:00) 겹침 구간 계산 - 공휴일 여부에 따른 수당 분기
- 2026년 기준 최저시급(10,320원) 및 수당 배율 적용
HR 경험이 없었다면 이 항목들을 처음부터 설계하기 어려웠을 것이다. 내가 잘 아는 업무 맥락이 앱의 계산 규칙 설계로 직접 이어졌다.
여기까지 정리
WorkWage는 아직 마무리 작업이 남아 있는 프로젝트다. 하지만 지금 시점에서 돌아보면, 이 프로젝트에서 배운 것은 Flutter 문법보다 더 넓다.
- 내가 이해하는 문제를 고르는 것이 곧 기획의 시작이었다.
- 범위를 줄이는 결정이 앱의 목적을 더 선명하게 만들었다.
- 생성형 도구는 구조화된 요청에 반응한다.
- 계산 로직의 어려움은 코드가 아니라, 현실 규칙을 코드로 번역하는 과정에 있었다.
다음 편에서는 상태 관리와 로컬 저장 구조, 그리고 이후 기능 확장 방향을 정리한다. 결국 이 프로젝트에서 가장 중요했던 선택은 처음부터 급여 계산 자체를 MVP의 중심에 두고, 내가 실제로 이해하는 문제를 좁고 선명하게 다룬 것이었다.
Community
Comments
Comments appear immediately. Use report if something needs review.
No comments yet.