15 KiB
15 KiB
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 rolesMembershipPayment.php— Payment verification workflowDocument.php— Document library with versioningArticle.php,Page.php— CMS contentIssue.php— Issue tracker with comments, attachments, time logsAccountingEntry.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 controlArticleController.php— Article CRUD with publish/archivePageController.php— Page CRUD with publishAnnouncementController.php— Announcements with pinningSystemSettingsController.php— System settings UIGeneralLedgerController.php,TrialBalanceController.php— Accounting reports
app/Services:
- Purpose: Encapsulate complex business logic
- Files:
FinanceDocumentApprovalService.php— Multi-tier approval orchestrationMembershipFeeCalculator.php— Fee calculation with disability discountSettingsService.php— System settings caching/retrievalPaymentVerificationService.php— Payment workflow coordinationSiteRevalidationService.php— Next.js static site rebuild webhookSiteAssetSyncService.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 rulesUpdateMemberRequest.php— Member update rulesStoreFinanceDocumentRequest.php— Finance document rulesStoreIssueRequest.php— Issue creation rulesProfileUpdateRequest.php— User profile rules
- Pattern: Define
rules()andmessages()methods; controller receives validated data
app/Http/Middleware:
EnsureUserIsAdmin.php— Admin access check (admin role OR any permission)Authenticate.php— Session authenticationCheckPaidMembership.php— Membership status validation- Standard middleware: CSRF, encryption, trusted proxies
app/Support:
AuditLogger.php— Static class for centralized audit loggingDownloadFile.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 featuresadmin/finance/— Finance documentsadmin/members/— Member managementadmin/issues/— Issue trackeradmin/articles/,admin/pages/— CMSadmin/announcements/,admin/documents/— Announcements and document library
auth/— Login, register, password resetmember/— Member-facing viewspublic/— Public-facing viewslayouts/— Layout templates (app.blade.php, guest.blade.php)components/— Reusable Blade components
config/:
accounting.php— Account codes, amount tiers, chart of accountsauth.php— Authentication guards, registration enabled flagpermission.php— Spatie permission defaultsservices.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 andadminmiddleware
- Public:
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 pointapp/Providers/RouteServiceProvider.php— Route registrationroutes/web.php— All web routesroutes/api.php— API routes
Configuration:
config/accounting.php— Finance tier thresholds, account codesconfig/auth.php— Registration enabled flag, authentication settingsconfig/services.php— External service URLs and tokens.envfile (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 orchestrationapp/Traits/HasApprovalWorkflow.php— Reusable approval behaviorapp/Traits/HasAccountingEntries.php— Reusable accounting behavior
Business Rules:
app/Services/MembershipFeeCalculator.php— Fee calculationapp/Services/PaymentVerificationService.php— Payment workflowapp/Http/Controllers/FinanceDocumentController.php— Finance CRUD and workflow actionsapp/Http/Controllers/AdminMemberController.php— Member CRUD and lifecycle
Testing:
tests/— Test suite (PHPUnit)- Database tests use
RefreshDatabasetrait - Test accounts in seeders:
admin@test.com,requester@test.com,cashier@test.com, etc.
Database:
database/migrations/— 20+ migrationsdatabase/seeders/— RoleSeeder, ChartOfAccountSeeder, TestDataSeeder, FinancialWorkflowTestDataSeederdatabase/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/adminURL prefix - Public routes: No prefix (e.g.,
documents.index,register.member)
Database:
- Tables:
snake_caseplural (e.g.,finance_documents,membership_payments) - Columns:
snake_case(e.g.,submitted_by_user_id,approved_at) - Foreign keys:
model_idsingular (e.g.,member_id,user_id) - Timestamps:
created_at,updated_at(auto-managed) - Encrypted fields:
field_encryptedandfield_hashfor search (e.g.,national_id_encrypted,national_id_hash)
Constants:
- Status values:
ModelName::STATUS_STATEall caps (e.g.,FinanceDocument::STATUS_PENDING) - Type values:
ModelName::TYPE_NAMEall caps (e.g.,Member::TYPE_INDIVIDUAL) - Amount tiers:
ModelName::AMOUNT_TIER_LEVELall 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.phpor 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.phpwithin appropriate middleware group
- Model:
-
Example structure:
// 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.phpfor complex logic - Controller:
app/Http/Controllers/NewModuleController.phporAdmin/NewModuleController.php - Views:
resources/views/admin/new-module/orresources/views/new-module/ - Routes: Add feature routes to
routes/web.php - Migrations: Database tables in
database/migrations/
- Models: Multiple related models in
-
Example: Finance Documents (FinanceDocument → PaymentOrder → CashierLedgerEntry → AccountingEntry)
// 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.phpor method inapp/helpers.php - Example:
AuditLogger::log(),DownloadFile::download() - Global function: Add to
app/helpers.phpif 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.phpfor response formatting - Routes: Add to
routes/api.phpunderprefix('v1') - Example:
// 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:
// 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
@applyfor utility classes - Config:
tailwind.config.jswith dark mode class strategy - Build:
npm run buildcompiles topublic/css/app.css
config/:
- Purpose: Application configuration
- Committed: Yes (except
.env) - Environment-specific: Values read from
.envviaenv('KEY', 'default') - Access:
config('key.subkey')in code
tests/:
- Purpose: PHPUnit test suite
- Structure: Mirror app structure (Unit/, Feature/)
- Pattern:
RefreshDatabasetrait for database reset, use test factories - Run:
php artisan test
Structure analysis: 2026-02-13