나만의 프리랜서 프로젝트 관리 시스템 - 클라이언트 & 견적 & 인보이스 통합 관리 - 바이브코딩 레시피
중급 PHP + JavaScript Laravel + React + Inertia.js

나만의 프리랜서 프로젝트 관리 시스템 - 클라이언트 & 견적 & 인보이스 통합 관리

리포지토리명 freelancer-project-management-hub
조회수 39 1건 제출 2일 전

문제 설명

프리랜서를 위한 올인원 프로젝트 관리 시스템

프리랜서 개발자, 디자이너, 작가들을 위한 실용적인 프로젝트 관리 도구입니다. Laravel 12.x + Inertia.js + React 19 모노리스 풀스택 아키텍처로 구축하며, 클라이언트 정보부터 프로젝트 진행 상황, 견적서, 인보이스까지 한 곳에서 관리할 수 있습니다.

필수 기능

  • 클라이언트 관리: 클라이언트 정보(이름, 회사, 연락처, 이메일) CRUD
  • 프로젝트 관리: 프로젝트 생성 시 클라이언트 선택, 프로젝트명, 설명, 시작일, 마감일, 상태(견적중/진행중/완료/보류) 관리
  • 견적서 생성: 프로젝트별 작업 항목(작업명, 시간, 시간당 단가) 추가하여 자동 견적 금액 계산
  • 인보이스 발행: 완료된 프로젝트에 대해 인보이스 생성, 발행일, 지불 기한, 지불 상태(미지급/지급완료) 관리
  • 대시보드: 진행 중인 프로젝트 수, 이번 달 예상 수익, 미지급 인보이스 총액 등 통계 카드 표시
  • 관계형 데이터: Eloquent 관계 활용 (Client hasMany Projects, Project hasMany Quotes/Invoices)

선택 추가 기능 (보너스)

  • 프로젝트 상태별 필터링 및 검색
  • 클라이언트별 총 프로젝트 금액 합계 표시
  • 인보이스 PDF 다운로드 기능
  • 프로젝트 타임라인 시각화
  • 월별 수익 차트 (Chart.js 연동)

이 프로젝트를 통해 Laravel의 마이그레이션, Eloquent 관계, 컨트롤러 로직과 React의 컴포넌트 분리, 폼 처리, 조건부 렌더링을 익힐 수 있습니다.

제약 조건

  • Laravel 12.x + Inertia.js + React 19 모노리스 구조 (별도 REST API 라우트 없음)
  • Laravel Breeze React+Inertia starter kit 또는 `npx create laravel` 사용
  • SQLite 데이터베이스 사용
  • Eloquent ORM으로 모델 관계 구현 (hasMany, belongsTo)
  • Inertia::render()로 Laravel 컨트롤러에서 React 컴포넌트에 데이터 전달
  • React 19 기능 활용 (useState, useEffect, useForm 등)
  • Tailwind CSS로 반응형 UI 구현
  • 폼 검증은 Laravel의 Request Validation 활용
  • 인증 기능 제외 (단순화를 위해)

프롬프트 레시피

아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.

1
Step 1
Laravel 12.x + Inertia.js + React 19 프로젝트를 생성하고 기본 구조를 설정해주세요.

요구사항:
1. Laravel Breeze의 React+Inertia 스타터 키트로 새 프로젝트 생성 (또는 `npx create laravel` 사용)
2. SQLite 데이터베이스 설정 (.env 파일에서 DB_CONNECTION=sqlite)
3. 다음 모델과 마이그레이션 생성:
   - Client 모델: name(string), company(string, nullable), email(string), phone(string, nullable), timestamps
   - Project 모델: client_id(foreignId), title(string), description(text, nullable), start_date(date), deadline(date, nullable), status(enum: 'quoting', 'in_progress', 'completed', 'on_hold'), timestamps
   - Quote 모델: project_id(foreignId), item_name(string), hours(decimal), hourly_rate(decimal), timestamps
   - Invoice 모델: project_id(foreignId), invoice_number(string, unique), issued_date(date), due_date(date), payment_status(enum: 'unpaid', 'paid'), timestamps
4. Eloquent 관계 설정:
   - Client hasMany Projects
   - Project belongsTo Client, hasMany Quotes, hasMany Invoices
   - Quote belongsTo Project
   - Invoice belongsTo Project
5. 마이그레이션 실행하여 테이블 생성
6. Tailwind CSS가 올바르게 설정되었는지 확인

프로젝트 구조가 완성되면 `php artisan serve` 및 `npm run dev` 실행 확인까지 포함해주세요.

기대 결과: Laravel 12.x + Inertia.js + React 19 프로젝트가 생성되고, SQLite 데이터베이스에 clients, projects, quotes, invoices 테이블이 생성됩니다. 모델 간 Eloquent 관계가 정의되고, 개발 서버가 정상 작동합니다.

2
Step 2
클라이언트 관리 기능을 구현해주세요.

요구사항:
1. ClientController 생성 (resourceful controller)
2. 라우트 설정:
   - GET /clients - 클라이언트 목록
   - GET /clients/create - 클라이언트 생성 폼
   - POST /clients - 클라이언트 저장
   - GET /clients/{id}/edit - 클라이언트 수정 폼
   - PUT /clients/{id} - 클라이언트 업데이트
   - DELETE /clients/{id} - 클라이언트 삭제
3. React 페이지 컴포넌트 생성:
   - Pages/Clients/Index.jsx: 클라이언트 목록 테이블 (이름, 회사, 이메일, 전화번호, 수정/삭제 버튼)
   - Pages/Clients/Create.jsx: 클라이언트 생성 폼 (Inertia useForm 훅 사용)
   - Pages/Clients/Edit.jsx: 클라이언트 수정 폼
4. 네비게이션 메뉴에 'Clients' 링크 추가
5. 폼 검증: name, email 필수, email 형식 검증
6. 성공/에러 메시지 표시 (Inertia flash 메시지 활용)
7. Tailwind CSS로 깔끔한 테이블과 폼 디자인

컨트롤러에서 Inertia::render()로 데이터를 전달하고, React 컴포넌트에서 props로 받아 렌더링하세요.

기대 결과: 클라이언트 CRUD 기능이 완성됩니다. /clients 페이지에서 클라이언트 목록을 확인하고, 추가/수정/삭제가 가능합니다. 폼 검증이 작동하고, 성공 메시지가 표시됩니다.

3
Step 3
프로젝트 관리 기능을 구현해주세요.

요구사항:
1. ProjectController 생성 (resourceful controller)
2. 라우트 설정: /projects (index, create, store, edit, update, destroy)
3. React 페이지 컴포넌트:
   - Pages/Projects/Index.jsx: 프로젝트 목록 (제목, 클라이언트명, 시작일, 마감일, 상태 배지, 수정/삭제)
   - Pages/Projects/Create.jsx: 프로젝트 생성 폼
     - 클라이언트 선택 드롭다운 (컨트롤러에서 clients 목록 전달)
     - 제목, 설명(textarea), 시작일(date input), 마감일(date input)
     - 상태 선택 (radio 또는 select: 견적중/진행중/완료/보류)
   - Pages/Projects/Edit.jsx: 프로젝트 수정 폼
4. 프로젝트 목록에서 클라이언트명 표시 (Eloquent 관계 활용: $project->client->name)
5. 상태별 색상 배지 (견적중: gray, 진행중: blue, 완료: green, 보류: yellow)
6. 네비게이션 메뉴에 'Projects' 링크 추가
7. 폼 검증: client_id, title, start_date, status 필수
8. 프로젝트 삭제 시 확인 다이얼로그 추가

ProjectController의 index 메서드에서 $projects = Project::with('client')->latest()->get(); 형태로 클라이언트 정보를 eager loading하여 전달하세요.

기대 결과: 프로젝트 CRUD 기능이 완성됩니다. 프로젝트 생성 시 클라이언트를 선택할 수 있고, 목록에서 클라이언트명과 상태가 색상 배지로 표시됩니다. 프로젝트 추가/수정/삭제가 정상 작동합니다.

4
Step 4
프로젝트별 견적서 생성 기능을 구현해주세요.

요구사항:
1. QuoteController 생성
2. 라우트 설정:
   - GET /projects/{project}/quotes - 특정 프로젝트의 견적 항목 목록
   - POST /projects/{project}/quotes - 견적 항목 추가
   - DELETE /quotes/{quote} - 견적 항목 삭제
3. React 페이지 컴포넌트:
   - Pages/Projects/Quotes.jsx:
     - 프로젝트 정보 표시 (제목, 클라이언트명)
     - 견적 항목 추가 폼 (작업명, 시간, 시간당 단가)
     - 견적 항목 테이블 (작업명, 시간, 단가, 소계, 삭제 버튼)
     - 총 견적 금액 계산 (모든 항목의 소계 합계)
4. 프로젝트 목록(Projects/Index.jsx)에 각 프로젝트 행에 '견적서' 버튼 추가 → /projects/{id}/quotes로 이동
5. 견적 항목 추가 시 실시간으로 총액 업데이트
6. 금액 표시는 통화 형식(예: ₩1,000,000 또는 $1,000.00)으로 포맷
7. 폼 검증: item_name, hours, hourly_rate 필수, hours와 hourly_rate는 양수

QuoteController의 index 메서드에서 $project = Project::with(['client', 'quotes'])->findOrFail($id); 형태로 데이터를 전달하세요.

기대 결과: 프로젝트별 견적서 페이지가 생성됩니다. 견적 항목을 추가/삭제할 수 있고, 총 견적 금액이 자동 계산되어 표시됩니다. 프로젝트 목록에서 견적서 버튼을 클릭하면 해당 프로젝트의 견적 페이지로 이동합니다.

5
Step 5
인보이스 발행 기능을 구현해주세요.

요구사항:
1. InvoiceController 생성
2. 라우트 설정:
   - GET /projects/{project}/invoices - 특정 프로젝트의 인보이스 목록
   - GET /projects/{project}/invoices/create - 인보이스 생성 폼
   - POST /projects/{project}/invoices - 인보이스 저장
   - PATCH /invoices/{invoice}/mark-paid - 인보이스 지불 완료 처리
3. React 페이지 컴포넌트:
   - Pages/Projects/Invoices.jsx: 인보이스 목록 (인보이스 번호, 발행일, 지불 기한, 금액, 지불 상태, '지불완료' 버튼)
   - Pages/Invoices/Create.jsx: 인보이스 생성 폼
     - 인보이스 번호 자동 생성 (예: INV-2024-001)
     - 발행일, 지불 기한(date input)
     - 프로젝트의 견적 항목 목록 표시 (읽기 전용)
     - 총 인보이스 금액 자동 계산 (견적 항목 소계 합계)
4. 프로젝트 목록에 '인보이스' 버튼 추가 → /projects/{id}/invoices로 이동
5. 인보이스 목록에서 지불 상태 배지 (미지급: red, 지급완료: green)
6. 미지급 인보이스에만 '지불완료' 버튼 표시
7. 폼 검증: invoice_number(unique), issued_date, due_date 필수

InvoiceController의 create 메서드에서 프로젝트의 견적 항목을 함께 전달: $project = Project::with(['quotes', 'client'])->findOrFail($id);

기대 결과: 프로젝트별 인보이스 기능이 완성됩니다. 인보이스를 생성하면 프로젝트의 견적 항목이 자동으로 포함되고 총액이 계산됩니다. 인보이스 목록에서 지불 상태를 확인하고 '지불완료' 처리를 할 수 있습니다.

6
Step 6
대시보드 페이지를 구현하여 프로젝트 통계를 한눈에 볼 수 있게 해주세요.

요구사항:
1. DashboardController 생성 (또는 기존 컨트롤러 활용)
2. 라우트: GET / (루트 경로를 대시보드로)
3. React 페이지 컴포넌트 Pages/Dashboard.jsx:
   - 통계 카드 4개 (Tailwind Card 컴포넌트 스타일):
     a) 총 클라이언트 수
     b) 진행 중인 프로젝트 수 (status = 'in_progress')
     c) 이번 달 예상 수익 (이번 달 생성된 견적의 총액 합계)
     d) 미지급 인보이스 총액 (payment_status = 'unpaid')
   - 최근 프로젝트 목록 (최신 5개, 제목, 클라이언트명, 상태, 시작일)
   - 미지급 인보이스 목록 (인보이스 번호, 프로젝트명, 금액, 지불 기한)
4. 각 통계 카드에 아이콘 추가 (Heroicons React 사용 권장)
5. 대시보드에서 프로젝트/인보이스 클릭 시 해당 상세 페이지로 이동
6. 네비게이션 메뉴에 'Dashboard' 링크 추가 (최상단)

DashboardController에서 다음과 같은 데이터를 계산하여 전달:
- $totalClients = Client::count();
- $activeProjects = Project::where('status', 'in_progress')->count();
- $monthlyRevenue = Quote::whereHas('project', function($q) { $q->whereMonth('created_at', now()->month); })->sum(DB::raw('hours * hourly_rate'));
- $unpaidInvoices = Invoice::with('project')->where('payment_status', 'unpaid')->get();
- $recentProjects = Project::with('client')->latest()->take(5)->get();

기대 결과: 대시보드 페이지가 완성되어 루트 경로(/)에서 접근할 수 있습니다. 총 클라이언트 수, 진행 중인 프로젝트, 이번 달 예상 수익, 미지급 인보이스 총액이 카드 형태로 표시됩니다. 최근 프로젝트와 미지급 인보이스 목록도 함께 보입니다. 전체 시스템이 통합되어 프리랜서 프로젝트 관리 시스템이 완성됩니다.

제출된 작품 (1)

로그인 후 제출

프리랜서를 위한 올인원 프로젝트 관리 시스템 - 클라이언트, 견적서, 인보이스를 한 곳에서 통합 관리

조회수 22 댓글수 0 추천수 0

댓글 (1)

로그인 후 댓글을 남길 수 있습니다.
리자

숫자 입력시 소수점 없는 decimal 로 입력해야 하는데 소수점을 입력하도록 하게 하네요. 이 부분만 수정하면 제대로 된 결과를 볼수 있습니다.