# 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