This commit is contained in:
2025-10-22 20:08:22 +05:00
commit 736e3bef18
2573 changed files with 120385 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
### DB architecture guidelines
#### Overview
...
#### Core Concepts
- ....
#### User table
- # Model App\Models\User
- # Migrations database/migrations/0001_01_01_000000_create_users_table.php
- # Seeder database/seeders/UsersTableSeeder.php
...
##### Structure
- id
- username
- first_name
- last_name
- phone
- phone_verified_at
- locale
- password_must_be_changed
- options
- email_verified_at
- remember_token
- created_at
- updated_at
##### Indexes
- username (unique)
- phone (unique)
- email (unique)
- email_verified_at
- remember_token
##### Relations
- roles (Role model)
#### Branch table
- # Model App\Modules\Branch\Models\Branch
- # Migrations app/Modules/Branch/Database/Migrations/2025_10_09_190439_create_branches_table.php
- # Seeder Not found
##### Structure
- id
- unique_code
- name (json)
- address (json)
- region (string)[in: ag, mr, ah, ak, dz, bn, lb]
- province_id
- phone_numbers (json)
- billing_username
- billing_password
- billing_swift_username
- billing_swift_password
- billing_visa_master_username
- billing_visa_master_password
- billing_sber_username
- billing_sber_password
- active
- created_at
- updated_at
##### Indexes
- unique_code (unique)
- region
##### Relations
- province (Province model)
- users (User model)
#### Province table
- # Model App\Modules\Province\Models\Province
- # Migrations app/Modules/Province/Database/Migrations/2025_10_09_185951_create_provinces_table.php
- # Seeder Not found
##### Structure
- id
- region
- name (json)
- active
- created_at
- updated_at
##### Indexes
- None
##### Relations
- None
#### LoanOrderRequiredDocs table
- # Model App\Modules\LoanOrder\Models\LoanOrderRequiredDocs
- # Migrations app/Modules/LoanOrder/Database/Migrations/2025_10_09_211513_create_loan_order_required_docs_table.php
- # Seeder Not found
##### Structure
- id
- name (text)
- value (text)
- created_at
- updated_at
##### Indexes
- None
##### Relations
- loanOrders (LoanOrder model)
#### LoanType table
- # Model App\Modules\LoanOrder\Models\LoanType
- # Migrations app/Modules/LoanOrder/Database/Migrations/2025_10_09_183412_create_loan_types_table.php
- # Seeder Not found
##### Structure
- id
- name (json)
- tax
- maturity
- notes
- active
- created_at
- updated_at
##### Indexes
- None
##### Relations
- None
#### LoanOrder table
- # Model App\Modules\LoanOrder\Models\LoanOrder
- # Migrations app/Modules/LoanOrder/Database/Migrations/2025_10_09_220443_create_loan_orders_table.php
- # Seeder Not found
##### Structure
- id
- unique_id
- source
- user_id
- loan_type
- region
- branch_id
- customer_name
- customer_surname
- customer_patronic_name
- passport_address
- real_address
- passport_serie
- passport_id
- passport_given_at
- passport_given_by
- born_place
- born_at
- email
- phone
- phone_additional
- phone_home
- work_region
- work_province_id
- work_company
- work_company_accountant_number
- work_started_at
- work_salary
- work_position
- education
- marriage_status
- passport_one (text)
- passport_two (text)
- passport_three (text)
- passport_four (text)
- loan_amount
- card_number
- card_name
- card_month
- card_year
- guarantor_name
- guarantor_surname
- guarantor_patronic_name
- guarantor_passport_serie
- guarantor_passport_id
- guarantor_card_number
- guarantor_card_name
- guarantor_card_month
- guarantor_card_year
- guarantor_note
- guarantor_2_name
- guarantor_2_surname
- guarantor_2_patronic_name
- guarantor_2_passport_serie
- guarantor_2_passport_id
- guarantor_2_card_number
- guarantor_2_card_name
- guarantor_2_card_month
- guarantor_2_card_year
- guarantor_2_note
- loan_card_number
- loan_card_name
- loan_card_month
- loan_card_year
- loan_order_required_doc_id
- status
- satisfiable
- notes (text)
- created_at
- updated_at
- deleted_at
##### Indexes
- unique_id (unique)
- source
- customer_name
- customer_surname
- passport_serie
- passport_id
- phone
- work_region
- loan_amount
##### Relations
- loanType (LoanType model)
- branch (Branch model)
- workProvince (Province model)
- user (User model)
- requiredDocs (LoanOrderRequiredDocs model)
#### OtpVerification table
- # Model App\Modules\OtpVerification\Models\OtpVerification
- # Migrations app/Modules/OtpVerification/Database/Migrations/2025_09_22_164249_create_otp_verifications_table.php
- # Seeder Not found
##### Structure
- id
- username
- code
- created_at
- updated_at
##### Indexes
- None
##### Relations
- None
#### AuthEvent table
- # Model App\Modules\BaseAuth\Models\AuthEvent
- # Migrations app/Modules/BaseAuth/Database/Migrations/2025_10_07_181725_create_auth_events_table.php
- # Seeder Not found
##### Structure
- id
- name
- request_method
- ip
- user_agent
- target_url
- options (json)
- created_at
- updated_at
##### Indexes
- name
- request_method
- ip
- user_agent
- target_url
##### Relations
- None

View File

@@ -0,0 +1,246 @@
### Modular Architecture Guidelines
#### Overview
This application uses a custom modular architecture to organize features into distinct, self-contained units called "Modules". Each module encapsulates a specific piece of functionality, including its own models, migrations, seeders, controllers, and more. The system is designed to automatically discover and register components from enabled modules.
The core of this system is the `App\Modules\ModuleRepository`, which is responsible for finding, loading, and managing all the modules in the application. A set of helper functions is provided for easy interaction with the module repository.
#### Core Concepts
- **Module**: A directory within `app/Modules` that represents a distinct feature.
- **`ModuleRepository`**: A singleton service (`App\Modules\ModuleRepository`) that manages all modules. Accessed via the `modular()` helper.
- **`ModuleServiceProvider`**: A service provider (`App\Modules\ModuleServiceProvider`) that automatically discovers and registers resources (routes, migrations, views, etc.) from all enabled modules.
- **`ModuleContract`**: An interface (`App\Modules\ModuleContract`) that every module's main class must implement. It defines the basic contract for a module.
- **`BaseModule`**: A wrapper class (`App\Modules\BaseModule`) that holds information about a module, such as its path, name, and an instance of its `ModuleContract`.
- **Helpers**: Global functions defined in `app/Helpers/helpers.php` to simplify interaction with the modular system.
- **Core Module**: A special module located in `app/Modules/Core` that provides Artisan commands for creating new modules and their components.
#### Module Structure
Every module is a directory located in `app/Modules/`. For a module named `Example`, the structure would be `app/Modules/Example/`.
##### Required Structure
- `app/Modules/Example/ExampleModule.php`: This is the main class for the module. It **must** implement `App\Modules\ModuleContract`.
```php
<?php
namespace App\Modules\Example;
use App\Modules\ModuleContract;
class ExampleModule implements ModuleContract
{
/**
* Check if module is enabled
*/
public function isEnabled(): bool
{
return true;
}
/**
* Disable module
*/
public function disable(): void
{
// Logic to disable the module
}
/**
* Enable module
*/
public function enable(): void
{
// Logic to enable the module
}
/**
* Check if module has a filament resource
*/
public function hasFilamentResource(): bool
{
return false;
}
/**
* Get module composer requirements
*
* @return array<int, \App\Modules\Core\ModulePackage>
*/
public function getComposerRequirements(): array
{
return [];
}
/**
* Get module composer suggestions
*
* @return array<int, \App\Modules\Core\ModulePackage>
*/
public function getComposerSuggestions(): array
{
return [];
}
}
```
##### Automatic Discovery
The `ModuleServiceProvider` automatically discovers and registers the following directories and files for all **enabled** modules. The paths shown are for an `Example` module. If module name is `MyModule`, kebab naming will be used for routes, helpers, and config files will be `app/Modules/MyModule/Configs/my-module-config.php`, `app/Modules/MyModule/Routes/my-module-routes.php`, `app/Modules/MyModule/my-module-helpers.php`.
- **Configurations**: `app/Modules/Example/Configs/example-config.php`
- **Migrations**: `app/Modules/Example/Database/Migrations/`
- **Seeders**: `app/Modules/Example/Database/Seeders/`
- **Routes**: `app/Modules/Example/Routes/example-routes.php`
- **Views**: `app/Modules/Example/Resources/Views/`
- **Translations**: `app/Modules/Example/Resources/lang/`
- **Helper Files**: `app/Modules/Example/example-helpers.php`
##### Composer Dependencies
Modules can declare Composer package dependencies. This is useful for making a module's requirements explicit. There are two types of dependencies you can define: requirements and suggestions.
- **Requirements**: Packages that are essential for the module to function correctly.
- **Suggestions**: Packages that are recommended but not strictly necessary.
These dependencies are defined in the module's main class by implementing the `getComposerRequirements()` and `getComposerSuggestions()` methods from the `ModuleContract` interface. These methods should return an array of `ModulePackage` objects.
**Note:** Declaring a dependency does not automatically install it. This feature is for informational purposes, helping developers understand the module's dependencies.
Here is an example of how to declare a required package and a suggested module dependency:
```php
// app/Modules/Example/ExampleModule.php
use App\Modules\Core\ModulePackage;
use App\Modules\Core\ModulePackageType;
// ...
public function getComposerRequirements(): array
{
return [
new ModulePackage(
type: ModulePackageType::PACKAGE,
name: 'spatie/laravel-translatable',
message: 'This package is used for translatable models.',
version: '^8.0'
)
];
}
public function getComposerSuggestions(): array
{
return [
new ModulePackage(
type: ModulePackageType::MODULE,
name: 'OtherModule',
message: 'This module provides additional related functionality.'
)
];
}
```
##### Conventional Structure
Following the conventional structure is essential for the automatic discovery mechanism to work.
```
app/Modules/Example/
├── Configs/
└── example-config.php
├── Database/
├── Migrations/
└── 2025_09_22_000000_create_example_table.php
└── Seeders/
└── ExampleSeeder.php
├── Http/
├── Controllers/
└── Requests/
├── Models/
└── Example.php
├── Repositories/
├── Resources/
├── Lang/
└── Views/
├── Routes/
└── example-routes.php
├── example-helpers.php
└── ExampleModule.php
```
#### Creating a New Module
The `Core` module provides an Artisan command to simplify the creation of new modules.
1. **Run the `make:module` command**:
```bash
php artisan make:module NewFeature
```
This command will scaffold a new module in `app/Modules/NewFeature` with the necessary directory structure and default files, including the `NewFeatureModule.php` class, a model, controller, repository, and migration.
You can use the `--plain` option to create a module with only the main module class and an empty directory.
```bash
php artisan make:module NewFeature --plain
```
2. **Add Components**: Add any additional migrations, seeders, models, controllers, etc., to your module following the structure outlined above.
3. **Enable the Module**: Ensure the `isEnabled()` method in your module class returns `true`.
```php
// app/Modules/NewFeature/NewFeatureModule.php
public function isEnabled(): bool
{
return true;
}
```
Then, in your module's config file:
```php
// app/Modules/NewFeature/Configs/new-feature-config.php
<?php
return [
'enabled' => env('NEW_FEATURE_MODULE_ENABLED', true),
];
```
#### Usage via Helpers
Use the global helper functions to interact with modules throughout the application.
- **Get the Module Repository**:
```php
$repository = modular();
```
- **Get All Enabled Modules**:
```php
$enabledModules = modules(); // Returns a Collection of BaseModule objects
foreach ($enabledModules as $module) {
echo $module->name;
}
```
- **Get a Specific Module Instance**:
```php
$invoiceModule = module('Invoice'); // Returns instance of InvoiceModule
if ($invoiceModule->isEnabled()) {
// ...
}
```
- **Get the Modules Path**:
```php
$path = modules_path('Invoice/Database'); // app/Modules/Invoice/Database
```