363 lines
15 KiB
Markdown
363 lines
15 KiB
Markdown
# 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*
|