docs: map existing codebase

This commit is contained in:
2026-02-13 10:34:18 +08:00
parent 296a70010d
commit 47218c1874
7 changed files with 2083 additions and 0 deletions

View File

@@ -0,0 +1,362 @@
# Codebase Structure
**Analysis Date:** 2026-02-13
## Directory Layout
```
usher-manage-stack/
├── app/ # Application code
│ ├── Console/Commands/ # Custom Artisan commands
│ ├── Exceptions/ # Exception handlers
│ ├── Http/
│ │ ├── Controllers/ # Web controllers split by domain
│ │ │ ├── Admin/ # Admin panel controllers (10 controllers)
│ │ │ ├── Api/ # API controllers (4 controllers)
│ │ │ ├── Auth/ # Auth controllers
│ │ │ ├── *Controller.php # Main route controllers
│ │ ├── Middleware/ # HTTP middleware (11 total)
│ │ ├── Requests/ # Form Request validation classes
│ │ └── Resources/ # API response resources
│ ├── Jobs/ # Queued jobs
│ ├── Mail/ # Mail classes (notifications)
│ ├── Models/ # Eloquent models (36 models)
│ ├── Observers/ # Model observers
│ ├── Providers/ # Service providers
│ ├── Services/ # Business logic services (7 services)
│ ├── Support/ # Helper classes
│ ├── Traits/ # Shared model traits (2 traits)
│ ├── View/Components/ # Blade components
│ ├── helpers.php # Global helper functions
├── bootstrap/ # Bootstrap files
├── config/ # Configuration files
├── database/
│ ├── migrations/ # Database migrations
│ ├── seeders/ # Database seeders
│ ├── factories/ # Model factories for testing
│ └── schema/ # Schema dump
├── resources/
│ ├── css/ # Tailwind CSS
│ ├── views/ # Blade templates
│ │ ├── admin/ # Admin panel views (20+ subdirectories)
│ │ ├── auth/ # Auth views (login, register, etc.)
│ │ ├── components/ # Reusable components
│ │ ├── emails/ # Email templates
│ │ ├── layouts/ # Layout files
│ │ ├── member/ # Member-specific views
│ │ ├── public/ # Public-facing views
│ │ └── profile/ # Profile views
├── routes/
│ ├── web.php # Web routes (393 lines, 200+ named routes)
│ ├── api.php # API routes (v1)
│ ├── auth.php # Auth routes
│ ├── console.php # Console commands
│ └── channels.php # Broadcasting channels
├── storage/
│ ├── app/ # File uploads (private)
│ ├── logs/ # Application logs
│ └── framework/ # Framework files
├── tests/ # Test suite
├── .env.example # Environment template
├── CLAUDE.md # Project-specific instructions
├── composer.json # PHP dependencies
└── artisan # Artisan CLI entry point
```
## Directory Purposes
**app/Models:**
- Purpose: Eloquent models representing database tables
- Contains: 36 models with relationships, scopes, accessors
- Key files:
- `Member.php` — Member lifecycle (status, disability, identity type)
- `FinanceDocument.php` — Finance approval workflow (27+ status constants)
- `User.php` — User authentication and roles
- `MembershipPayment.php` — Payment verification workflow
- `Document.php` — Document library with versioning
- `Article.php`, `Page.php` — CMS content
- `Issue.php` — Issue tracker with comments, attachments, time logs
- `AccountingEntry.php` — Double-entry bookkeeping records
**app/Http/Controllers:**
- Purpose: Handle HTTP requests and coordinate responses
- Contains: 25+ controller classes
- Structure:
- `Admin/` — 10 controllers for admin features (articles, documents, pages, etc.)
- `Api/` — 4 controllers for REST API endpoints
- Root controllers for public and authenticated routes
- Pattern: Inject dependencies, call services, return view/response
**app/Http/Controllers/Admin:**
- `DocumentController.php` — Document CRUD with version control
- `ArticleController.php` — Article CRUD with publish/archive
- `PageController.php` — Page CRUD with publish
- `AnnouncementController.php` — Announcements with pinning
- `SystemSettingsController.php` — System settings UI
- `GeneralLedgerController.php`, `TrialBalanceController.php` — Accounting reports
**app/Services:**
- Purpose: Encapsulate complex business logic
- Files:
- `FinanceDocumentApprovalService.php` — Multi-tier approval orchestration
- `MembershipFeeCalculator.php` — Fee calculation with disability discount
- `SettingsService.php` — System settings caching/retrieval
- `PaymentVerificationService.php` — Payment workflow coordination
- `SiteRevalidationService.php` — Next.js static site rebuild webhook
- `SiteAssetSyncService.php`, `NextjsRepoSyncService.php` — Frontend sync
**app/Traits:**
- Purpose: Shared behavior across multiple models
- `HasApprovalWorkflow.php` — Multi-tier approval methods (6 methods)
- `HasAccountingEntries.php` — Double-entry bookkeeping (8 methods)
- Usage: Models add `use TraitName;` to inherit behavior
**app/Http/Requests:**
- Purpose: Form request validation classes (implicit validation in controllers)
- Files:
- `StoreMemberRequest.php` — Member creation rules
- `UpdateMemberRequest.php` — Member update rules
- `StoreFinanceDocumentRequest.php` — Finance document rules
- `StoreIssueRequest.php` — Issue creation rules
- `ProfileUpdateRequest.php` — User profile rules
- Pattern: Define `rules()` and `messages()` methods; controller receives validated data
**app/Http/Middleware:**
- `EnsureUserIsAdmin.php` — Admin access check (admin role OR any permission)
- `Authenticate.php` — Session authentication
- `CheckPaidMembership.php` — Membership status validation
- Standard middleware: CSRF, encryption, trusted proxies
**app/Support:**
- `AuditLogger.php` — Static class for centralized audit logging
- `DownloadFile.php` — File download handler with cleanup
- Usage: `AuditLogger::log('action_name', $model, $metadata)`
**resources/views:**
- Purpose: Blade templates rendering HTML
- Structure:
- `admin/` — 20+ directories for admin features
- `admin/finance/` — Finance documents
- `admin/members/` — Member management
- `admin/issues/` — Issue tracker
- `admin/articles/`, `admin/pages/` — CMS
- `admin/announcements/`, `admin/documents/` — Announcements and document library
- `auth/` — Login, register, password reset
- `member/` — Member-facing views
- `public/` — Public-facing views
- `layouts/` — Layout templates (app.blade.php, guest.blade.php)
- `components/` — Reusable Blade components
**config/:**
- `accounting.php` — Account codes, amount tiers, chart of accounts
- `auth.php` — Authentication guards, registration enabled flag
- `permission.php` — Spatie permission defaults
- `services.php` — External service configuration (Nextjs revalidate URL)
- `app.php`, `database.php`, `cache.php`, etc. — Standard Laravel configs
**routes/:**
- `web.php` — All 200+ web routes
- Public: `/`, `/documents`, `/register/member` (if enabled), `/beta/bug-report`
- Auth: `/dashboard`, `/my-membership`, `/member/submit-payment`, `/profile`
- Admin: `/admin/*` with group prefix and `admin` middleware
- `api.php` — API v1 routes
- `/api/v1/articles`, `/api/v1/pages`, `/api/v1/homepage`, `/api/v1/public-documents`
- Authentication: Sanctum (optional)
- `auth.php` — Login, register, password reset routes
## Key File Locations
**Entry Points:**
- `public/index.php` — Application entry point
- `app/Providers/RouteServiceProvider.php` — Route registration
- `routes/web.php` — All web routes
- `routes/api.php` — API routes
**Configuration:**
- `config/accounting.php` — Finance tier thresholds, account codes
- `config/auth.php` — Registration enabled flag, authentication settings
- `config/services.php` — External service URLs and tokens
- `.env` file (not committed) — Environment variables
**Core Logic:**
- `app/Models/FinanceDocument.php` — Finance workflow logic (approval, disbursement, recording)
- `app/Models/Member.php` — Member lifecycle logic (status checks, fees)
- `app/Services/FinanceDocumentApprovalService.php` — Approval orchestration
- `app/Traits/HasApprovalWorkflow.php` — Reusable approval behavior
- `app/Traits/HasAccountingEntries.php` — Reusable accounting behavior
**Business Rules:**
- `app/Services/MembershipFeeCalculator.php` — Fee calculation
- `app/Services/PaymentVerificationService.php` — Payment workflow
- `app/Http/Controllers/FinanceDocumentController.php` — Finance CRUD and workflow actions
- `app/Http/Controllers/AdminMemberController.php` — Member CRUD and lifecycle
**Testing:**
- `tests/` — Test suite (PHPUnit)
- Database tests use `RefreshDatabase` trait
- Test accounts in seeders: `admin@test.com`, `requester@test.com`, `cashier@test.com`, etc.
**Database:**
- `database/migrations/` — 20+ migrations
- `database/seeders/` — RoleSeeder, ChartOfAccountSeeder, TestDataSeeder, FinancialWorkflowTestDataSeeder
- `database/factories/` — Model factories for testing
## Naming Conventions
**Files:**
- Controllers: `PluralCamelCase + Controller.php` (e.g., `FinanceDocumentController.php`)
- Models: `SingularCamelCase.php` (e.g., `FinanceDocument.php`)
- Requests: `Action + ModelName + Request.php` (e.g., `StoreFinanceDocumentRequest.php`)
- Migrations: `YYYY_MM_DD_HHMMSS_action_table_name.php`
- Views: `snake_case.blade.php` (e.g., `create.blade.php`, `edit.blade.php`)
**Directories:**
- Controllers: Group by feature/domain (Admin/, Api/, Auth/)
- Views: Mirror controller structure (admin/, auth/, member/, public/)
- Models: Flat in app/Models/
- Services: Flat in app/Services/
- Migrations: Flat in database/migrations/
**Routes:**
- Named routes: `domain.action` (e.g., `admin.finance.index`, `member.payments.store`)
- Admin routes: Prefix `admin.` and grouped under `/admin` URL prefix
- Public routes: No prefix (e.g., `documents.index`, `register.member`)
**Database:**
- Tables: `snake_case` plural (e.g., `finance_documents`, `membership_payments`)
- Columns: `snake_case` (e.g., `submitted_by_user_id`, `approved_at`)
- Foreign keys: `model_id` singular (e.g., `member_id`, `user_id`)
- Timestamps: `created_at`, `updated_at` (auto-managed)
- Encrypted fields: `field_encrypted` and `field_hash` for search (e.g., `national_id_encrypted`, `national_id_hash`)
**Constants:**
- Status values: `ModelName::STATUS_STATE` all caps (e.g., `FinanceDocument::STATUS_PENDING`)
- Type values: `ModelName::TYPE_NAME` all caps (e.g., `Member::TYPE_INDIVIDUAL`)
- Amount tiers: `ModelName::AMOUNT_TIER_LEVEL` all caps (e.g., `FinanceDocument::AMOUNT_TIER_SMALL`)
## Where to Add New Code
**New Feature (CRUD):**
- Primary code:
- Model: `app/Models/NewModel.php` — Define relationships, scopes, accessors
- Controller: `app/Http/Controllers/Admin/NewModelController.php` or root controller
- Requests: `app/Http/Requests/Store/UpdateNewModelRequest.php`
- Views: `resources/views/admin/new-models/` with index/create/edit/show
- Routes: Add to `routes/web.php` within appropriate middleware group
- Example structure:
```php
// Model relationships
public function relationships()
// Form validation in FormRequest
public function rules()
// Controller action
public function store(StoreNewModelRequest $request)
// View rendering
return view('admin.new-models.create', ['data' => ...]);
```
**New Component/Module (Multi-Model Feature):**
- Implementation:
- Models: Multiple related models in `app/Models/`
- Service: `app/Services/NewModuleService.php` for complex logic
- Controller: `app/Http/Controllers/NewModuleController.php` or `Admin/NewModuleController.php`
- Views: `resources/views/admin/new-module/` or `resources/views/new-module/`
- Routes: Add feature routes to `routes/web.php`
- Migrations: Database tables in `database/migrations/`
- Example: Finance Documents (FinanceDocument → PaymentOrder → CashierLedgerEntry → AccountingEntry)
```php
// Service orchestrates workflow
$service->approveBySecretary($document, $user);
// Models track state
$document->status, $document->disbursement_status, $document->recording_status
```
**Utilities/Helpers:**
- Shared helpers: `app/Support/HelperClass.php` or method in `app/helpers.php`
- Example: `AuditLogger::log()`, `DownloadFile::download()`
- Global function: Add to `app/helpers.php` if used in multiple places
- Config values: Add to appropriate `config/` file
**New API Endpoint:**
- Controller: `app/Http/Controllers/Api/ResourceController.php`
- Resource: `app/Http/Resources/ResourceResource.php` for response formatting
- Routes: Add to `routes/api.php` under `prefix('v1')`
- Example:
```php
// routes/api.php
Route::get('/articles', [ArticleController::class, 'index']);
// app/Http/Controllers/Api/ArticleController.php
public function index() {
return ArticleResource::collection(Article::active()->get());
}
```
**New Blade Component:**
- File: `resources/views/components/component-name.blade.php`
- Class (if needed): `app/View/Components/ComponentName.php`
- Usage: `<x-component-name :data="$data" />`
**New Service:**
- File: `app/Services/NewService.php`
- Usage: Dependency injection in controllers or other services
- Pattern:
```php
// In controller
public function action(NewService $service) {
$result = $service->doSomething();
}
```
**New Trait (Shared Behavior):**
- File: `app/Traits/HasNewBehavior.php`
- Usage: `use HasNewBehavior;` in models
- Pattern: Define methods that multiple models need
## Special Directories
**storage/app/:**
- Purpose: Private file uploads
- Subdirectories: `finance-documents/`, `articles/`, `disability-certificates/`
- Generated: Yes
- Committed: No (in .gitignore)
- Access: `Storage::disk('local')->get($path)` or via authenticated controller
**database/schema/:**
- Purpose: Schema dump for reference
- Generated: By `php artisan schema:dump`
- Committed: Yes (read-only reference)
- Use: Check table structure without opening migrations
**resources/css/:**
- Purpose: Tailwind CSS source
- Style: Uses `@apply` for utility classes
- Config: `tailwind.config.js` with dark mode class strategy
- Build: `npm run build` compiles to `public/css/app.css`
**config/:**
- Purpose: Application configuration
- Committed: Yes (except `.env`)
- Environment-specific: Values read from `.env` via `env('KEY', 'default')`
- Access: `config('key.subkey')` in code
**tests/:**
- Purpose: PHPUnit test suite
- Structure: Mirror app structure (Unit/, Feature/)
- Pattern: `RefreshDatabase` trait for database reset, use test factories
- Run: `php artisan test`
---
*Structure analysis: 2026-02-13*