# 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: `` **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*