Contributing Guide
Last Updated: 2026-01-09 Status: Active Audience: Developers
Thank you for contributing to the Client Portal project! This document provides guidelines and best practices for contributing.
Table of Contents
- Getting Started
- Development Workflow
- Code Standards
- Commit Guidelines
- Pull Request Process
- Testing Requirements
- Documentation
Getting Started
Prerequisites
- PHP 8.2+
- Composer
- Node.js 18+ and npm
- MySQL 8.0+
- Git
Setup Development Environment
# Clone repository
git clone <repository-url>
cd client-portal-laravel
# Install PHP dependencies
composer install
# Install Node dependencies
npm install
# Copy environment file
cp .env.example .env
# Generate application key
php artisan key:generate
# Configure database in .env
# DB_DATABASE=client_portal
# DB_USERNAME=your_username
# DB_PASSWORD=your_password
# Run migrations
php artisan migrate
# Seed development data (if available)
php artisan db:seed
# Build frontend assets
npm run dev
# Start development server
php artisan serve
Verify Setup
# Run tests
php artisan test
# Run linting
./vendor/bin/pint --test
# Check for issues
php artisan about
Development Workflow
1. Create a Branch
# Update main branch
git checkout main
git pull origin main
# Create feature branch
git checkout -b feature/your-feature-name
# Or for bug fixes
git checkout -b fix/bug-description
Branch Naming Conventions
| Prefix | Purpose | Example |
|---|---|---|
feature/ | New features | feature/invoice-pdf-export |
fix/ | Bug fixes | fix/login-redirect-loop |
refactor/ | Code refactoring | refactor/invoice-service |
docs/ | Documentation | docs/api-guide |
test/ | Test additions | test/invoice-validation |
chore/ | Maintenance | chore/update-dependencies |
2. Make Changes
- Write clean, readable code
- Follow existing patterns
- Add comments for complex logic
- Update documentation as needed
3. Test Your Changes
# Run all tests
php artisan test
# Run specific test
php artisan test --filter=ClientTest
# Run with coverage
php artisan test --coverage
# Run code style check
./vendor/bin/pint --test
4. Commit Your Changes
See Commit Guidelines below.
5. Push and Create Pull Request
# Push to remote
git push origin feature/your-feature-name
# Create PR via GitHub UI
Code Standards
PHP / Laravel
- Follow PSR-12 coding standard
- Use Laravel Pint for code formatting
- Use type hints for parameters and return types
- Use strict types where appropriate
<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\Invoice;
class InvoiceService
{
public function calculateTotal(Invoice $invoice): float
{
return $invoice->items->sum(
fn ($item) => $item->quantity * $item->unit_price
);
}
}
Run Code Formatter
# Check code style
./vendor/bin/pint --test
# Fix code style
./vendor/bin/pint
Quality Gates
The CI pipeline (.github/workflows/ci.yml) runs on every PR and enforces three gates. Run them locally before pushing:
# All three at once
composer check
# Or individually
composer lint # Pint code style (--test, fails on style issues)
composer analyse # PHPStan / Larastan (level 6, baseline-locked)
composer test # PHPUnit suite
PHPStan baseline: existing violations are absorbed in phpstan-baseline.neon. New code must NOT add to the baseline. If your change introduces a legitimate new pattern that needs the baseline updated, regenerate it explicitly and call it out in the PR:
./vendor/bin/phpstan analyse --generate-baseline=phpstan-baseline.neon --allow-empty-baseline
Do not add @phpstan-ignore comments or widen types to silence errors — fix the underlying issue instead.
composer ship also runs composer check before deploying. To deploy in an emergency without the gates, run the underlying deploy script directly (node scripts/deploy/deploy.cjs) — and follow up with the fixes immediately.
Type Hints
// Good - Full type hints
public function createInvoice(Client $client, array $items): Invoice
{
// ...
}
// Bad - No type hints
public function createInvoice($client, $items)
{
// ...
}
Blade Templates
- Use components for reusable UI
- Escape output with
{{ }}(default) - Use
@csrfin all forms - Keep logic minimal in views
{{-- Good --}}
<x-invoice-card :invoice="$invoice" />
@foreach ($items as $item)
<x-invoice-item :item="$item" />
@endforeach
{{-- Bad - Too much logic in view --}}
@foreach ($invoices->filter(fn($i) => $i->status === 'paid')->sortBy('paid_at') as $invoice)
{{-- ... --}}
@endforeach
JavaScript
- Use ES6+ syntax
- Use Alpine.js for simple interactions
- Keep JavaScript minimal (prefer Livewire or server-side)
Commit Guidelines
Commit Message Format
Type: Brief description (50 chars max)
Detailed explanation if needed (wrap at 72 chars).
Can span multiple lines.
Refs #123
Commit Types
| Type | Description |
|---|---|
Add: | New feature |
Fix: | Bug fix |
Update: | Update existing feature |
Refactor: | Code refactoring |
Docs: | Documentation changes |
Test: | Test additions/modifications |
Chore: | Maintenance tasks |
Style: | Code style changes |
Perf: | Performance improvements |
Examples
# Good
git commit -m "Add: invoice PDF export feature"
git commit -m "Fix: client email validation not checking uniqueness"
git commit -m "Update: improve dashboard loading performance"
git commit -m "Docs: add API authentication guide"
# Bad
git commit -m "updated stuff"
git commit -m "fix bug"
git commit -m "WIP"
Commit Best Practices
- One logical change per commit
- Write clear, descriptive messages
- Reference issue numbers when applicable
- Don't commit broken code
- Don't commit debug code or console logs
Pull Request Process
Before Creating PR
-
Code Complete
- Feature fully implemented
- Tests written and passing
- No linting errors
- No type errors
-
Documentation Updated
- Code comments added where needed
- README updated (if needed)
- API docs updated (if API changed)
-
Tests Passing
php artisan test ./vendor/bin/pint --test -
Branch Updated
git checkout main git pull origin main git checkout your-branch git rebase main
PR Template
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Changes Made
- Change 1
- Change 2
- Change 3
## Testing
- [ ] Unit tests added/updated
- [ ] Feature tests added/updated
- [ ] Manual testing completed
## Screenshots (if applicable)
[Add screenshots here]
## Related Issues
Fixes #123
Review Process
-
For PR Authors
- Respond to feedback promptly
- Make requested changes
- Re-request review after changes
-
For Reviewers
- Review within 24-48 hours
- Be constructive in feedback
- Test changes locally if possible
Testing Requirements
Coverage Targets
| Area | Target |
|---|---|
| Critical features | 80%+ |
| Services | 70%+ |
| Controllers | 60%+ |
| Overall | 60%+ |
Required Tests
- New features: Feature tests required
- Bug fixes: Test that reproduces bug
- API changes: API tests required
- Authorization: Policy tests required
Test Naming
// Use descriptive names
public function test_admin_can_create_client(): void {}
public function test_client_cannot_access_admin_dashboard(): void {}
public function test_invoice_total_calculates_correctly(): void {}
Running Tests
# All tests
php artisan test
# Specific test file
php artisan test tests/Feature/Admin/ClientTest.php
# Specific method
php artisan test --filter=test_admin_can_create_client
# With coverage
php artisan test --coverage
Documentation
When to Update Docs
- Adding new features
- Changing API endpoints
- Modifying configuration
- Changing workflows
Documentation Files
docs/
├── guides/ # Development guides
│ ├── CONTRIBUTING.md
│ ├── NAMING_CONVENTIONS.md
│ └── ...
├── plans/ # Implementation plans
│ ├── 001-*.md
│ └── archive/ # Completed plans
└── DOCS_GUIDE.md # Documentation conventions
Code Comments
// Good - Explains why
// Cache client data for 1 hour to reduce database load
// during high-traffic periods
$client = Cache::remember("client.{$id}", 3600, fn () => Client::find($id));
// Bad - Explains what (obvious from code)
// Get the client
$client = Client::find($id);
Best Practices
Do
- Write self-documenting code
- Keep functions small and focused
- Use meaningful variable names
- Handle errors gracefully
- Write tests for new features
- Follow existing patterns
- Ask questions when unclear
Don't
- Commit sensitive data (API keys, passwords)
- Commit commented-out code
- Commit debug statements
- Push directly to main
- Skip testing
- Ignore linting errors
- Make massive PRs (keep them focused)
Getting Help
Resources
- Laravel Documentation
- Project README
- Development Guides
Questions?
- Check existing documentation
- Search closed issues/PRs
- Ask in team chat
- Create a discussion issue
Code of Conduct
Expected Behavior
- Be respectful and professional
- Accept constructive criticism gracefully
- Focus on what is best for the project
- Show empathy towards others
Unacceptable Behavior
- Harassment or discrimination
- Trolling or insulting comments
- Publishing private information
- Unprofessional conduct
Thank you for contributing!