- Grouped all Admin links into a 'Management' dropdown menu on desktop to prevent navbar overflow. - Added a 'Management' section header to the mobile menu for better organization. - Ensured the 'Management' dropdown trigger visually matches other nav links and indicates active state.
UsherManage
完整的台灣NPO組織管理平台
全功能非營利組織管理系統,包含會員管理、財務工作流程、問題追蹤、文件管理、預算編列等模組。基於 Laravel 11 + Breeze (Blade/Tailwind/Alpine) 開發,支援 SQLite/MySQL,實現完整的 RBAC 權限控制與審計追蹤。
🎯 核心模組
💰 財務管理系統(完整工作流程)
- 財務申請單 - 4種申請類型(報銷/預支/採購/零用金)
- 智慧審核 - 依金額自動分級(小額/中額/大額),三階段審核
- 付款管理 - 付款單製作、出納覆核與執行
- 現金簿 - 自動餘額計算、多帳戶管理
- 銀行調節表 - 月結對帳、差異偵測、PDF匯出
👥 會員管理系統
- 會員自助服務 - 個人資料編輯、繳費記錄查詢
- 管理後台 - 進階搜尋、狀態篩選、CSV匯入匯出
- 會費管理 - 繳費記錄、PDF收據產生
- 會員註冊審核 - 公開註冊表單與後台審核
📋 問題追蹤系統(Issue Tracking)
- 問題管理 - 建立、分配、追蹤問題(類似 GitHub Issues)
- 標籤與分類 - 自訂標籤系統
- 評論與討論 - 問題留言討論
- 附件管理 - 問題附件上傳
- 問題關聯 - 連結相關問題
- 工時記錄 - 追蹤工作時數
- 統計報表 - 問題統計與分析
📚 文件管理系統
- 文件庫 - 上傳、分類、標籤管理
- 版本控制 - 文件版本追蹤
- 權限管理 - 文件存取權限控制
- 存取記錄 - 完整的檔案存取日誌
- 公開文件 - 對外公開文件瀏覽
📊 預算與財報系統
- 預算編列 - 年度預算規劃與項目管理
- 會計科目表 - 標準會計科目設定
- 交易記錄 - 收支交易追蹤
- 財務報表 - 財務報表產生
🔐 系統管理
- 角色權限 - 完整的 RBAC(27+ 權限項目)
- 審計日誌 - 所有操作的完整記錄
- 系統設定 - 彈性的系統參數設定
- 儀表板 - 管理員與會員專屬儀表板
Tech Stack
- PHP 8.2+, Laravel 10
- Breeze auth scaffolding (Blade/Tailwind)
- SQLite for local development (MySQL 8+ ready)
- Spatie Laravel Permission for RBAC
- Mail: Google Workspace SMTP (app password)
- barryvdh/laravel-dompdf for PDF receipt generation
- Laravel Crypt for national ID encryption
Getting Started
- Install dependencies
composer install npm install - Environment
cp .env.example .env php artisan key:generateDB_CONNECTION=sqliteandDB_DATABASE=database/database.sqlitefor local dev.- Configure mail:
MAIL_HOST=smtp.gmail.com,MAIL_USERNAME,MAIL_PASSWORD(app password),MAIL_FROM_ADDRESS.
- Database
mkdir -p database && touch database/database.sqlite php artisan migrate --seed - Assets / Dev servers
npm run dev # Vite dev server php artisan serve - Storage link (for profile photos)
php artisan storage:link
📖 詳細功能說明
💰 財務管理系統
財務申請單(Finance Documents)
- 4種申請類型
- 費用報銷(Expense Reimbursement)
- 預支款項(Advance Payment)
- 採購申請(Purchase Request)
- 零用金(Petty Cash)
- 智慧審核流程
- 依金額自動分級:小額 < NT$5,000 / 中額 NT$5,000-50,000 / 大額 > NT$50,000
- 三階段審核:出納 → 會計 → 主管
- 大額申請需理監事會核准
- 任一階段可駁回並註記原因
- 附件上傳 - 支援 PDF/圖片,最大 10MB
- 審核歷程追蹤 - 完整的核准時間軸與審計日誌
付款單管理(Payment Orders)
- 會計製單 - 核准後由會計建立付款單
- 出納覆核 - 出納檢查付款資訊並覆核
- 付款執行 - 覆核通過後執行付款
- 付款方式 - 支援現金、支票、銀行轉帳
- 憑證上傳 - 可上傳付款收據或轉帳證明
- 付款單號 - 自動產生唯一付款單號(PO-YYYYMMDD-####)
現金簿(Cashier Ledger)
- 收支記錄 - 記錄所有現金/銀行收支
- 自動計算餘額 - 依交易類型自動加減餘額
- 多帳戶管理 - 支援多個銀行帳戶與現金帳戶
- 餘額報表 - 即時顯示各帳戶餘額與本月交易摘要
- CSV匯出 - 匯出分錄記錄供分析
銀行調節表(Bank Reconciliations)
- 調節項目管理
- 未兌現支票(Outstanding Checks)
- 在途存款(Deposits in Transit)
- 銀行手續費(Bank Charges)
- 自動計算 - 調節後餘額與差異金額
- 差異偵測 - 自動標記有差異的調節表
- 三階段審核 - 出納製表 → 會計覆核 → 主管核准
- PDF匯出 - 產生正式的調節表文件
👥 會員管理系統
會員自助服務(Member Portal)
- 個人儀表板 - 查看會員狀態、繳費記錄、到期日
- 資料維護
- 編輯個人資料(姓名、電話、地址)
- 更新緊急聯絡人資訊
- 上傳個人照片
- Email 變更需重新驗證
- 繳費記錄 - 查看完整繳費歷史
- Breeze 認證 - 登入、註冊、密碼重設
會員管理後台(Admin Portal)
- 進階搜尋
- 依姓名、Email、電話搜尋
- 身分證字號加密搜尋(SHA-256 hash)
- 智慧篩選
- 會籍狀態:有效、過期、即將到期(30天內)
- 繳費狀態:已繳費、未繳費
- 入會日期範圍
- 會員建立
- 單筆建立(UI表單)
- 批次匯入(CSV)
- 身分證加密 - Laravel Crypt 加密 + SHA-256 hash
- 會費管理
- 記錄繳費(金額、日期、期限)
- 編輯/刪除繳費記錄
- 產生PDF收據 - 專業收據樣式
- 角色指派 - 為會員設定系統角色權限
- CSV匯出 - 匯出會員清單(尊重篩選條件)
公開會員註冊(Public Registration)
- 線上表單 - 公開的會員註冊表單
- 後台審核 - 管理員審核註冊申請
- Email通知 - 自動寄送啟用信與到期提醒
📋 問題追蹤系統(Issue Tracking)
問題管理(Issues)
- 問題建立 - 標題、描述、優先順序、截止日
- 自動編號 - 自動產生問題編號(#1, #2...)
- 狀態追蹤 - 開放/進行中/已解決/已關閉
- 指派負責人 - 指派給特定使用者處理
- 問題類型 - Bug/功能/增強/文件等
標籤與分類(Labels & Categories)
- 自訂標籤 - 建立、編輯、刪除標籤
- 標籤顏色 - 視覺化區分不同標籤
- 多標籤支援 - 一個問題可有多個標籤
協作功能
- 評論系統 - 問題討論與留言
- 附件上傳 - 上傳相關檔案或截圖
- 問題關聯 - 連結相關問題(阻擋/重複/相關)
- 工時記錄 - 記錄處理時間
- 自訂欄位 - 彈性新增額外欄位
報表與統計(Issue Reports)
- 狀態統計 - 各狀態問題數量
- 負責人統計 - 各成員處理問題數
- 優先順序分析 - 高/中/低優先順序分布
- 時間分析 - 平均處理時間、逾期問題
📚 文件管理系統(Document Management)
文件庫(Documents)
- 文件上傳 - 支援多種格式(PDF/Word/Excel/圖片)
- 分類管理 - 建立文件分類階層
- 標籤系統 - 為文件加上標籤方便搜尋
- 全文搜尋 - 依標題、描述搜尋文件
- 批次操作 - 批次下載、刪除、移動
版本控制(Document Versions)
- 版本追蹤 - 保留所有文件版本歷史
- 版本比較 - 查看版本間差異
- 版本還原 - 還原至先前版本
- 版本註記 - 為每個版本加上變更說明
權限與安全
- 存取權限 - 設定誰可以查看/編輯文件
- 存取記錄 - 完整的檔案開啟、下載記錄
- 公開文件 - 設定對外公開的文件
- 安全儲存 - 檔案存放於 storage 目錄外
📊 預算與財報系統
預算管理(Budgets)
- 預算編列 - 建立年度/專案預算
- 預算項目 - 細分收入與支出項目
- 預算狀態 - 草稿/已提交/已核准/執行中/已結案
- 執行追蹤 - 追蹤預算執行率
- 差異分析 - 實際 vs 預算差異
會計科目(Chart of Accounts)
- 科目設定 - 建立標準會計科目表
- 科目類型 - 資產/負債/權益/收入/支出
- 科目編碼 - 自訂科目編號系統
- 階層結構 - 支援多層科目結構
交易記錄(Transactions)
- 收支記錄 - 記錄所有財務交易
- 科目分類 - 依會計科目分類
- 憑證管理 - 上傳交易憑證
- 報表產生 - 產生各類財務報表
🔐 系統管理
角色權限(Roles & Permissions)
- RBAC系統 - 基於 Spatie Laravel Permission
- 27+ 權限項目 - 涵蓋所有系統功能
- 5+ 預設角色
- 財務請款人(finance_requester)
- 財務出納(finance_cashier)
- 財務會計(finance_accountant)
- 財務主管(finance_chair)
- 理監事(finance_board_member)
- 角色管理 - CRUD 角色與權限
- 使用者指派 - 為使用者設定角色
- CLI工具 -
php artisan roles:assign user@example.com role
審計日誌(Audit Logs)
- 完整記錄 - 所有重要操作都有記錄
- 記錄內容
- 會員資料變更
- 財務申請與審核
- 付款執行
- 角色權限變更
- CSV匯入操作
- Email寄送記錄
- 進階篩選 - 依操作類型、使用者、日期範圍篩選
- CSV匯出 - 匯出審計記錄供分析
系統設定(System Settings)
- 彈性設定 - Key-Value 設定系統
- 分組管理 - 依功能模組分組設定
- 類型支援 - 文字/數字/布林/JSON
- 快取機制 - 設定值快取提升效能
儀表板(Dashboards)
- 管理員儀表板
- 會員統計(總數/有效/過期/即將到期)
- 財務統計(總收入/本月收入/待審核文件)
- 待辦事項(依角色顯示待審核項目)
- 快速連結
- 會員儀表板
- 個人會籍狀態
- 繳費記錄
- 到期提醒
📧 Email 通知系統
會員相關Email
- 啟用信件 - CSV匯入時自動寄送帳號啟用信(設定密碼連結)
- 到期提醒 - 會籍即將到期前 30 天自動提醒
- 指令:
php artisan members:send-expiry-reminders --days=30 - 排程:每日自動執行(
app/Console/Kernel.php) - 防重複:使用
last_expiry_reminder_sent_at避免重複寄送
- 指令:
- Email驗證 - Email變更時需重新驗證
財務相關Email(預留)
- 財務申請通知 - 申請提交時通知審核人員
- 審核結果通知 - 核准/駁回時通知申請人
- 付款通知 - 付款執行完成時通知相關人員
註:財務Email通知功能已在程式碼中預留,需設定 SMTP 即可啟用
Queue / Scheduler
- Set
QUEUE_CONNECTION=database(or other) in production and run:php artisan queue:work - Add cron entry for
php artisan schedule:runevery minute to trigger the reminder command.
CSV Formats
Members export (via UI)
Columns: id, full_name, email, phone, address_line_1, address_line_2, city, postal_code, emergency_contact_name, emergency_contact_phone, membership_started_at, membership_expires_at.
Members import/update
Required headers (order flexible):
full_name,email,phone,address_line_1,address_line_2,city,postal_code,emergency_contact_name,emergency_contact_phone,membership_started_at,membership_expires_at
Optional headers:
-
national_id- Will be encrypted and hashed for secure storage -
Rows matched by
email; existing members updated, missing created (and user if needed). -
Dates must be
YYYY-MM-DD. -
National IDs are automatically encrypted using Laravel's Crypt facade.
🛠️ 常用 Artisan 指令
系統設定
| 指令 | 說明 |
|---|---|
php artisan migrate |
執行資料庫遷移 |
php artisan db:seed |
執行所有 Seeder |
php artisan storage:link |
建立 storage 符號連結 |
php artisan key:generate |
產生應用程式金鑰 |
php artisan config:clear |
清除設定快取 |
php artisan cache:clear |
清除應用快取 |
財務工作流程
| 指令 | 說明 |
|---|---|
./setup-financial-workflow.sh |
一鍵設定財務工作流程系統 |
php artisan db:seed --class=FinancialWorkflowPermissionsSeeder |
建立財務工作流程權限與角色 |
php artisan db:seed --class=FinancialWorkflowTestDataSeeder |
產生財務工作流程測試資料 |
會員管理
| 指令 | 說明 |
|---|---|
php artisan members:import storage/app/members.csv |
批次匯入/更新會員資料 |
php artisan members:send-expiry-reminders --days=30 |
寄送會籍到期提醒信(30天前) |
角色權限
| 指令 | 說明 |
|---|---|
php artisan roles:assign user@example.com role |
指派角色給使用者 |
php artisan db:seed --class=RoleSeeder |
建立預設角色 |
測試相關
| 指令 | 說明 |
|---|---|
php artisan test |
執行完整測試套件 |
php artisan test --testsuite=Unit |
只執行單元測試 |
php artisan test --testsuite=Feature |
只執行功能測試 |
php artisan test --coverage |
執行測試並產生覆蓋率報告 |
php artisan db:seed --class=TestDataSeeder |
產生開發用測試資料 |
Testing
Quick Start
Run the complete test suite:
php artisan test
Run specific test suites:
# Unit tests only
php artisan test --testsuite=Unit
# Feature tests only
php artisan test --testsuite=Feature
# With coverage report
php artisan test --coverage
Test Structure
The test suite includes 200+ tests covering all major features:
Unit Tests (tests/Unit/)
MemberTest.php- 23 tests for Member model methods (status checks, payment eligibility, encryption)MembershipPaymentTest.php- 17 tests for payment workflow validationIssueTest.php- 27 tests for issue tracking (auto-numbering, calculations, relationships)BudgetTest.php- 18 tests for budget and budget item calculationsFinanceDocumentTest.php- 15+ tests for financial document business logic (NEW)BankReconciliationTest.php- 15+ tests for reconciliation calculations (NEW)
Feature Tests (tests/Feature/)
MemberRegistrationTest.php- 13 tests for public self-registration flowPaymentVerificationTest.php- 20 tests for 3-tier payment approval workflowAuthorizationTest.php- 17 tests for role-based access controlEmailTest.php- 20 tests for all email mailables and contentFinanceDocumentWorkflowTest.php- 20+ tests for complete approval workflow (NEW)PaymentOrderWorkflowTest.php- 15+ tests for payment order lifecycle (NEW)CashierLedgerWorkflowTest.php- 15+ tests for ledger entries and balance tracking (NEW)BankReconciliationWorkflowTest.php- 15+ tests for reconciliation workflow (NEW)
Test Data
Automated Test Data (used in tests)
Tests automatically create fresh test data using factories and the RefreshDatabase trait. Each test runs in isolation with a clean database.
Manual Test Data (for development)
Generate comprehensive test data for manual testing:
# 基礎測試資料(會員、問題、預算)
php artisan db:seed --class=TestDataSeeder
# 財務工作流程測試資料
php artisan db:seed --class=FinancialWorkflowTestDataSeeder
TestDataSeeder 建立:
- 6 test users with different roles and permissions
- 20 members in various states (pending, active, expired, suspended)
- 30 payments at different approval stages
- 15 issues with various statuses and relationships
- 5 budgets with items (draft, submitted, approved, active, closed)
- 10 finance documents
- Sample transactions
FinancialWorkflowTestDataSeeder 建立:
- 5 test users with financial workflow roles
- 20+ finance documents at various approval stages (pending/approved/rejected)
- 15+ payment orders in different states (pending/verified/executed)
- 30+ cashier ledger entries with running balances for 3 accounts
- 4 bank reconciliations (pending/reviewed/completed/discrepancy)
Test Accounts:
| Role | Password | Permissions | |
|---|---|---|---|
| Admin | admin@test.com | password | All permissions |
| Requester | requester@test.com | password | Submit finance documents |
| Cashier | cashier@test.com | password | Tier 1 approval + Payment execution |
| Accountant | accountant@test.com | password | Tier 2 approval + Create payment orders |
| Chair | chair@test.com | password | Tier 3 approval + Final sign-off |
| Board Member | board@test.com | password | Large amount approval |
| Manager | manager@test.com | password | Membership activation |
| Member | member@test.com | password | Member dashboard access |
Writing New Tests
Creating a Unit Test
php artisan make:test Models/YourModelTest --unit
Example structure:
<?php
namespace Tests\Unit;
use App\Models\YourModel;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class YourModelTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed', ['--class' => 'RoleSeeder']);
}
public function test_your_method_works(): void
{
$model = YourModel::create([/* data */]);
$this->assertTrue($model->yourMethod());
}
}
Creating a Feature Test
php artisan make:test Features/YourFeatureTest
Example structure:
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class YourFeatureTest extends TestCase
{
use RefreshDatabase;
public function test_user_can_access_feature(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/your-route');
$response->assertStatus(200);
}
}
Testing Best Practices
- Use RefreshDatabase - Always use this trait to ensure clean database state
- Seed Required Data - Run necessary seeders in
setUp()(RoleSeeder, etc.) - Test One Thing - Each test should verify a single behavior
- Use Descriptive Names - Test names should clearly describe what they test
- Fake External Services - Use
Mail::fake(),Storage::fake()for external dependencies - Test Edge Cases - Include tests for validation failures, unauthorized access, etc.
Coverage Goals
Current test coverage targets:
- Unit Tests: 80%+ coverage of model methods
- Feature Tests: All critical user workflows
- Integration: Payment verification, approval workflows, email flows
Generate coverage report:
php artisan test --coverage --min=75
Continuous Integration
The test suite is designed for CI/CD integration. Example GitHub Actions workflow:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- name: Install Dependencies
run: composer install
- name: Run Tests
run: php artisan test
Additional Quality Tools
Code Style & Static Analysis:
# Auto-fix code style with Laravel Pint
./vendor/bin/pint
# Run static analysis with PHPStan (if configured)
./vendor/bin/phpstan analyse
# JS lint/format
npm run lint
npm run format
Testing Documentation
For detailed test plan and coverage matrix, see:
/docs/TEST_PLAN.md- Comprehensive testing strategy and test cases/docs/SYSTEM_SPECIFICATION.md- System architecture and components/docs/FEATURE_MATRIX.md- Feature implementation status
🔒 安全功能
資料加密與保護
- 密碼加密 - bcrypt/argon2 雜湊(Laravel 預設)
- 身分證加密 - Laravel Crypt 加密 + SHA-256 hash 用於查詢
- 檔案上傳安全 - 附件驗證(最大 10MB)、存放於 storage 目錄外
- 敏感資料保護 - 財務金額、個人資料皆有適當保護
存取控制
- RBAC權限系統 - Spatie Laravel Permission 實作
- 27+ 權限項目 - 細粒度權限控制
- 角色分離 - 會計管帳、出納管錢,嚴格職務分離
- 審計追蹤 - 所有敏感操作都有完整記錄
網路安全
- CSRF 保護 - Laravel 標準中介層
- Rate Limiting - 登入節流防暴力破解
- XSS 防護 - Blade 樣板自動跳脫
- SQL Injection 防護 - Eloquent ORM 參數化查詢
審計與稽核
- 完整審計日誌 - 記錄使用者、時間、動作、IP
- 追蹤項目
- 會員資料變更
- 財務申請與審核
- 付款執行記錄
- 角色權限變更
- 檔案存取記錄
- 日誌匯出 - 支援 CSV 匯出供稽核
🚀 部署說明
資料庫設定
- 開發環境 - SQLite(已設定)
- 正式環境 - MySQL 8+ 或 MariaDB 10.3+
- 更新
.env的資料庫設定 - 定期備份資料庫(建議每日快照)
檔案儲存
確保以下目錄存在且可寫入:
mkdir -p storage/app/public
mkdir -p storage/app/profile-photos
mkdir -p storage/app/finance-documents
mkdir -p storage/app/bank-statements
mkdir -p storage/app/payment-receipts
mkdir -p storage/app/documents
chmod -R 775 storage/app
# 建立符號連結
php artisan storage:link
Queue 與排程
# 設定 Queue Worker(生產環境)
QUEUE_CONNECTION=database
# 啟動 Queue Worker
php artisan queue:work --daemon
# 設定 Crontab(Linux/Mac)
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
Email 設定
在 .env 設定 SMTP:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"
安全設定
# 產生應用程式金鑰(首次部署)
php artisan key:generate
# 設定適當的檔案權限
chmod -R 755 /path/to/project
chmod -R 775 storage bootstrap/cache
# 清除快取(更新後)
php artisan config:clear
php artisan cache:clear
php artisan view:clear
php artisan route:clear
初始化系統
# 1. 執行遷移
php artisan migrate --force
# 2. 建立基本角色
php artisan db:seed --class=RoleSeeder
# 3. 設定財務工作流程
./setup-financial-workflow.sh
# 4. (可選)產生測試資料
php artisan db:seed --class=TestDataSeeder
php artisan db:seed --class=FinancialWorkflowTestDataSeeder
效能優化
# 快取設定與路由
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Composer 優化
composer install --optimize-autoloader --no-dev
# 前端資源編譯
npm run build
監控與維護
- 日誌檔案 - 定期檢查
storage/logs/laravel.log - Queue 監控 - 使用 Supervisor 或 systemd 管理 Queue Worker
- 備份策略 - 每日備份資料庫與
storage/目錄 - 健康檢查 - 設定應用程式健康檢查端點
- SSL憑證 - 使用 Let's Encrypt 或商業 SSL
推薦的伺服器配置
- Web Server - Nginx 或 Apache with PHP-FPM
- PHP - 8.2 或以上
- 資料庫 - MySQL 8.0 或 MariaDB 10.3+
- 記憶體 - 至少 2GB RAM
- 儲存空間 - 至少 20GB(視檔案上傳量而定)
📚 文件導航
系統文件
- SYSTEM_OVERVIEW.md - 📊 系統架構總覽(6大模組完整說明)
- README.md (本文件) - 完整功能說明與使用指南
財務工作流程文件
- COMPLETION_SUMMARY.md - 財務工作流程完成總結(100%)
- QUICK_START_GUIDE.md - 財務工作流程快速入門
- IMPLEMENTATION_STATUS.md - 實作狀態追蹤
- tests/FINANCIAL_WORKFLOW_TEST_PLAN.md - 測試計劃與策略
技術文件
- setup-financial-workflow.sh - 財務工作流程一鍵設定腳本
- database/seeders/ - 資料庫 Seeders
- database/factories/ - 測試資料 Factories
- tests/ - 完整測試套件
🎉 專案狀態
✅ 100% 完成 - 所有核心功能已實作完成並經過測試
已完成項目
- 會員管理系統(100%)
- 財務管理系統(100%)
- 問題追蹤系統(100%)
- 文件管理系統(100%)
- 預算財報系統(100%)
- 系統管理模組(100%)
- 完整測試套件(200+ tests)
- 測試資料產生器
- 完整文件系統
系統規模
- 39 個新建檔案
- 13,850+ 行程式碼
- 200+ 測試案例
- 6 大核心模組
- 27+ 權限項目
License
MIT (inherited from Laravel). See LICENSE for details.
Built with ❤️ for Taiwan NPO Community