· case-study · 2 min read

건설 인력 매칭 플랫폼 개발 사례

일용직 근로자와 건설사업장을 연결하는 모바일 매칭 플랫폼을 Flutter, Hono, Cloudflare Workers, Supabase, R2, Next.js 관리자 콘솔로 설계한 풀스택 개발 사례.

건설 인력 매칭 플랫폼 개발 사례

한 문장 요약

일용직 근로자와 건설사업장을 연결하는 모바일 중심 매칭 플랫폼을 개발했습니다. 근로자 앱, 사업자 앱, 관리자 콘솔, 서버리스 API, 파일 저장소, 인증과 개인정보 보호까지 한 흐름으로 묶어야 했던 풀스택 프로젝트입니다.

겉으로는 채용 공고와 지원 기능처럼 보이지만, 실제 난도는 상태 설계에 있었습니다. 누가 가입했고, 누가 승인됐고, 어떤 공고가 열려 있고, 어떤 지원이 완료됐는지 명확하지 않으면 플랫폼 전체가 흔들립니다.

채용 게시판이 아닌 상태 기반 제품

처음에 정리한 것은 기술 스택이 아니라 역할이었습니다.

  • 근로자: 공고 탐색, 지원, 근무 일정, 서류 제출, 설문
  • 사업자: 회사 정보 제출, 공고 작성, 지원자 확인, 선정과 거절, 평가
  • 관리자: 사업자 승인, 문서 검토, 공지와 배너, 광고, 평판, 통계

이 구분은 화면 메뉴를 나누는 기준이면서 API 권한과 데이터베이스 상태의 기준이 됐습니다. 사용자 상태는 가입 대기, 승인, 정지, 탈퇴처럼 서비스 접근 권한을 결정합니다. 사업자 상태는 승인 대기와 승인 완료를 구분해 공고 작성 가능 여부와 연결됩니다. 공고와 지원도 각각 임시 저장, 공개, 마감, 대기, 선정, 거절, 취소, 완료 같은 상태를 가집니다.

상태가 느슨하면 화면과 API가 쉽게 어긋납니다. 앱에서는 버튼이 보이지만 서버에서는 거절되거나, 관리자가 승인했는데 모바일 앱은 여전히 대기 상태로 보는 문제가 생깁니다. 그래서 PRD, 데이터 모델, API 응답, 화면 상태를 같은 단어로 맞추는 일이 초반 개발의 핵심이었습니다.

하나의 Flutter 코드베이스 안에 두 경험 나누기

모바일 앱은 하나의 Flutter 코드베이스로 만들었지만, 실제로는 근로자와 사업자라는 두 앱에 가까웠습니다. 근로자는 오늘 들어갈 수 있는 현장을 빠르게 찾는 것이 중요하고, 사업자는 공고와 지원자를 업무처럼 관리해야 합니다.

기본 구조는 Flutter, GoRouter, Riverpod, Dio, Secure Storage를 중심으로 잡았습니다. GoRouter는 인증 전후 경로와 역할별 탭 구조를 분리했고, Riverpod은 세션, 프로필, 공고 목록, 캘린더, 광고 상태를 관리했습니다. Dio 클라이언트는 JWT 주입, 토큰 갱신, 401 재시도, 공통 응답 파싱을 맡았습니다.

역할별 화면은 Shell을 나눠 정리했습니다. 근로자 Shell은 홈, 채용공고, 캘린더, 내 정보, 설정을 중심으로 구성했고, 사업자 Shell은 홈, 공고 관리, 캘린더, 평가, 설정을 중심으로 구성했습니다. 공통 API 클라이언트와 디자인 토큰은 공유하되, 홈 화면과 주요 업무 흐름은 역할에 맞게 분리했습니다.

이 판단이 유지보수에 도움이 됐습니다. 역할 기반 앱에서 중요한 것은 공통 컴포넌트를 얼마나 많이 공유하느냐가 아니라, 업무 흐름을 어디서 분리하느냐였습니다.

Hono와 Cloudflare Workers로 옮긴 백엔드

초기 백엔드는 전통적인 서버 구조로 시작할 수 있었지만, 운영 비용과 배포 단순성, API 응답 속도를 고려해 Hono 기반 Cloudflare Workers 구조로 정리했습니다. 데이터는 Supabase Postgres를 사용하고, 파일은 Cloudflare R2에 저장했습니다. 캐시나 가벼운 상태 저장에는 KV를 활용했습니다.

서버리스 구조에서 중요한 것은 라우트보다 경계입니다. 인증 미들웨어, 관리자 권한, 사업자 권한, 근로자 권한이 섞이면 테스트하기 어려워집니다. 그래서 라우트별로 어떤 역할이 접근 가능한지 명확히 나누고, 파일 업로드나 개인정보 조회처럼 위험한 기능은 별도 검증을 두었습니다.

파일 업로드도 단순하지 않았습니다. 프로필 이미지, 문서 이미지, 광고 배너처럼 자산마다 공개 범위가 다릅니다. 공개 이미지는 빠르게 열려야 하지만, 민감한 문서는 인증 없이 열리면 안 됩니다. 이 때문에 업로드 API는 파일 종류와 소유자, 접근 권한을 함께 다루도록 설계했습니다.

인증, 개인정보, 문서 업로드

모바일 매칭 플랫폼에서 인증은 가입 절차의 일부가 아니라 신뢰 구조의 일부입니다. 휴대폰 인증, 소셜 로그인, 사업자 승인, 근로자 문서 제출, 관리자 검토가 서로 이어집니다.

가입 전 파일 업로드도 고민이 필요했습니다. 아직 사용자 토큰이 없는 상태에서 민감 문서를 바로 사설 저장소에 올릴 수 없기 때문입니다. 앱은 먼저 선택한 파일을 로컬 상태로 보관하고, 등록 API를 통해 세션을 만든 뒤 presign 요청과 직접 업로드를 진행하는 구조로 정리했습니다.

개인정보는 검색과 운영에 필요하지만, 노출은 최소화해야 합니다. 지원자 목록에서는 필요한 범위의 정보만 보여주고, 관리자 화면에서도 실제 문서와 계정 정보가 과하게 노출되지 않도록 화면과 API를 나누었습니다. 보안은 백엔드 코드만의 문제가 아니라 관리자 UX의 문제이기도 했습니다.

관리자 콘솔은 부가 기능이 아니었다

양면 플랫폼에서는 관리자 기능이 없으면 서비스 흐름이 멈춥니다. 사업자가 가입해도 승인되지 않으면 공고를 올릴 수 없고, 근로자가 문서를 제출해도 검토되지 않으면 지원 품질이 흔들립니다.

그래서 Next.js 관리자 콘솔은 단순 대시보드가 아니라 운영 파이프라인으로 설계했습니다. 사업자 승인, 근로자 문서 확인, 공지와 배너, 광고 노출, 평판 조회, 통계 확인을 한 곳에서 다룰 수 있게 했습니다. 일반 사용자 앱과 관리자 앱은 같은 백엔드를 공유하지만, 화면 구조와 권한 검사는 분리했습니다.

관리자 인증은 httpOnly 쿠키 기반으로 정리했습니다. 토큰을 JavaScript에서 직접 읽지 않는 대신, CORS와 credentials, SameSite, Secure 설정을 정확히 맞춰야 했습니다. 인증 방식을 바꾸면 API 호출의 전제도 함께 바뀐다는 점을 다시 확인한 지점입니다.

운영 배포에서 발견한 문제

개발 환경에서 잘 되던 기능이 운영 환경에서 깨지는 경우가 여러 번 있었습니다. 가장 대표적인 문제는 로컬호스트였습니다. Next.js 관리자 앱의 공개 환경 변수는 빌드 시점에 번들에 들어갑니다. 운영 배포 전에 값을 바꿨다고 생각해도, 로컬 설정이 우선되면 빌드 결과가 로컬 API를 바라볼 수 있습니다.

Flutter 앱도 비슷했습니다. 릴리스 빌드에서 운영 환경 플래그를 넘기지 않으면 기본 개발 API를 바라볼 수 있었습니다. 인증이나 소셜 로그인이 실패하면 코드 로직을 의심하기 쉽지만, 실제 원인은 빌드 설정인 경우가 많았습니다.

그래서 출시 전 점검은 기능 테스트만으로 끝내지 않았습니다. 백엔드 typecheck, test, lint, 관리자 build, 모바일 analyze와 release build, 라우트 감사, 스키마 비교, 파일 접근 검증, 실제 기기 인증 테스트를 릴리스 게이트로 묶었습니다. 백엔드 테스트는 80개 이상으로 늘었고, 단순 성공 경로보다 권한과 상태 전이를 검증하는 케이스가 중요했습니다.

프로젝트에서 얻은 것

CRUD보다 상태 설계

매칭 플랫폼은 공고와 지원을 저장하는 서비스가 아닙니다. 역할과 상태가 제품의 품질을 결정합니다. 상태 전이가 흐릿하면 화면, API, 관리자 운영이 서로 다른 말을 하게 됩니다.

모바일 앱과 관리자 콘솔의 동시 설계

사용자 앱만 먼저 만들고 관리자를 나중에 붙이면 운영 흐름이 막힙니다. 사업자 승인, 문서 검토, 광고와 공지, 평판 관리는 제품의 일부로 처음부터 설계해야 합니다.

배포는 별도 개발 대상

빌드 시점 변수, 런타임 변수, OAuth 콜백, 쿠키 정책, 파일 접근 권한은 코드 밖처럼 보이지만 실제로는 제품 동작의 일부입니다. 출시 품질은 마지막 명령이 아니라 반복 가능한 점검 체계에서 나옵니다.

자주 받는 질문

비슷한 매칭 플랫폼을 만드는 데 얼마나 걸리나요?
역할이 두 개 이상이고 관리자 승인, 파일 업로드, 인증, 결제 또는 광고가 들어가면 보통 12-20주를 봅니다. 초기에는 화면보다 상태 모델과 권한 정책을 먼저 잡는 편이 안전합니다.

Flutter 하나로 근로자 앱과 사업자 앱을 같이 만들 수 있나요?
가능합니다. 다만 탭 구조, 홈 화면, 가입 흐름, 주요 액션은 역할별로 나누는 것이 좋습니다. 공통으로 가져갈 것은 인증, API 클라이언트, 디자인 토큰, 일부 UI 컴포넌트입니다.

서버리스 백엔드는 이런 플랫폼에 적합한가요?
API 요청이 명확하고 운영 부담을 줄이고 싶다면 적합합니다. 대신 파일 권한, DB 연결, 테스트 환경, 배포 변수, 인증 콜백 같은 경계를 꼼꼼히 관리해야 합니다.


건설, 물류, 교육, 돌봄처럼 여러 역할이 연결되는 매칭 플랫폼을 준비 중이시라면 프로젝트 문의 로 사용자 역할과 핵심 상태 흐름을 알려주세요. 첫 상담에서는 보통 기능 목록보다 상태 모델과 운영자 권한부터 같이 정리합니다.

Hammergrid Lab은 모바일 앱, 서버리스 백엔드, 관리자 콘솔, 데이터 모델링을 함께 설계하는 크리에이티브 개발 스튜디오입니다.

관련 서비스

3d웹, 3dweb, 3d 컨피규레이터, 3D 제품 컨피규레이터, 3D 제품 뷰어, WebGPU, Three.js

English version: Building a Construction Labor Matching Platform with Flutter and Serverless APIs

← 인사이트로

프로젝트 문의