Features: - Support login via phone number or email (LoginRequest) - Add members:import-roster command for Excel roster import - Merge survey emails with roster data Code Quality (Phase 1-4): - Add database locking for balance calculation - Add self-approval checks for finance workflow - Create service layer (FinanceDocumentApprovalService, PaymentVerificationService) - Add HasAccountingEntries and HasApprovalWorkflow traits - Create FormRequest classes for validation - Add status-badge component - Define authorization gates in AuthServiceProvider - Add accounting config file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
112 lines
3.9 KiB
Markdown
112 lines
3.9 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Taiwan NPO (Non-Profit Organization) management platform built with Laravel 11. Features member lifecycle management, multi-tier financial approval workflows, issue tracking, and document management with version control.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Development
|
|
php artisan serve && npm run dev # Start both servers
|
|
|
|
# Testing
|
|
php artisan test # Run all tests
|
|
php artisan test --filter=ClassName # Run specific test class
|
|
php artisan test --filter=test_method_name # Run specific test method
|
|
php artisan dusk # Run browser tests
|
|
|
|
# Database
|
|
php artisan migrate:fresh --seed # Reset with all seeders
|
|
php artisan db:seed --class=TestDataSeeder # Seed test data only
|
|
php artisan db:seed --class=FinancialWorkflowTestDataSeeder # Finance test data
|
|
|
|
# Code Quality
|
|
./vendor/bin/pint # Fix code style (PSR-12)
|
|
./vendor/bin/phpstan analyse # Static analysis
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Multi-Tier Approval Workflows
|
|
|
|
The system uses tiered approval based on amount thresholds (configurable):
|
|
- **Small (<5,000)**: Secretary approval only
|
|
- **Medium (5,000-50,000)**: Secretary → Chair
|
|
- **Large (>50,000)**: Secretary → Chair → Board
|
|
|
|
Finance documents follow a 3-stage lifecycle:
|
|
1. **Approval Stage**: Multi-tier approval based on amount
|
|
2. **Disbursement Stage**: Dual confirmation (requester + cashier)
|
|
3. **Recording Stage**: Accountant records to ledger
|
|
|
|
Key model methods for workflow state:
|
|
```php
|
|
$doc->isApprovalComplete() // All required approvals obtained
|
|
$doc->isDisbursementComplete() // Both parties confirmed
|
|
$doc->isRecordingComplete() // Ledger entry created
|
|
$doc->isFullyProcessed() // All 3 stages complete
|
|
```
|
|
|
|
### RBAC Structure
|
|
|
|
Uses Spatie Laravel Permission. Core financial roles:
|
|
- `finance_requester`: Submit finance documents
|
|
- `finance_cashier`: Tier 1 approval, payment execution
|
|
- `finance_accountant`: Tier 2 approval, create payment orders
|
|
- `finance_chair`: Tier 3 approval
|
|
- `finance_board_member`: Large amount approval
|
|
|
|
Permission checks: `$user->can('permission-name')` or `@can('permission-name')` in Blade.
|
|
|
|
### Service Layer
|
|
|
|
Complex business logic lives in `app/Services/`:
|
|
- `MembershipFeeCalculator`: Calculates fees with disability discount support
|
|
- `SettingsService`: System-wide settings with caching
|
|
|
|
### Data Security Patterns
|
|
|
|
- **National ID**: AES-256 encrypted (`national_id_encrypted`), SHA256 hashed for search (`national_id_hash`)
|
|
- **File uploads**: Private disk storage, served via authenticated controller methods
|
|
- **Audit logging**: All significant actions logged to `audit_logs` table
|
|
|
|
### Member Lifecycle
|
|
|
|
States: `pending` → `active` → `expired` / `suspended`
|
|
|
|
Key model methods:
|
|
```php
|
|
$member->hasPaidMembership() // Active with future expiry
|
|
$member->canSubmitPayment() // Pending with no pending payment
|
|
$member->getNextFeeType() // entrance_fee or annual_fee
|
|
```
|
|
|
|
### Testing Patterns
|
|
|
|
Tests use `RefreshDatabase` trait. Setup commonly includes:
|
|
```php
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->artisan('db:seed', ['--class' => 'RoleSeeder']);
|
|
}
|
|
```
|
|
|
|
Test accounts (password: `password`):
|
|
- `admin@test.com` - Full access
|
|
- `requester@test.com` - Submit documents
|
|
- `cashier@test.com` - Tier 1 approval
|
|
- `accountant@test.com` - Tier 2 approval
|
|
- `chair@test.com` - Tier 3 approval
|
|
|
|
## Key Files
|
|
|
|
- `routes/web.php` - All web routes (admin routes under `/admin` prefix)
|
|
- `app/Models/FinanceDocument.php` - Core financial workflow logic with status constants
|
|
- `app/Models/Member.php` - Member lifecycle with encrypted field handling
|
|
- `database/seeders/` - RoleSeeder, ChartOfAccountSeeder, TestDataSeeder
|
|
- `docs/SYSTEM_SPECIFICATION.md` - Complete system specification
|