Loading the catalog…
Loading the catalog…
1. 화물 배송 현장을 위한 정산 서비스 bigpicture_truck 은 화물 기사들의 일일 배송 실적(신용·착불·추가금)과 주간 출금을 기록하고, 관리자가 전 직원의 정산 현황을 한눈에 파악할 수 있도록 돕는 서비스다. 기사는 매일 운행을 마치고 매출과 출금 내역을 입력하며, 관리자는 대시보드에서 차종별 필터와 검색을 거쳐 정산 합계를 확인하거나 직원별 상세 내역을 조회하고 엑셀로 내려받는다. 운전대를 잡고 이동하는 현장 기사들이 모바일 브라우저나 설치형 앱으로 매일 정산을 마감해야 하는 만큼, 입력의 명확성과 모바일 환경에서의 즉각적인 반응 속도가 서비스의 핵심이다. 2. 현장에서 마주한 세 가지 문제 서비스를 실제 운영하는 과정에서 기능과 성능 양쪽 모두에서 병목이 드러났다. 첫째, 정산 계산과 입력 방식이 지나치게 복잡했다. 기존에는 매출에서 '그 주에 일한 앞 5일'에 단가를 곱한 사납금을 제하고 실수령을 구한 뒤 출금을 차감하는 구조였다. 하지만 사납금 부과 방식은 현장 기사들에게 심리적인 압박을 주었고, 기준 요일을 따지는 계산식 또한 불필요한 혼선을 낳았다. 입력 방식 역시 '건별로 찍는 방식'과 '하루치를 몰아서 적는 방식'을 동시에 열어두었더니, 두 방식의 결과가 같음에도 기사들이 무엇을 골라야 할지 매번 고민해야 했다. 둘째, 모바일 환경의 터치 반응이 극도로 느렸다. 프로덕션 환경의 TTFB(Time to First Byte)를 측정한 결과 1.2~2.7초에 달했다. Vercel의 응답 헤더( x-vercel-id )를 추적해 보니 icn1::iad1 로 찍혔다. 사용자의 요청은 서울 엣지( icn1 )로 들어오는데, 서버리스 함수는 미국 동부( iad1 )에서 돌고 있었고, 데이터베이스(Supabase)는 서울에 있었다. 쿼리 하나를 던질 때마다 태평양을 두 번 건너야 했고, 레이아웃과 페이지 컴포넌트가 세션 확인과 프로필 조회를 각각 따로 수행해 네트워크 왕복 횟수마저 두 배로 늘어났다. 여기에 loading.tsx 조차 없어 탭을 눌러도 서버 응답이 올 때까지 화면이 멈춘 것처럼 보였다. 셋째, 정산 내역 수정의 권한과 이력 추적 체계가 없었다. 돈이 오가는 정산 데이터임에도 누가 언제 무엇을 고쳤는지 남지 않았다. 또한 직원이 지난 정산 내역을 임의로 고칠 수 있으면 주간 마감 데이터가 뒤틀릴 위험이 있었고, 반대로 당일 오기입한 내역까지 완전히 잠가버리면 관리자에게 사소한 수정 요청이 쏟아지는 문제가 있었다. 3. 구조적 단순화와 인프라 정리를 위한 판단 복잡해진 화면과 느린 흐름을 해결하기 위해 과감하게 덜어내고 바닥부터 정리하는 방식을 택했다. 정산 모델의 단순화 : 사납금 개념을 앱 전체에서 통째로 걷어냈다. 정산 구조를 매출 → 출금 → 미출금(매출 - 출금액) 세 줄로 축약했다. 복잡한 주간 근무일수 계산식을 지우고, AI 코칭 프롬프트와 공지사항, 설정 화면에서도 사납금 관련 로직을 전면 제거했다. 입력 UX의 단일화 : '건별 입력' 탭을 없애고 '하루 마감'과 '일주일 출금' 2개 탭으로 통일했다. 당일 총건수와 신용·착불·추가금 합계만 적어 마감하도록 통일해 현장의 입력 피로도를 낮췄다. 함수 리전 서울 고정 및 요청 최적화 : Vercel 서버리스 함수 실행 리전을 icn1 (서울)로 강제 지정했다. 데이터베이스가 있는 곳과 물리적 거리를 일치시켜 네트워크 지연을 없애는 것이 최우선이었다. 반복되는 프로필 조회는 React cache 로 묶어 요청당 1회만 실행되게 했고, 홈 화면에서 순차적으로 호출하던 AI 보고서 쿼리를 기존 정산 쿼리와 Promise.all 로 묶어 병렬화했다. RLS 기반 수정 통제와 DB 트리거 이력 관리 : 직원은 오직 '오늘 작성한 내역'만 수정·삭제할 수 있도록 제한했다. 이때 기준을 작업 일자( work_date )가 아니라 실제 등록 시점( created_at )으로 잡았다. 지난 날짜의 정산을 뒤늦게 올리더라도 방금 등록한 오타는 즉시 고칠 수 있어야 하기 때문이다. 관리자는 과거 내역까지 자유롭게 수정할 수 있게 하되, 변경 사항은 애플리케이션 코드가 아닌 PostgreSQL DB 트리거로 자동 기록하도록 설계했다. 화면 코드에 이력 로깅을 두면 API 엔드포인트나 진입 경로가 늘어날 때 누락이 발생하기 때문이다. 또한 Supabase의 anon 키가 노출되는 환경을 고려해 서버 액션뿐 아니라 RLS(Row Level Security)에도 동일한 시간 검증 규칙을 걸어 직접 호출 우회를 막았다. 4. 변경 전과 변경 후 4.1. 서버리스 함수 리전 지정 및 병렬 쿼리 처리 서버리스 함수가 미국 동부에서 돌며 DB 왕복 지연을 일으키던 문제를 해결하기 위해 vercel.json 에 서울 리전을 명시하고, 페이지 로드 시 필요한 데이터 조회를 하나로 묶었다. 변경 전: 순차 쿼리 호출 및 기본 리전 실행 // src/app/(app)/home/page.tsx const [{ data: entryData }, { data: weekDaily }, { data: weekWithdrawals }] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), ]); // 앞선 조회가 끝난 뒤 순차적으로 따로 호출하여 추가 왕복 시간 발생 const { data: aiRows } = await supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate); 변경 후: vercel.json 서울 리전 고정 및 병렬 조회 통합 // vercel.json { "framework": "nextjs", "regions": ["icn1"] } // src/app/(app)/home/page.tsx // 모든 초기 데이터를 Promise.all 내에서 병렬로 단 한 번에 조회 const [ { data: entryData }, { data: weekDaily }, { data: weekWithdrawals }, { data: aiRows }, ] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate), ]); 4.2. 정산 내역 수정 권한 통제 직원이 과거의 정산 데이터를 임의로 조작하지 못하도록 서버 액션 단계에서 작성 시점을 검증하도록 변경했다. 변경 후: 작성일 기준의 권한 판별 로직 // src/app/(app)/entry-actions.ts /** * 내역 수정·삭제 권한 판단: * - 관리자: 전 직원 내역 언제든 수정 가능 * - 직원: 본인 내역이면서 '오늘 작성한 것(created_at)'만 수정 가능 */ async function canModify(entryId: string): Promise<ActionResult> { const profile = await requireProfile(); const supabase = await createClient(); const { data } = await supabase .from("entries") .select("user_id, created_at") .eq("id", entryId) .maybeSingle(); if (!data) return { ok: false, error: "내역을 찾을 수 없습니다." }; if (profile.role === "admin") return { ok: true }; if (data.user_id !== profile.id) { return { ok: false, error: "본인 내역만 수정할 수 있습니다." }; } if (!isWrittenToday(data.created_at)) { return { ok: false, error: "오늘 적은 것만 수정할 수 있습니다. 지난 것은 관리자에게 말씀해 주세요.", }; } return { ok: true }; } 5. 정돈된 화면과 안정적인 운영 이번 작업을 통해 모바일 현장과 관리자 운영 환경 전반이 실질적으로 달라졌다. 체감 응답 속도와 입력 단순화 : Vercel 서버리스 함수를 서울( icn1 )로 옮겨 쿼리 왕복 시간을 줄였고, loading.tsx 와 스켈레톤, useLinkStatus 진행 막대를 적용해 탭 이동 시 멈춤 현상을 없앴다. 정산 입력은 '하루 마감' 하나로 정리되어 기사들이 작성 방식을 고민할 필요가 없어졌다. 정산 데이터의 무결성 확보 : 직원은 오늘 등록한 내역만 바로잡을 수 있고 과거 내역은 관리자만 수정할 수 있도록 분리했다. 수정 권한은 서버 액션과 RLS 양쪽에 걸려 있어 우회가 불가능하며, 관리자가 항목을 수정하거나 삭제할 때마다 DB 트리거가 이전 값과 변경 값을 빠짐없이 entry_logs 에 기록한다. 관리 업무의 효율화 : 관리자 대시보드에는 차종별 다중 필터와 선택 인원 합계 보기 기능이 붙었고, 조회 기간 그대로 직원별 시트와 누적 미출금액이 포함된 엑셀(.xlsx) 파일로 내려받을 수 있게 되었다. 독립적인 앱 배포 환경 구축 : Capacitor를 얹어 웹 서비스를 감싸는 형태로 안드로이드 정식 서명 키(PKCS12) 기반의 APK 자동 빌드 파이프라인(GitHub Actions)을 마련했다. 스토어 심사를 기다리지 않고 웹 배포만으로 앱 화면이 즉시 갱신되며, 카카오톡 인앱 브라우저 차단과 삼성 보안 설정을 안내하는 전용 설치 페이지( /install )를 제공해 현장 기사들의 설치 문의를 줄였다.
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
사납금과 건별 입력을 덜어내고, 서울 리전 고정과 DB 트리거로 화물 정산을 단순화하기. 1. 화물 배송 현장을 위한 정산 서비스 bigpicture_truck 은 화물 기사들의 일일 배송 실적(신용·착불·추가금)과 주간 출금을 기록하고, 관리자가 전 직원의 정산 현황을 한눈에 파악할 수 있도록 돕는 서비스다. 기사는 매일 운행을 마치고 매출과 출금 내역을 입력하며, 관리자는 대시보드에서 차종별 필터와 검색을 거쳐 정산 합계를 확인하거나 직원별 상세 내역을 조회하고 엑셀로 내려받는다. 운전대를 잡고 이동하는 현장 기사들이 모바일 브라우저나 설치형 앱으로 매일 정산을 마감해야 하는 만큼, 입력의 명확성과 모바일 환경에서의 즉각적인 반응 속도가 서비스의 핵심이다. 2. 현장에서 마주한 세 가지 문제 서비스를…
Open source