Developer Onboarding

Deep dive into setting up and contributing to Church Ledger.

Developer Onboarding

Welcome to the Church Ledger developer guide. This document provides a detailed walkthrough of the project setup, development workflow, and coding standards.

Development Environment Setup

Church Ledger is built with Laravel 12 and React 19. We use pnpm for package management and Supabase for our database.

Prerequisites

Install the following on your system based on your OS:

Database Configuration

We recommend using Supabase for development. Create a new project on Supabase and grab your connection string.

Local Setup

# 1. Clone & Enter git clone https://github.com/veikeAgency/church-ledger.git cd church-ledger # 2. Setup Environment cp .env.example .env php artisan key:generate # 3. Install Backend & Frontend composer install pnpm install # 4. Migrate Database php artisan migrate

Running the App

Instead of managing multiple terminals, we use composer run dev which leverages concurrently to start everything:

composer run dev

This command starts:

  • Vite: Frontend hot-reloading at http://localhost:5173.
  • Artisan Serve: Backend API server at http://localhost:8000.
  • Queue Listener: Processes background jobs like PDF generation.

Architecture & Data Flow

Church Ledger follows a "Modern Monolith" approach using Inertia.js. This removes the need for a client-side API layer and router.

When a user searches for a member, the request flows through a Repository to keep the Controller clean.

// app/Http/Controllers/MemberController.php public function index(Request $request) { $search = $request->input('search'); // Delegate to repository $members = $this->memberRepository->search($search) ->through(fn ($item) => $item->load('household')); return Inertia::render('members/index', [ 'members' => $members, 'filters' => $request->only(['search']), ]); }

Coding Standards

1. Multi-Tenancy

Always use the BelongsToChurch trait in your models. It automatically applies a global scope to ensure users only see data from their own church.

use App\Traits\BelongsToChurch; class Pledge extends Model { use BelongsToChurch; // Automatically filters by church_id }

2. Authorization

Define permissions in database/seeders/RolesAndPermissionsSeeder.php. Use the can middleware in routes and the auth.user.can prop in React.

const { auth } = usePage().props { auth.user.can["manage offerings"] && ( <Button variant="primary">Add Offering</Button> ) }

3. Background Processing

Any task that takes longer than 200ms (like PDF generation or bulk emails) should be dispatched to a job.

// Example: PDF Export public function exportPdf() { GenerateMemberReport::dispatch(auth()->user()); return back()->with('success', 'Report generation started. Check your email soon.'); }