Skip to content

JakeEstrada/Paarth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Paarth - San Clemente Woodworking CRM

A comprehensive Customer Relationship Management (CRM) and project management system designed specifically for San Clemente Woodworking. This application helps manage the entire workflow from initial customer contact through project completion, including job tracking, scheduling, customer management, and payroll.

πŸ“‹ Table of Contents


🎯 Overview

Paarth is a full-stack CRM solution built to streamline operations for a custom woodworking business. It provides end-to-end management of:

  • Customer Relationships: Centralized customer database with multiple contact methods and addresses
  • Sales Pipeline: Visual kanban board tracking jobs through 13 distinct stages from appointment to final payment
  • Project Management: Detailed job tracking with estimates, contracts, scheduling, and file management
  • Calendar Integration: Google Calendar sync for seamless scheduling with recurrence support
  • Task Management: General todos and job-specific tasks with priority and due dates
  • Payroll: Timesheet tracking with hours, travel miles, receipts, and overtime calculations
  • Activity Logging: Comprehensive audit trail of all customer and job interactions

The system is designed with a modern, responsive UI built on Material-UI and a robust REST API backend using Express and MongoDB.


πŸ—οΈ Architecture

System Architecture

Paarth follows a client-server architecture with clear separation between frontend and backend:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   React Frontend β”‚ ◄─────► β”‚  Express Backend β”‚ ◄─────► β”‚   MongoDB       β”‚
β”‚   (Port 5173)    β”‚  REST   β”‚   (Port 4000)    β”‚  ODM    β”‚   Database      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   API    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                        β”‚
         β”‚                        β”‚
         β–Ό                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Material-UI    β”‚         β”‚  Google Calendarβ”‚
β”‚   Components     β”‚         β”‚  API (OAuth 2.0)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Frontend Architecture

Technology Stack:

  • React 19: Modern UI framework with hooks and functional components
  • Material-UI (MUI) v7: Component library for consistent design
  • React Router v7: Client-side routing
  • Axios: HTTP client for API communication
  • @dnd-kit: Drag-and-drop functionality for pipeline board
  • date-fns: Date manipulation and formatting
  • react-hot-toast: User notifications
  • Vite: Fast build tool and dev server

Structure:

frontend/src/
β”œβ”€β”€ components/          # Reusable UI components
β”‚   β”œβ”€β”€ appointments/   # Appointment-related components
β”‚   β”œβ”€β”€ customers/      # Customer management components
β”‚   β”œβ”€β”€ jobs/           # Job detail modals and forms
β”‚   β”œβ”€β”€ layout/         # MainLayout, Sidebar, TopBar
β”‚   β”œβ”€β”€ pipeline/       # Pipeline board and job cards
β”‚   β”œβ”€β”€ tasks/          # Task management components
β”‚   └── todos/          # Todo list components
β”œβ”€β”€ pages/              # Route-level page components
β”œβ”€β”€ context/            # React Context providers (if any)
β”œβ”€β”€ hooks/              # Custom React hooks
β”œβ”€β”€ services/           # API service layer
β”œβ”€β”€ theme/              # MUI theme configuration
└── utils/              # Utility functions

Key Design Patterns:

  • Component Composition: Modular, reusable components
  • Container/Presentational: Separation of data logic and presentation
  • Context API: Global state management (if needed)
  • Custom Hooks: Reusable stateful logic

Backend Architecture

Technology Stack:

  • Node.js: JavaScript runtime
  • Express 5: Web framework with middleware support
  • MongoDB: NoSQL database for flexible schema
  • Mongoose: ODM (Object Document Mapper) for MongoDB
  • JWT: Token-based authentication
  • Multer: File upload handling
  • Google APIs: Calendar integration via OAuth 2.0
  • bcryptjs: Password hashing

Structure:

backend/src/
β”œβ”€β”€ controllers/        # Business logic layer
β”‚   β”œβ”€β”€ authController.js
β”‚   β”œβ”€β”€ customerController.js
β”‚   β”œβ”€β”€ jobController.js
β”‚   β”œβ”€β”€ taskController.js
β”‚   β”œβ”€β”€ appointmentController.js
β”‚   β”œβ”€β”€ calendarController.js
β”‚   β”œβ”€β”€ fileController.js
β”‚   └── activityController.js
β”œβ”€β”€ models/            # Mongoose schemas
β”‚   β”œβ”€β”€ User.js
β”‚   β”œβ”€β”€ Customer.js
β”‚   β”œβ”€β”€ Job.js
β”‚   β”œβ”€β”€ Task.js
β”‚   β”œβ”€β”€ Appointment.js
β”‚   β”œβ”€β”€ Activity.js
β”‚   └── File.js
β”œβ”€β”€ routes/            # API route definitions
β”‚   β”œβ”€β”€ auth.js
β”‚   β”œβ”€β”€ customers.js
β”‚   β”œβ”€β”€ jobs.js
β”‚   β”œβ”€β”€ tasks.js
β”‚   β”œβ”€β”€ appointments.js
β”‚   β”œβ”€β”€ calendar.js
β”‚   └── files.js
β”œβ”€β”€ middleware/        # Express middleware
β”‚   β”œβ”€β”€ auth.js        # JWT authentication
β”‚   └── upload.js      # File upload handling
β”œβ”€β”€ utils/             # Helper functions
β”‚   β”œβ”€β”€ generateToken.js
β”‚   └── stageConfig.js
└── server.js          # Express app setup and MongoDB connection

Key Design Patterns:

  • MVC (Model-View-Controller): Clear separation of concerns
  • RESTful API: Standard HTTP methods and status codes
  • Middleware Chain: Authentication, validation, error handling
  • Repository Pattern: Data access abstraction through Mongoose models

Data Flow

  1. User Interaction: User interacts with React component
  2. API Call: Component calls API service function (Axios)
  3. HTTP Request: Request sent to Express backend
  4. Middleware: Authentication, validation, file upload processing
  5. Controller: Business logic execution
  6. Model: Database operations via Mongoose
  7. Response: JSON response sent back to frontend
  8. State Update: React component updates UI based on response

Database Architecture

MongoDB Collections:

  • users: User accounts and authentication
  • customers: Customer information with multiple addresses/contacts
  • jobs: Job details, stages, estimates, contracts, scheduling
  • tasks: General tasks and todos
  • appointments: Scheduled appointments
  • activities: Activity log for audit trail
  • files: File metadata and references

Relationships:

  • Jobs β†’ Customers (many-to-one)
  • Jobs β†’ Users (assignedTo, createdBy)
  • Tasks β†’ Jobs (optional, many-to-one)
  • Tasks β†’ Customers (optional, many-to-one)
  • Activities β†’ Jobs (optional, many-to-one)
  • Activities β†’ Customers (required, many-to-one)
  • Files β†’ Jobs (optional, many-to-one)

Indexing Strategy:

  • Jobs: stage, isArchived, customerId, assignedTo
  • Customers: Text search on name and primaryEmail
  • Activities: jobId, customerId with timestamps
  • Tasks: jobId, assignedTo, dueDate for efficient querying

πŸ’Ό Use Cases

Use Case 1: New Customer Inquiry

Scenario: A potential customer calls or emails about a custom woodworking project.

Workflow:

  1. Create Customer Record

    • Navigate to Customers page
    • Click "Add Customer"
    • Enter name, phone, email, address
    • Select source (referral, Yelp, Instagram, etc.)
    • Save customer
  2. Schedule Appointment

    • From customer detail or Pipeline page
    • Create new job with title (e.g., "Kitchen Cabinets - John Smith")
    • Job automatically starts in "Appointment Scheduled" stage
    • Add appointment date/time and location
    • Optionally sync to Google Calendar
  3. Track Follow-up

    • Create task to "Follow up on appointment"
    • Set due date and priority
    • System logs activity automatically

System Actions:

  • Customer record created in database
  • Job created with APPOINTMENT_SCHEDULED stage
  • Activity log entry: customer_created, job_created
  • If calendar sync enabled, Google Calendar event created

Use Case 2: Estimate Process

Scenario: After appointment, create and send estimate to customer.

Workflow:

  1. Move Job to Estimate Stage

    • Drag job card from "Appointment Scheduled" to "Estimate Current, first 5 days"
    • Or use job detail modal to change stage
  2. Add Estimate Details

    • Open job detail modal
    • Enter estimated value
    • Add line items (description, quantity, unit price)
    • Upload estimate PDF if available
  3. Send Estimate

    • Move job to "Estimate Sent" stage
    • System records estimate.sentAt timestamp
    • Activity log: estimate_sent
  4. Track Response

    • If no response after 7 days, job automatically moves to "Dead Estimates" archive
    • If customer responds, move to "Design Review" or "Contract Out"

System Actions:

  • Job stage updated in database
  • Estimate data saved (amount, line items, sent date)
  • Activity log: stage_change, estimate_sent
  • File upload stored in backend/uploads/ and metadata in database

Use Case 3: Contract Signing and Deposit

Scenario: Customer approves estimate and signs contract.

Workflow:

  1. Contract Preparation

    • Move job to "Contract Out" stage
    • Upload contract PDF
    • Add notes about contract terms
  2. Contract Signed

    • Move job to "Signed / Deposit Pending" stage
    • Record contract signed date
    • Enter deposit required amount
  3. Deposit Received

    • Update deposit received amount and date
    • Job moves to "Job Prep" stage
    • Activity log: contract_signed, deposit_received

System Actions:

  • Contract details saved (signed date, deposit amounts)
  • Job stage progression tracked
  • Activity log entries created
  • Payment information recorded for financial tracking

Use Case 4: Job Preparation and Scheduling

Scenario: Prepare job for production and schedule installation.

Workflow:

  1. Job Prep

    • Job in "Job Prep" stage
    • Add notes about materials, measurements, special requirements
  2. Takeoff Complete

    • Move to "Takeoff Complete" stage
    • Record takeoff completion date and person
    • Add takeoff notes
  3. Ready to Schedule

    • Move to "Ready to Schedule" stage
    • All prep work complete
  4. Schedule Installation

    • Navigate to Calendar page
    • Select job and set start/end dates
    • Configure recurrence if needed (daily, weekly, monthly, yearly)
    • Add crew notes
    • Sync to Google Calendar
    • Job moves to "Scheduled" stage

System Actions:

  • Schedule data saved (start date, end date, recurrence)
  • Google Calendar event created/updated via API
  • Job stage updated to SCHEDULED
  • Activity log: job_scheduled, calendar_sync

Use Case 5: Production and Installation

Scenario: Track job through production and installation phases.

Workflow:

  1. In Production

    • Move job to "In Production" stage
    • Add progress notes
    • Upload photos of work in progress
  2. Installation

    • Move to "Installed" stage
    • Record installation date
    • Add installation notes and photos
  3. Final Payment

    • Move to "Final Payment Closed" stage
    • Record final payment amount and method
    • Job completion date recorded

System Actions:

  • Job stage progression tracked
  • Files uploaded and linked to job
  • Activity log entries for each stage change
  • Payment information recorded

Use Case 6: Task Management

Scenario: Create and track tasks for follow-ups and job-related activities.

Workflow:

  1. Create Task

    • Navigate to Tasks page
    • Click "Add Task"
    • Enter title, description, due date
    • Set priority (low, medium, high, urgent)
    • Optionally link to job or customer
    • Assign to team member
  2. Complete Task

    • Mark task as complete
    • System records completion date and user
    • Task moves to "Completed Tasks" page

System Actions:

  • Task created in database
  • Activity log: task_created
  • On completion: task_completed activity logged
  • Task filtered from active list

Use Case 7: Payroll Tracking

Scenario: Track employee hours, travel, and expenses for payroll.

Workflow:

  1. Daily Time Entry

    • Navigate to Payroll page
    • Enter date
    • Record clock in/out times
    • Add break duration
    • System calculates total hours
  2. Travel Miles

    • Add daily travel miles
    • System calculates travel cost (configurable rate)
  3. Receipts

    • Add multiple receipts with descriptions
    • Upload receipt images/PDFs
  4. Overtime Calculation

    • System automatically calculates weighted hours
    • Hours over 40/week = 1.5x rate
  5. Print Timesheet

    • Use print functionality for clean formatted output

System Actions:

  • Hours calculated from in/out times and breaks
  • Overtime calculated based on weekly totals
  • Travel costs calculated
  • All data stored for payroll processing

Use Case 8: Customer Relationship Management

Scenario: Manage customer information and track interactions.

Workflow:

  1. View Customer

    • Navigate to Customers page
    • Search by name or email
    • View customer detail with all jobs
  2. Update Customer

    • Add additional phone numbers or emails
    • Add multiple addresses
    • Add tags for categorization
    • Update notes
  3. View Customer History

    • See all jobs associated with customer
    • View activity log for all interactions
    • See all files uploaded for customer's jobs

System Actions:

  • Customer data updated in database
  • Activity log: customer_updated
  • All related jobs remain linked
  • Search functionality uses MongoDB text indexes

Use Case 9: Archive Management

Scenario: Archive completed jobs and dead estimates.

Workflow:

  1. Archive Completed Job

    • From job detail modal, click "Archive"
    • Job moves to archive (not deleted)
    • Archived timestamp and user recorded
  2. View Dead Estimates

    • Navigate to "Dead Estimates" page
    • View estimates sent but no response after 7 days
    • Can reactivate if customer responds later
  3. View Job Archive

    • Navigate to "Job Archive" page
    • View all archived jobs
    • Filter and search archived jobs

System Actions:

  • Job isArchived flag set to true
  • Archived timestamp and user recorded
  • Job removed from active pipeline
  • All data preserved for historical reference

Use Case 10: Google Calendar Integration

Scenario: Sync job schedules with Google Calendar.

Workflow:

  1. Initial Setup

    • Follow GOOGLE_CALENDAR_SETUP.md guide
    • Configure OAuth 2.0 credentials
    • Get refresh token
  2. Schedule Job

    • Set job schedule dates on Calendar page
    • Configure recurrence if needed
    • Click "Sync to Calendar"
    • System creates Google Calendar event
  3. Automatic Updates

    • When job details change, calendar event updates
    • When job deleted/archived, calendar event removed

System Actions:

  • OAuth 2.0 authentication with Google
  • Google Calendar API calls to create/update/delete events
  • Event ID stored in job calendar.googleEventId
  • Sync status tracked in calendar.calendarStatus

✨ Features

Core Functionality

Sales Pipeline Management

  • Visual Kanban Board: Drag-and-drop interface for managing jobs through stages
  • 13 Job Stages: From appointment scheduling to final payment
  • Stage Grouping: Organized into Appointments, Sales, Readiness, and Execution phases
  • Value Tracking: Estimated and contracted values for revenue forecasting
  • Source Tracking: Track where leads come from (referral, Yelp, Instagram, etc.)

Customer Management

  • Comprehensive Database: Store customer information with multiple contact methods
  • Multiple Addresses: Support for multiple addresses per customer
  • Multiple Contacts: Multiple phone numbers and email addresses
  • Tags: Categorize customers with custom tags
  • Search Functionality: Full-text search by name or email
  • Customer History: View all jobs and activities for each customer

Job Tracking

  • Detailed Job Records: Complete job information with stages, estimates, contracts
  • File Management: Upload and manage job-related files (PDFs, images, documents)
  • Notes Timeline: Chronological notes with user attribution
  • Stage History: Track all stage changes with timestamps
  • Assignment: Assign jobs to team members
  • Archive System: Archive instead of delete for historical reference

Calendar Integration

  • Google Calendar Sync: Two-way sync with Google Calendar
  • Recurrence Support: Daily, weekly, monthly, yearly recurrence patterns
  • Automatic Updates: Calendar events update when job details change
  • Crew Notes: Add notes visible in calendar events

Task Management

  • General Tasks: Create tasks independent of jobs
  • Job-Linked Tasks: Link tasks to specific jobs or customers
  • Priority Levels: Low, medium, high, urgent priorities
  • Due Dates: Set and track due dates
  • Assignment: Assign tasks to team members
  • Completion Tracking: Mark tasks complete with timestamp

Appointment Scheduling

  • Appointment Creation: Schedule customer appointments
  • Location Tracking: Record appointment locations
  • Notes: Add appointment-specific notes
  • Completion Tracking: Mark appointments as complete

File Management

  • Upload Support: Upload files (PDFs, images, documents)
  • Job Linking: Link files to specific jobs
  • Metadata Storage: Store file metadata in database
  • Static Serving: Files served via Express static middleware

Activity Logging

  • Comprehensive Tracking: Log all customer and job interactions
  • Activity Types: 20+ activity types (created, updated, stage_change, etc.)
  • User Attribution: Track who performed each action
  • Timestamps: All activities timestamped
  • Change Tracking: Record what changed in updates

Payroll System

  • Timesheet Management: Daily hours tracking with in/out times
  • Break Tracking: Record break durations
  • Overtime Calculation: Automatic weighted hours (1.5x for hours over 40)
  • Travel Miles: Track daily travel with automatic cost calculation
  • Receipts: Add multiple receipts with descriptions
  • Print Functionality: Clean formatted print output

Developer Tasks

  • Separate Task System: Task management for development work
  • JSON Storage: Stored in developer-tasks.json file
  • Independent from Main Tasks: Separate from customer/job tasks

πŸ› οΈ Tech Stack

Frontend

  • React 19: UI framework
  • Material-UI (MUI) v7: Component library
  • React Router v7: Routing
  • Axios: HTTP client
  • @dnd-kit: Drag-and-drop
  • date-fns: Date manipulation
  • react-hot-toast: Notifications
  • Vite: Build tool

Backend

  • Node.js: Runtime environment
  • Express 5: Web framework
  • MongoDB: Database
  • Mongoose: ODM
  • JWT: Authentication
  • Multer: File uploads
  • Google APIs: Calendar integration
  • bcryptjs: Password hashing

πŸ“¦ Installation

Prerequisites

  • Node.js (v18 or higher)
  • MongoDB (local installation or MongoDB Atlas account)
  • npm or yarn
  • Google Cloud account (optional, for Calendar integration)

Step 1: Clone Repository

git clone <repository-url>
cd Paarth

Step 2: Install Backend Dependencies

cd backend
npm install

Step 3: Install Frontend Dependencies

cd ../frontend
npm install

βš™οΈ Configuration

Backend Environment Variables

Create a .env file in the backend directory:

# MongoDB Connection
MONGODB_URI=mongodb://localhost:27017/paarth
# or for MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/paarth

# JWT Secret (use a strong random string)
JWT_SECRET=your_jwt_secret_here

# Server Port
PORT=4000

# Google Calendar API (Optional - see GOOGLE_CALENDAR_SETUP.md)
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=http://localhost:4000/calendar/auth/callback
GOOGLE_REFRESH_TOKEN=your_refresh_token

# File Upload
MAX_FILE_SIZE=10485760  # 10MB in bytes

Frontend Environment Variables

Create a .env file in the frontend directory:

VITE_API_URL=http://localhost:4000

For production, update to your production API URL.


πŸš€ Running the Application

Development Mode

  1. Start MongoDB (if running locally):

    mongod
  2. Start Backend Server:

    cd backend
    npm run dev

    Backend will run on http://localhost:4000

  3. Start Frontend Development Server:

    cd frontend
    npm run dev

    Frontend will run on http://localhost:5173

Production Build

  1. Build Frontend:

    cd frontend
    npm run build

    This creates a dist folder with optimized production files.

  2. Start Backend:

    cd backend
    npm start
  3. Serve Frontend (optional): You can serve the frontend dist folder using a web server like Nginx, or configure Express to serve static files.


πŸ“ Project Structure

Paarth/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ controllers/     # Business logic
β”‚   β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ customerController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ jobController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ taskController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ appointmentController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ calendarController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ fileController.js
β”‚   β”‚   β”‚   └── activityController.js
β”‚   β”‚   β”œβ”€β”€ models/          # Mongoose schemas
β”‚   β”‚   β”‚   β”œβ”€β”€ User.js
β”‚   β”‚   β”‚   β”œβ”€β”€ Customer.js
β”‚   β”‚   β”‚   β”œβ”€β”€ Job.js
β”‚   β”‚   β”‚   β”œβ”€β”€ Task.js
β”‚   β”‚   β”‚   β”œβ”€β”€ Appointment.js
β”‚   β”‚   β”‚   β”œβ”€β”€ Activity.js
β”‚   β”‚   β”‚   └── File.js
β”‚   β”‚   β”œβ”€β”€ routes/          # API routes
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.js
β”‚   β”‚   β”‚   β”œβ”€β”€ customers.js
β”‚   β”‚   β”‚   β”œβ”€β”€ jobs.js
β”‚   β”‚   β”‚   β”œβ”€β”€ tasks.js
β”‚   β”‚   β”‚   β”œβ”€β”€ appointments.js
β”‚   β”‚   β”‚   β”œβ”€β”€ calendar.js
β”‚   β”‚   β”‚   β”œβ”€β”€ files.js
β”‚   β”‚   β”‚   └── activities.js
β”‚   β”‚   β”œβ”€β”€ middleware/      # Express middleware
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.js      # JWT authentication
β”‚   β”‚   β”‚   └── upload.js    # File upload handling
β”‚   β”‚   β”œβ”€β”€ utils/           # Helper functions
β”‚   β”‚   β”‚   β”œβ”€β”€ generateToken.js
β”‚   β”‚   β”‚   └── stageConfig.js
β”‚   β”‚   └── server.js        # Express server setup
β”‚   β”œβ”€β”€ uploads/             # Uploaded files storage
β”‚   β”œβ”€β”€ package.json
β”‚   └── .env                 # Environment variables (create this)
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/      # Reusable components
β”‚   β”‚   β”‚   β”œβ”€β”€ appointments/
β”‚   β”‚   β”‚   β”œβ”€β”€ customers/
β”‚   β”‚   β”‚   β”œβ”€β”€ jobs/
β”‚   β”‚   β”‚   β”œβ”€β”€ layout/
β”‚   β”‚   β”‚   β”œβ”€β”€ pipeline/
β”‚   β”‚   β”‚   β”œβ”€β”€ tasks/
β”‚   β”‚   β”‚   └── todos/
β”‚   β”‚   β”œβ”€β”€ pages/           # Page components
β”‚   β”‚   β”‚   β”œβ”€β”€ PipelinePage.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ CustomersPage.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ CalendarPage.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ TasksPage.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ PayrollPage.jsx
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ services/        # API services
β”‚   β”‚   β”œβ”€β”€ theme/           # MUI theme
β”‚   β”‚   β”œβ”€β”€ utils/           # Utility functions
β”‚   β”‚   β”œβ”€β”€ App.jsx          # Main app component
β”‚   β”‚   └── main.jsx         # Entry point
β”‚   β”œβ”€β”€ public/              # Static assets
β”‚   β”œβ”€β”€ package.json
β”‚   └── .env                 # Environment variables (create this)
β”œβ”€β”€ GOOGLE_CALENDAR_SETUP.md # Calendar setup guide
└── README.md                # This file

πŸ”Œ API Documentation

Authentication

All protected routes require a JWT token in the Authorization header:

Authorization: Bearer <token>

POST /auth/register

Register a new user.

Request Body:

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "password123"
}

Response:

{
  "token": "jwt_token_here",
  "user": {
    "id": "user_id",
    "name": "John Doe",
    "email": "john@example.com"
  }
}

POST /auth/login

Login user.

Request Body:

{
  "email": "john@example.com",
  "password": "password123"
}

Response:

{
  "token": "jwt_token_here",
  "user": {
    "id": "user_id",
    "name": "John Doe",
    "email": "john@example.com"
  }
}

GET /auth/me

Get current authenticated user.

Headers: Authorization: Bearer <token>

Response:

{
  "id": "user_id",
  "name": "John Doe",
  "email": "john@example.com"
}

Jobs

GET /jobs

Get all jobs (optionally filtered by stage, archived status).

Query Parameters:

  • stage: Filter by stage
  • isArchived: Filter archived jobs (true/false)
  • customerId: Filter by customer

Response:

[
  {
    "id": "job_id",
    "customerId": "customer_id",
    "title": "Kitchen Cabinets",
    "stage": "SCHEDULED",
    "valueEstimated": 15000,
    "valueContracted": 15000,
    "source": "referral",
    "schedule": {
      "startDate": "2024-01-15T00:00:00.000Z",
      "endDate": "2024-01-20T00:00:00.000Z"
    },
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

POST /jobs

Create a new job.

Request Body:

{
  "customerId": "customer_id",
  "title": "Kitchen Cabinets",
  "stage": "APPOINTMENT_SCHEDULED",
  "valueEstimated": 15000,
  "source": "referral"
}

GET /jobs/:id

Get job by ID.

PATCH /jobs/:id

Update job.

Request Body: (partial update, include only fields to update)

{
  "stage": "ESTIMATE_IN_PROGRESS",
  "valueEstimated": 16000
}

DELETE /jobs/:id

Delete job (soft delete - sets isArchived flag).

POST /jobs/:id/move-stage

Move job to different stage.

Request Body:

{
  "stage": "ESTIMATE_SENT",
  "note": "Estimate sent to customer"
}

POST /jobs/:id/archive

Archive job.


Customers

GET /customers

Get all customers.

Query Parameters:

  • search: Search by name or email

POST /customers

Create customer.

Request Body:

{
  "name": "John Smith",
  "primaryPhone": "555-1234",
  "primaryEmail": "john@example.com",
  "address": {
    "street": "123 Main St",
    "city": "San Clemente",
    "state": "CA",
    "zip": "92672"
  },
  "source": "referral"
}

GET /customers/:id

Get customer by ID.

PATCH /customers/:id

Update customer.

DELETE /customers/:id

Delete customer.

POST /customers/upload-csv

Upload customers from CSV file.


Tasks

GET /tasks

Get all tasks.

Query Parameters:

  • jobId: Filter by job
  • customerId: Filter by customer
  • completed: Filter completed tasks (true/false)

POST /tasks

Create task.

Request Body:

{
  "title": "Follow up on estimate",
  "description": "Call customer about estimate",
  "dueDate": "2024-01-15T00:00:00.000Z",
  "priority": "high",
  "jobId": "job_id"
}

POST /tasks/:id/complete

Mark task as complete.

DELETE /tasks/:id

Delete task.


Appointments

GET /appointments

Get all appointments.

Query Parameters:

  • completed: Filter completed appointments (true/false)

POST /appointments

Create appointment.

POST /appointments/:id/complete

Mark appointment as complete.

DELETE /appointments/:id

Delete appointment.


Calendar

GET /calendar/auth-url

Get Google Calendar OAuth authorization URL.

Response:

{
  "authUrl": "https://accounts.google.com/..."
}

GET /calendar/auth/callback

OAuth callback endpoint (handles code exchange for refresh token).

POST /calendar/jobs/:id/sync

Sync job to Google Calendar.

Request Body:

{
  "startDate": "2024-01-15T00:00:00.000Z",
  "endDate": "2024-01-20T00:00:00.000Z",
  "recurrence": {
    "type": "none",
    "interval": 1,
    "count": 10
  }
}

DELETE /calendar/jobs/:id

Remove job from Google Calendar.


Files

POST /files/upload

Upload file.

Request: Multipart form data

  • file: File to upload
  • jobId: (optional) Link to job
  • description: (optional) File description

Response:

{
  "id": "file_id",
  "filename": "contract.pdf",
  "path": "/uploads/contract-1234567890.pdf",
  "mimetype": "application/pdf",
  "size": 102400,
  "jobId": "job_id"
}

GET /files/:id

Get file metadata.

DELETE /files/:id

Delete file.


Developer Tasks

GET /developer-tasks

Get all developer tasks.

POST /developer-tasks

Create developer task.

PATCH /developer-tasks/:id

Update developer task.

DELETE /developer-tasks/:id

Delete developer task.


πŸ—„οΈ Database Schema

User Model

{
  name: String (required),
  email: String (required, unique, lowercase),
  password: String (required, hashed),
  isActive: Boolean (default: true),
  role: String (enum: ['admin', 'user']),
  createdAt: Date,
  updatedAt: Date
}

Customer Model

{
  name: String (required),
  primaryPhone: String,
  primaryEmail: String (lowercase),
  phones: [String],
  emails: [String],
  address: {
    street: String,
    city: String,
    state: String,
    zip: String
  },
  addresses: [{
    street: String,
    city: String,
    state: String,
    zip: String,
    fullAddress: String
  }],
  tags: [String],
  notes: String,
  source: String (enum: ['referral', 'yelp', 'instagram', 'facebook', 'website', 'repeat', 'other']),
  createdBy: ObjectId (ref: 'User'),
  createdAt: Date,
  updatedAt: Date
}

Job Model

{
  customerId: ObjectId (ref: 'Customer', required),
  title: String (required),
  stage: String (enum: [
    'APPOINTMENT_SCHEDULED',
    'ESTIMATE_IN_PROGRESS',
    'ESTIMATE_SENT',
    'ENGAGED_DESIGN_REVIEW',
    'CONTRACT_OUT',
    'CONTRACT_SIGNED',
    'DEPOSIT_PENDING',
    'JOB_PREP',
    'TAKEOFF_COMPLETE',
    'READY_TO_SCHEDULE',
    'SCHEDULED',
    'IN_PRODUCTION',
    'INSTALLED',
    'FINAL_PAYMENT_CLOSED'
  ]),
  valueEstimated: Number,
  valueContracted: Number,
  source: String (enum: ['referral', 'yelp', 'instagram', 'facebook', 'website', 'repeat', 'other']),
  assignedTo: ObjectId (ref: 'User'),
  appointment: {
    dateTime: Date,
    location: String,
    notes: String
  },
  estimate: {
    amount: Number,
    sentAt: Date,
    lineItems: [{
      description: String,
      quantity: Number,
      unitPrice: Number,
      total: Number
    }]
  },
  contract: {
    signedAt: Date,
    depositRequired: Number,
    depositReceived: Number,
    depositReceivedAt: Date
  },
  takeoff: {
    completedAt: Date,
    completedBy: ObjectId (ref: 'User'),
    notes: String
  },
  schedule: {
    startDate: Date,
    endDate: Date,
    crewNotes: String,
    recurrence: {
      type: String (enum: ['none', 'daily', 'weekly', 'monthly', 'yearly']),
      interval: Number,
      count: Number
    }
  },
  calendar: {
    googleEventId: String,
    calendarStatus: String (enum: ['created', 'updated', 'error', 'none']),
    lastSyncedAt: Date
  },
  finalPayment: {
    amountDue: Number,
    amountPaid: Number,
    paidAt: Date,
    paymentMethod: String (enum: ['cash', 'check', 'bank_transfer', 'credit_card', 'other'])
  },
  notes: [{
    content: String,
    createdBy: ObjectId (ref: 'User'),
    createdAt: Date,
    isStageChange: Boolean,
    isAppointment: Boolean
  }],
  isArchived: Boolean (default: false),
  archivedAt: Date,
  archivedBy: ObjectId (ref: 'User'),
  isDeadEstimate: Boolean (default: false),
  movedToDeadEstimateAt: Date,
  createdBy: ObjectId (ref: 'User', required),
  createdAt: Date,
  updatedAt: Date
}

Task Model

{
  jobId: ObjectId (ref: 'Job', optional),
  customerId: ObjectId (ref: 'Customer', optional),
  title: String (required),
  description: String,
  dueDate: Date,
  priority: String (enum: ['low', 'medium', 'high', 'urgent']),
  type: String (enum: ['follow_up', 'send_estimate', 'review_design', 'collect_deposit', 'schedule_install', 'site_visit', 'quality_check', 'collect_payment', 'other']),
  assignedTo: ObjectId (ref: 'User'),
  completedAt: Date,
  completedBy: ObjectId (ref: 'User'),
  createdBy: ObjectId (ref: 'User', required),
  createdAt: Date,
  updatedAt: Date
}

Activity Model

{
  type: String (enum: [
    'customer_created', 'customer_updated',
    'job_created', 'job_updated', 'job_archived',
    'stage_change', 'value_update', 'note',
    'call', 'email', 'sms', 'meeting',
    'file_uploaded', 'file_deleted',
    'estimate_sent', 'estimate_updated',
    'contract_signed', 'deposit_received', 'payment_received',
    'job_scheduled', 'calendar_sync',
    'task_created', 'task_completed',
    'takeoff_complete'
  ]),
  jobId: ObjectId (ref: 'Job', optional),
  customerId: ObjectId (ref: 'Customer', required),
  fromStage: String,
  toStage: String,
  changes: Map,
  note: String,
  fileId: ObjectId (ref: 'File'),
  fileName: String,
  amount: Number,
  paymentType: String,
  paymentMethod: String,
  duration: String,
  location: String,
  subject: String,
  googleEventId: String,
  createdBy: ObjectId (ref: 'User', required),
  createdAt: Date,
  updatedAt: Date
}

πŸ“… Google Calendar Integration

The application supports syncing jobs to Google Calendar for seamless scheduling. See GOOGLE_CALENDAR_SETUP.md for detailed setup instructions.

Key Features

  • Automatic Event Creation: When jobs are scheduled, events are created in Google Calendar
  • Recurrence Support: Daily, weekly, monthly, yearly recurrence patterns
  • Event Updates: Calendar events update when job details change
  • Event Deletion: Calendar events are removed when jobs are archived or deleted
  • OAuth 2.0: Secure authentication with Google APIs

Setup Process

  1. Create Google Cloud Project
  2. Enable Google Calendar API
  3. Create OAuth 2.0 credentials
  4. Configure redirect URI
  5. Get refresh token
  6. Add credentials to .env file

See GOOGLE_CALENDAR_SETUP.md for step-by-step instructions.


πŸ’° Payroll System

The payroll page provides comprehensive timesheet management:

Features

  • Work Hours Tracking: Daily hours with in/out times and breaks
  • Overtime Calculation: Automatic weighted hours (1.5x for hours over 40 per week)
  • Travel Miles: Track daily travel with automatic cost calculation
  • Receipts: Add multiple receipts with descriptions
  • Print Functionality: Clean formatted print output for payroll processing

Usage

  1. Navigate to Payroll page
  2. Select date
  3. Enter clock in/out times
  4. Add break duration
  5. Add travel miles (if applicable)
  6. Add receipts (if applicable)
  7. System calculates total hours and overtime
  8. Print timesheet for payroll processing

πŸ” Authentication & Security

Authentication Flow

  1. User registers/logs in via /auth/register or /auth/login
  2. Backend validates credentials and generates JWT token
  3. Token returned to frontend
  4. Frontend stores token (typically in localStorage)
  5. Frontend includes token in Authorization: Bearer <token> header for protected routes
  6. Backend middleware (requireAuth) validates token on each request
  7. User object attached to request for use in controllers

Security Features

  • Password Hashing: Passwords hashed using bcryptjs
  • JWT Tokens: Secure token-based authentication
  • Protected Routes: Middleware protects sensitive endpoints
  • CORS: Configured for secure cross-origin requests
  • File Upload Validation: File type and size validation
  • Input Validation: Mongoose schema validation

Best Practices

  • Use strong JWT secrets in production
  • Store sensitive environment variables securely
  • Use HTTPS in production
  • Regularly update dependencies
  • Implement rate limiting for production
  • Use MongoDB authentication in production

πŸ› Troubleshooting

MongoDB Connection Issues

Symptoms:

  • Backend starts but shows "MongoDB connection error"
  • API requests return 503 "Database connection unavailable"

Solutions:

  1. Ensure MongoDB is running:

    # Check if MongoDB is running
    mongosh
  2. Verify MONGODB_URI in .env:

    MONGODB_URI=mongodb://localhost:27017/paarth
  3. For MongoDB Atlas:

    • Check IP whitelist in Atlas dashboard
    • Verify connection string format
    • Check network connectivity
  4. Check MongoDB logs for errors

Google Calendar Not Working

Symptoms:

  • "Google Calendar not configured" error
  • Events not syncing to Google Calendar

Solutions:

  1. Verify all environment variables are set:

    GOOGLE_CLIENT_ID=...
    GOOGLE_CLIENT_SECRET=...
    GOOGLE_REDIRECT_URI=...
    GOOGLE_REFRESH_TOKEN=...
  2. Check that Calendar API is enabled in Google Cloud Console

  3. Verify refresh token is valid (may need to re-authenticate):

    • Visit /calendar/auth-url endpoint
    • Complete OAuth flow
    • Update refresh token in .env
  4. Check backend logs for API errors

File Upload Issues

Symptoms:

  • Files not uploading
  • "File too large" errors
  • Files not accessible

Solutions:

  1. Check MAX_FILE_SIZE in .env:

    MAX_FILE_SIZE=10485760  # 10MB
  2. Ensure uploads/ directory exists and is writable:

    mkdir -p backend/uploads
    chmod 755 backend/uploads
  3. Verify file types are allowed (check upload.js middleware)

  4. Check disk space on server

Frontend Not Connecting to Backend

Symptoms:

  • API calls failing
  • CORS errors in browser console

Solutions:

  1. Verify VITE_API_URL in frontend .env:

    VITE_API_URL=http://localhost:4000
  2. Ensure backend is running on correct port

  3. Check CORS configuration in server.js

  4. Verify backend is accessible:

    curl http://localhost:4000/health

Build Issues

Symptoms:

  • Frontend build fails
  • TypeScript errors

Solutions:

  1. Clear node_modules and reinstall:

    rm -rf node_modules package-lock.json
    npm install
  2. Check Node.js version (should be v18+):

    node --version
  3. Verify all dependencies are installed:

    npm install

πŸ“ Notes

  • The application uses MongoDB for data persistence
  • File uploads are stored in backend/uploads/
  • Developer tasks are stored in backend/developer-tasks.json
  • The frontend communicates with the backend via REST API
  • All dates are handled in local timezone
  • Jobs are archived (soft deleted) rather than permanently deleted
  • Dead estimates are automatically moved after 7 days of no response

πŸ“„ License

[Add your license here]


πŸ‘₯ Contributors

[Add contributors here]


πŸ“ž Support

For issues or questions, please create an issue or contact the development team.


πŸ”„ Version History

  • v1.0.0: Initial release with core CRM functionality
    • Sales pipeline management
    • Customer management
    • Job tracking
    • Calendar integration
    • Task management
    • Payroll system

🚧 Future Enhancements

Potential features for future releases:

  • Email integration for sending estimates/contracts
  • SMS notifications
  • Advanced reporting and analytics
  • Mobile app (React Native)
  • Multi-tenant support
  • Advanced search and filtering
  • Export functionality (PDF, CSV)
  • Integration with accounting software
  • Customer portal for viewing job status

Last updated: [Current Date]

About

Paarth is a custom CRM tool that I am building for small business needs

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages